mybatis 中的 resultmap
在 mybatis 中,resultmap 用于 定义数据库查询结果到 java 对象属性的映射关系。适合处理 复杂的映射关系,如 嵌套对象、集合、一对多或多对一的关系,以及 字段和属性名不一致 的情况。
resultmap 明确指定数据库查询结果(字段)如何映射到 java 对象的属性。通常,resultmap 被用于 select 查询时的 结果映射,但也可以用于 插入 和 更新 等操作。
1. resultmap 的基本语法
resultmap 通常写在 mybatis 的 mapper.xml 文件中,通过 <resultmap> 标签定义。以下是 resultmap 的基本语法结构:
<resultmap id="resultmapid" type="java类类型">
<result property="属性名" column="列名"/>
</resultmap>id:resultmap的唯一标识,可以在select、insert等语句中引用。type:指定查询结果映射的 java 类型(通常是一个 pojo 类)。property:java 对象的属性名。column:数据库表的列名。
2. 简单的 resultmap 示例
假设数据库表 t_user 和实体类 user 如下:
t_user 表:
create table t_user (
id int primary key auto_increment,
username varchar(50),
user_email varchar(100),
user_age int
);user 实体类:
public class user {
private integer id;
private string username;
private string email;
private integer age;
// getters and setters
}resultmap 示例:
<mapper namespace="com.example.mapper.usermapper">
<resultmap id="userresultmap" type="user">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="email" column="user_email"/>
<result property="age" column="user_age"/>
</resultmap>
<select id="selectuserbyid" resultmap="userresultmap">
select id, username, user_email, user_age
from t_user
where id = #{id}
</select>
</mapper><resultmap>标签用于定义数据库列和 java 属性之间的映射。<result>标签用于指定字段和属性的具体映射关系(**<resultmap>**中用于具体描述映射关系的子标签)。column是数据库列名,property是 java 实体类的属性。
在这个例子中,当执行查询时,mybatis 会将 t_user 表中的字段映射到 user 类的属性上。
关于上面的例子,大家可能会有这样的问题,为什么属性名和字段名一样也要写出来,这种情况mybatis不是会自动映射吗?这其实是出于一种 清晰和规范化的考虑,使用resultmap 的时候尽量把所有属性和字段的映射关系都写出来。详细可以参考:
mybatis系列第8篇:自动映射,使用需谨慎!
【mybatis自动映射】为什么即使字段名和属性名一致,使用resultmap时也应该显式列出所有映射?
3. 常用的 resultmap 功能
(1) 处理字段名和属性名不一致
有时数据库的列名与 java 类的属性名不一致,resultmap 可以帮助处理这种映射。使用 column 来指定数据库中的列名,property 来指定 java 类的属性名。
例如:
<resultmap id="userresultmap" type="user">
<result property="id" column="user_id"/>
<result property="username" column="user_name"/>
<result property="email" column="user_email"/>
</resultmap>(2) 一对一映射(<association>)
如果查询的结果需要映射到一个嵌套的对象(如一对一关系),可以使用 <association> 标签。
示例:一对一关系(用户和地址)
假设 t_user 表中有 address_id 字段,表示该用户的地址 id,而地址信息存储在 t_address 表中。我们需要将查询结果映射为用户和地址的组合。
t_address 表:
create table t_address (
id int primary key auto_increment,
street varchar(100),
city varchar(50)
);address 实体类:
public class address {
private integer id;
private string street;
private string city;
// getters and setters
}user 实体类(修改版):
public class user {
private integer id;
private string username;
private address address; // 关联一个 address 对象
// getters and setters
}resultmap 示例:
<mapper namespace="com.example.mapper.usermapper">
<resultmap id="userresultmap" type="user">
<result property="id" column="user_id"/>
<result property="username" column="user_name"/>
<association property="address" column="address_id" javatype="address"
select="selectaddressbyid"/>
</resultmap>
<select id="selectuserbyid" resultmap="userresultmap">
select user_id, user_name, address_id
from t_user
where user_id = #{id}
</select>
<select id="selectaddressbyid" resulttype="address">
select id, street, city
from t_address
where id = #{addressid}
</select>
</mapper>- 使用
<association>标签实现 一对一 映射,property是 java 对象中的属性(address),column是数据库中关联的列(address_id)。 javatype是关联对象的类型(address),select属性指定了通过address_id查询地址完整信息的 sql 查询。
原本只能查出
address_id,现在在userresultmap中定义把查出来的address_id映射到address,但是一个integer类的id怎么赋值给address类?所以需要在association的select属性中指定根据这个id去对应表中查询出对应实体类的全部信息,然后再赋值,这就是为什么还要写一个selectaddressbyid的select语句。
(3) 一对多映射(<collection>)
如果查询的结果是多个对象(如一对多关系),可以使用 <collection> 标签。
示例:一对多关系(用户和订单)
假设 t_user 表与 t_order 表之间有一对多关系,即一个用户有多个订单。我们可以使用 resultmap 和 <collection> 来映射多个订单。
t_order 表:
create table t_order (
id int primary key auto_increment,
user_id int,
order_date date
);order 实体类:
public class order {
private integer id;
private date orderdate;
// getters and setters
}user 实体类(修改版):
public class user {
private integer id;
private string username;
private list<order> orders; // 一对多的订单列表
// getters and setters
}resultmap 示例:
<mapper namespace="com.example.mapper.usermapper">
<resultmap id="userresultmap" type="user">
<result property="id" column="user_id"/>
<result property="username" column="user_name"/>
<collection oftype="order" property="orders" select="selectordersbyuserid" column="user_id"/>
</resultmap>
<select id="selectuserbyid" resultmap="userresultmap">
select user_id, user_name
from t_user
where user_id = #{id}
</select>
<select id="selectordersbyuserid" resulttype="order">
select id, order_date
from t_order
where user_id = #{userid}
</select>
</mapper><collection>标签用于一对多的关系映射。property对应 java 类中的集合属性(如orders),oftype指定集合元素的类型(如order),select指定查询订单的 sql。collection oftype="order":字面意思就是关于“order”的集合property="orders",column="user_id":表示我们要从查询出的user_id映射到orders属性,但是一个是integer类,一个是list类,怎么对应?select="selectordersbyuserid":所以用指定一个查询语句,我们可以根据这个integer类的id(user_id)查询出list类(这个用户对应的所有订单的list)
4. 总结
resultmap是 mybatis 中强大的映射工具,能够帮助我们处理复杂的 字段到属性的映射关系,如一对一、一对多、嵌套对象等。- 对于 简单的字段映射,我们可以使用
@results注解;但对于 复杂的关联关系,resultmap给予我们更大的灵活性。 <association>和<collection>是resultmap中常用的标签,用于处理 一对一 和 一对多 的关系映射。- 使用
resultmap可以让查询结果映射更明确和可控,尤其适用于多表联查或关系复杂的场景。
到此这篇关于mybatis resultmap 的基本用法的文章就介绍到这了,更多相关mybatis resultmap用法内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论