MyBatis之手动映射

server/2024/9/22 22:17:37/

在一些简单的场景下,MyBatis 能够自动完成对象和数据库字段之间的映射,这时就不需要手动映射

手动映射通常在以下情况下需要使用:

  1. 复杂查询或结果:当查询返回的结果结构与实体类不完全匹配,或者返回的结果需要进行复杂的处理时。
  2. 多表关联查询:当通过SQL进行多表联合查询时,返回的结果可能包含多个实体类的字段,这时需要手动映射结果到特定的对象。
  3. 非标准字段名数据库的字段名与实体类属性名不一致,自动映射工具无法正确处理时。
  4. 部分字段映射:当查询的结果只需要映射到对象的部分字段时。

在MyBatis的XML文件中,我们可以通过<resultMap>来进行手动映射。这种方式适合需要映射复杂对象的情况,比如下面的用户和地址信息的场景。下面是如何在MyBatis的XML文件中编写手动映射的示例。

例子:手动映射实体类和SQL查询

1. 表结构

假设有两个表:useraddress,它们的关系是一对一(每个用户对应一个地址)。

User表

CREATE TABLE user (id BIGINT PRIMARY KEY,name VARCHAR(50),email VARCHAR(100)
);

Address表

CREATE TABLE address (id BIGINT PRIMARY KEY,user_id BIGINT,city VARCHAR(100),street VARCHAR(100),FOREIGN KEY (user_id) REFERENCES user(id)
);

2. 实体类

User实体类

public class User {private Long id;private String name;private String email;private Address address;  // 对应用户的地址// Getters and Setters
}

Address实体类

public class Address {private Long id;private String city;private String street;// Getters and Setters
}

3. 在XML手动映射

MyBatis XML文件通常与Mapper接口文件对应。假设Mapper接口是UserMapper.javaXML文件命名为UserMapper.XML.html" title=xml>xml

XML文件内容如下:

XML"><?XML.html" title=xml>xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.example.mapper.UserMapper"><!-- 手动映射User和Address --><resultMap id="UserResultMap" type="com.example.model.User"><!-- 映射User表的字段 --><id property="id" column="userId" /><result property="name" column="name" /><result property="email" column="email" /><!-- 嵌套映射Address对象 --><association property="address" javaType="com.example.model.Address"><id property="id" column="addressId" /><result property="city" column="city" /><result property="street" column="street" /></association></resultMap><!-- 查询用户及其地址 --><select id="getUserWithAddress" parameterType="long" resultMap="UserResultMap">SELECT u.id AS userId, u.name, u.email, a.id AS addressId, a.city, a.streetFROM user uLEFT JOIN address a ON u.id = a.user_idWHERE u.id = #{userId}</select></mapper>
  • <resultMap>:用来定义如何将查询结果映射到Java对象。id用于标识主键字段,result用于映射普通字段。

  • <--column 数据库中的字段名--> <--property 实体类中对应的属性 该关键字可以省略... --> 

  • <association>:用于嵌套映射复杂对象。在本例中,我们将User中的address字段映射到Address对象。

  • <select>:这是查询语句,parameterType="long"表示传入的参数类型是LongresultMap="UserResultMap"表示结果映射使用上面定义的UserResultMap

4. 详解解析

4.1 XML声明和<mapper>根元素

XML"><?XML.html" title=xml>xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.example.mapper.UserMapper">
  • <?XML.html" title=xml>xml version="1.0" encoding="UTF-8" ?>: 声明了XML的版本和编码。
  • <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">: 这是MyBatis的映射文件的DTD声明,用于校验映射文件的合法性。
  • <mapper>: 根元素,声明了Mapper接口的命名空间,namespace="com.example.mapper.UserMapper"表示此XML文件对应于UserMapper接口。MyBatis通过这个命名空间将SQL映射与接口方法进行关联。

4.2 手动映射用户和地址对象

XML"><resultMap id="UserResultMap" type="com.example.model.User"><!-- 映射User表的字段 --><id property="id" column="userId" /><result property="name" column="name" /><result property="email" column="email" /><!-- 嵌套映射Address对象 --><association property="address" javaType="com.example.model.Address"><id property="id" column="addressId" /><result property="city" column="city" /><result property="street" column="street" /></association>
</resultMap>

resultMap

  • <resultMap>: 定义如何将查询结果映射到Java对象。在这里,id="UserResultMap"表示这个结果映射的名称,type="com.example.model.User"表示这个映射对应的是User类。
  • <id>: 映射主键。property="id"表示User对象的id属性,column="userId"表示数据库中的userId列。这一步将数据库中的userId映射到User类的id字段。
  • <result>: 映射普通字段。property="name"property="email"分别映射到数据库中的nameemail列。

嵌套映射Address

  • <association>: 用于将复杂的关联对象进行映射。在本例中,property="address"表示User对象中关联的Address对象,javaType="com.example.model.Address"表示映射到的Java类型是Address类。
  • <id><result>: 同样映射Address对象的属性。property="id"表示Addressid属性,column="addressId"表示查询结果中表示addressId的列。citystreet属性同理。

4.3 查询用户及其地址的SQL语句

