1.reusltmap的说明
resultmap定义了数据库的结果映射到java对象的规则,resultmap包含4个属性:
id: resultmap 的唯一标识type: 映射到的 java 类型(全限定类名或别名)extends: 继承另一个 resultmapautomapping: 是否开启自动映射(true/false)
前三个比较常用
resultmap包含以下子元素,并且子元素是有定义顺序的,如下:
<constructor>(可选)<id>(至少一个)<result>(零个或多个)<association>(零个或多个)<collection>(零个或多个)<discriminator>(可选)
必须遵循上述顺序,如果顺序不正确,mybatis 在解析 xml 时会抛出异常
<id>元素必须出现在<result>元素之前- 如果使用
<constructor>,它必须是第一个元素 <discriminator>必须是最后一个元素(如果存在)
2.association的使用
<association> 是 mybatis 中用于处理一对一关联关系的元素,它可以将查询结果中的一部分数据映射到一个复杂的关联对象中。
在实际开发中,如果想一次查询两张表的数据,不想通过两次查询的方式,而是想一次查询出来,可以通过两张表关联将表a和表b的数据都查询出来
| 属性名 | 说明 |
|---|---|
| property | java对象中的属性名 |
| javatype | 关联对象的java类型(全限定类名或别名) |
| resultmap | 引用外部定义的resultmap |
| column | 传递给嵌套查询的列名(可以是多个列:column="{prop1=col1,prop2=col2}") |
| select | 另一个映射语句的id,用于嵌套查询 |
| fetchtype | 覆盖全局的延迟加载设置(lazy/eager) |
| automapping | 是否启用自动映射(true/false) |
<!-- 一对一关联映射示例 -->
<resultmap id="userwithdeptmap" type="com.example.user">
<!-- 用户表字段映射 -->
<id column="user_id" property="id" jdbctype="bigint"/>
<result column="user_name" property="name" jdbctype="varchar"/>
<result column="user_age" property="age" jdbctype="integer"/>
<!-- 一对一关联 department 对象 -->
<association property="department" javatype="com.example.department">
<id column="dept_id" property="id" jdbctype="bigint"/>
<result column="dept_name" property="deptname" jdbctype="varchar"/>
<result column="dept_location" property="location" jdbctype="varchar"/>
</association>
</resultmap><select id="selectuserwithdepartment" resultmap="userwithdeptmap">
select
u.id as user_id,
u.name as user_name,
u.age as user_age,
d.id as dept_id,
d.name as dept_name,
d.location as dept_location
from
user u
left join
department d on u.dept_id = d.id
where
u.id = #{userid}
</select>package com.example;
public class user {
private long id; // 对应 user_id 字段
private string name; // 对应 user_name 字段
private integer age; // 对应 user_age 字段
private department department; // 一对一关联对象
// 必须的 getter 和 setter 方法
public long getid() {
return id;
}
public void setid(long id) {
this.id = id;
}
public string getname() {
return name;
}
public void setname(string name) {
this.name = name;
}
public integer getage() {
return age;
}
public void setage(integer age) {
this.age = age;
}
public department getdepartment() {
return department;
}
public void setdepartment(department department) {
this.department = department;
}
}package com.example;
public class department {
private long id; // 对应 dept_id 字段
private string deptname; // 对应 dept_name 字段
private string location; // 对应 dept_location 字段
// 必须的 getter 和 setter 方法
public long getid() {
return id;
}
public void setid(long id) {
this.id = id;
}
public string getdeptname() {
return deptname;
}
public void setdeptname(string deptname) {
this.deptname = deptname;
}
public string getlocation() {
return location;
}
public void setlocation(string location) {
this.location = location;
}
}使用关联查询只需要指定以下两个属性即可
配置项 | 作用 |
property="department" | 指定 user 类中关联属性的名称(需与字段名一致)。 |
javatype | 指定关联对象的完整类名(可省略,mybatis 通常能自动推断)。 |
3.collection的使用
<collection> 是 mybatis 中用于处理一对多关联关系的核心元素,它能够将查询结果中的多条记录映射到一个集合属性中(如 list、set 等)
| 属性名 | 是否必填 | 说明 |
|---|---|---|
| property | 必填 | java对象中的集合属性名称 |
| oftype | 条件必填 | 集合中元素的java类型(当不使用resultmap时必填) |
| column | 条件必填 | 传递给嵌套查询的列名(使用select时必填) |
| select | 可选 | 另一个映射语句的id,用于嵌套查询 |
| fetchtype | 可选 | 加载方式(lazy/eager),覆盖全局配置 |
| javatype | 可选 | 集合的java类型(如arraylist、hashset等) |
| resultmap | 可选 | 引用外部定义的resultmap |
| automapping | 可选 | 是否启用自动映射(true/false) |
<resultmap id="userwithordersmap" type="com.example.model.user">
<id property="id" column="user_id"/>
<result property="name" column="user_name"/>
<result property="age" column="user_age"/>
<!-- 一对多关联订单集合 -->
<collection property="orders" oftype="com.example.model.order">
<id property="id" column="order_id"/>
<result property="orderno" column="order_no"/>
<result property="amount" column="order_amount"/>
<result property="userid" column="user_id"/>
</collection>
</resultmap>
<select id="selectuserwithorders" resultmap="userwithordersmap">
select
u.id as user_id,
u.name as user_name,
u.age as user_age,
o.id as order_id,
o.order_no as order_no,
o.amount as order_amount,
o.user_id
from user u
left join orders o on u.id = o.user_id
where u.id = #{userid}
</select>package com.example.model;
import java.util.list;
public class user {
private long id;
private string name;
private integer age;
private list<order> orders; // 一对多关联的订单集合
// getters and setters
public long getid() {
return id;
}
public void setid(long id) {
this.id = id;
}
public string getname() {
return name;
}
public void setname(string name) {
this.name = name;
}
public integer getage() {
return age;
}
public void setage(integer age) {
this.age = age;
}
public list<order> getorders() {
return orders;
}
public void setorders(list<order> orders) {
this.orders = orders;
}
}package com.example.model;
public class order {
private long id;
private string orderno;
private double amount;
private long userid; // 外键,关联用户id
// getters and setters
public long getid() {
return id;
}
public void setid(long id) {
this.id = id;
}
public string getorderno() {
return orderno;
}
public void setorderno(string orderno) {
this.orderno = orderno;
}
public double getamount() {
return amount;
}
public void setamount(double amount) {
this.amount = amount;
}
public long getuserid() {
return userid;
}
public void setuserid(long userid) {
this.userid = userid;
}
}使用关联查询只需要指定以下两个属性即可
| 属性名 | 是否必填 | 说明 |
|---|---|---|
| property | 必填 | java对象中的集合属性名称 |
| oftype | 条件必填 | 集合中元素的java类型(当不使用resultmap时必填) |
4.总结
①在 mybatis 的 <resultmap> 中,如果使用 <association> 或 <collection> 映射关联关系,必须为父对象(主对象)至少定义一个 <id> 属性
mybatis 使用 <id> 来唯一标识一个对象,用于:
- 一级/二级缓存的键值
- 解决嵌套映射中的循环引用问题
- 避免重复创建相同对象(性能优化)
关联映射的依赖:
- 当存在
<association>或<collection>时,mybatis 需要通过父对象的<id>来管理关联对象的加载和绑定。
②association及collection中的id属性是可选的,但建议加上,它用于避免重复子对象(例如 join 导致重复数据时去重)。
如果子对象中定义了 <id> 属性,mybatis 会对 <collection> 中的重复子对象进行去重。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论