XML"><select id="getUserWithAddress" parameterType="long" resultMap="UserResultMap">SELECT u.id AS userId, u.name, u.email, a.id AS addressId, a.city, a.streetFROM user uLEFT JOIN address a ON u.id = a.user_idWHERE u.id = #{userId}
</select>

<select>元素

  • <select>: 定义SQL查询语句。id="getUserWithAddress"表示这个查询的名称,MyBatis会根据这个ID将它与Mapper接口中的方法进行关联。parameterType="long"表示传入的参数类型是Long类型,通常是用于传递userId
  • resultMap="UserResultMap": 指定查询结果的映射规则,使用前面定义的UserResultMap来将结果集映射到User对象和关联的Address对象。

SQL语句

  • SELECT u.id AS userId, u.name, u.email, a.id AS addressId, a.city, a.street: 这是具体的SQL查询语句,查询用户表user和地址表address中的字段,并为字段取别名以便与Java对象的字段匹配。

    • u.id AS userId: 将user表的id作为userId,用于映射User类的id字段。
    • a.id AS addressId: 将address表的id作为addressId,用于映射Address类的id字段。
  • FROM user u LEFT JOIN address a ON u.id = a.user_id: 从user表中查询,同时使用LEFT JOINaddress表进行关联,条件是u.id = a.user_id,即用户的id等于地址表中的user_id

  • WHERE u.id = #{userId}: 查询条件是用户的id等于传入的userId

4.4 整体流程

  1. 传入参数: 当调用Mapper接口的getUserWithAddress(Long userId)方法时,userId会被传入SQL语句中的WHERE子句中。
  2. 执行查询: MyBatis执行SELECT语句,查询用户和关联的地址信息。
  3. 结果映射: 查询结果根据UserResultMap中的定义,映射到UserAddress对象的属性中。
  4. 返回结果: 映射后的User对象(包含嵌套的Address对象)被返回。

http://www.ppmy.cn/server/118335.html

相关文章

单片机中为什么要使用5v转3.3v,不直接使用3.3V电压

5V和3.3V是常见的电压水平&#xff0c;在技术上都有其特定的应用场景。为了保护电路、提升效能和确保系统的稳定运行&#xff0c;经常需要将5V转换为3.3V。 1.为什么要5V来供电 使用5V是因为部分传感器需要5V的供电&#xff0c;并且我们数据线一般都输出5V电压&#xff0c;而…

从Prompt到创造:解锁AI的无限潜能

文章目录 &#x1f34a;AI内容创作核心&#xff1a;提示词Prompt1 什么是提示词工程?1.1 提示词的原理是什么&#xff1f;1.2 提示词工程师&#xff1a;百万年薪的职业&#xff1f;1.3 谁都能成为提示词工程师吗&#xff1f; 2 提示词书写的基本技巧3 常见的提示词框架3.1 CO-…

C# USB通信技术(通过LibUsbDotNet库)

文章目录 1.下载LibusbDotNet库2.引入命名空间3. 实例化USB设备4.发送数据5.关闭连接 1.下载LibusbDotNet库 右击项目选择管理NuGet程序包在弹出的界面中搜索LibusbDotNet&#xff0c;然后下载安装。 2.引入命名空间 using LibUsbDotNet; using LibUsbDotNet.Main;3. 实例化…

flask搭建微服务器并训练CNN水果识别模型应用于网页

一. 搭建flask环境 概念 flask:一个轻量级 Web 应用框架&#xff0c;被设计为简单、灵活&#xff0c;能够快速启动一个 Web 项目。CNN:深度学习模型&#xff0c;用于处理具有网格状拓扑结构的数据&#xff0c;如图像&#xff08;2D网格&#xff09;和视频&#xff08;3D网格&a…

数据结构-线性表顺序单项链表双向链表循环链表

1数据结构概述 数据结构是计算机组织、存储数据的方式。是思想层面的东西&#xff0c;和具体的计算机编程语言没有关系。可以用任何计算机编程语言去实现这些思想。 1.1 数据逻辑结构 反映数据逻辑之间的逻辑关系&#xff0c;这些逻辑关系和他们咱在计算机中的存储位置无关。…

pycv实时目标检测快速实现

使用python_cv实现目标实时检测 python 安装依赖核心代码快速使用实现结果展示enjoy python 安装依赖 opencv_python4.7.0.72 pandas1.5.3 tensorflow2.11.0 tensorflow_hub0.13.0 tensorflow_intel2.11.0 numpy1.23.5核心代码快速使用 # 使用了TensorFlow Hub和OpenCV库来实…

C++3D迷宫

目录 开头程序程序的流程图程序游玩的效果下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。 程序 #include <iostream> using namespace std; void printmaze(char strmaze[5][5][5]) {cout << "-----" << endl;int i 0;int ia 0…

安全基础设施如何形成统一生态标准?OASA 硬件安全合作计划启动 | 2024 龙蜥大会

近日&#xff0c;2024 龙蜥操作系统大会&#xff08;OpenAnolis Conference&#xff09;在北京盛大召开。 与此同时&#xff0c;由龙蜥社区运营委员会副主席、龙腾计划生态负责人金美琴&#xff0c;阿里云智能集团高级技术专家张天佳&#xff0c;海光信息技术生态技术总监李伟&…