今天继续完善一下mybatis系列相关博客,以便查阅,同时也希望能帮助到有需要的小伙伴,各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!
这一篇记录一下mybatis的结果映射,虽说在其它博客中也有所体现,但是并不完整,博客中关于parameterType、resultType就不使用全限定名了,都使用别名代替。mybatis已经给常用的数据类型起好了别名,它们都是不区分大小写的,具体参考官网:Java 类型内建的类型别名
resultMap元素是MyBatis中最重要最强大的元素。它可以让你从90%的JDBC ResultSets数据提取代码中解放出来,并在一些情形下允许你进行一些JDBC不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份resultMap能够代替实现同等功能的数千行代码。ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
目录
简单结果映射
之前你已经见过简单映射语句的示例,它们没有显式指定 resultMap。比如:
<select id="selectHashMap1" resultType="hashmap">
select *
from mybatis_user
</select>
上述语句只是简单地将所有的列映射到HashMap的键上,这由resultType属性指定。虽然在大部分情况下都够用,但是HashMap并不是一个很好的领域模型。你的程序更可能会使用JavaBean作为领域模型。MyBatis对两者都提供了支持。
看看下面这个 JavaBean:
@Data
@Builder
public class User implements Serializable {
private Integer id;
private String name;
private Integer age;
private String sex;
private String province;
private String city;
private Date createdTime;
private String createdBy;
private Date updatedTime;
private String updatedBy;
}
基于JavaBean的规范,这些属性会对应到select语句中的列名。这样的一个JavaBean可以被映射到ResultSet,就像映射到HashMap一样简单。
<select id="selectHashMap" parameterType="int" resultType="User">
select *
from mybatis_user
where id = #{id}
</select>
在这些情况下,MyBatis会在幕后自动创建一个ResultMap,再根据属性名来映射列到JavaBean的属性上。如果列名和属性名不匹配,可以在SELECT语句中设置列别名来完成匹配。比如:
<select id="selectUsers" resultType="User">
select
user_id as "id",
user_name as "userName",
from mybatis_user
where id = #{id}
</select>
你会发现上面的例子没有一个需要显式配置ResultMap,这就是ResultMap的优秀之处——你完全可以不用显式地配置它们。 虽然上面的例子不用显式配置ResultMap。 但为了讲解,我们来看看如果在刚刚的示例中,显式使用外部的resultMap会怎样,这也是解决列名和属性名不匹配的另外一种方式,这里只选取三个属性,并且列name写成user_name演示一下:
<resultMap id="userResultMap" type="User">
<id property="id" column="id" />
<result property="name" column="user_name"/>
<result property="province" column="province"/>
</resultMap>
然后在引用它的语句中设置resultMap属性就行了(注意我们去掉了 resultType 属性)。比如:
<select id="selectUsers" resultMap="userResultMap">
select id, user_name, province
from mybatis_user
where id = #{id}
</select>
高级结果映射
参考:
springboot整合mybatis使用association做关联查询 一对一查询
springboot整合mybatis使用collection查询 一对多 多对一 多对多查询
resultType自动映射
resultType功能虽说不如resultMap强大,但是一般的查询也都能满足,相比使用resultMap有时候可能更加方便,如上面的查询:
<select id="selectUsers" resultType="User">
select
user_id as "id",
user_name as "userName",
from mybatis_user
where id = #{id}
</select>
另外,对于有嵌套关系的查询同样可以使用,如下:
@Data
public class UserWifeDto implements Serializable {
private Integer id;
private String name;
private Integer age;
private String sex;
private String province;
private String city;
private Date createdTime;
private String createdBy;
private Date updatedTime;
private String updatedBy;
private String wifeName;
private Wife wife;
}
<select id="testAutomappering" resultType="com.yjh.learn.mybatislearn.dto.UserWifeDto">
select u.*, w.wife_name from mybatis_user u
left join mybatis_wife w on u.id = w.user_id where u.id = #{id}
</select>
<select id="testAutomappering1" resultType="com.yjh.learn.mybatislearn.dto.UserWifeDto">
select u.*, w.* from mybatis_user u
left join mybatis_wife w on u.id = w.user_id where u.id = #{id}
</select>
@Test
public void test6(){
UserWifeDto dto = userMapper.testAutomappering(1);
System.out.println("--- dto ---" + dto);
UserWifeDto dto1 = userMapper.testAutomappering1(1);
System.out.println("--- dto1 ---" + dto1);
}
mapper就省了不贴代码了,如上两个查询都能查询到wifeName的值,但是wife为null,如下:
如果只是只需要关联查询出副表的部分属性这样没什么问题,如果需要关联查询出的属性太多,一般使用对象接收,但是上面这样就查询不出来了,如果想查询wife的所有属性,就需要借助resultMap了,可以借助association和collection描述对象之间的关系完成映射,参考高级结果映射中的博客,这里记录一下不使用association和collection直接使用resultMap级联属性封装结果集的方式完成结果映射,如下:
<select id="testCascadeResultMap" resultMap="cascadeResultMap">
select u.*, w.* from mybatis_user u
left join mybatis_wife w on u.id = w.user_id where u.id = #{id}
</select>
<resultMap id="cascadeResultMap" type="com.yjh.learn.mybatislearn.dto.UserWifeDto">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sex" column="sex"/>
<result property="age" column="age"/>
<result property="province" column="province"/>
<result property="city" column="city"/>
<result property="createdTime" column="created_time"/>
<result property="createdBy" column="created_by"/>
<result property="updatedTime" column="updated_time"/>
<result property="updatedBy" column="updated_by"/>
<result property="wife.wifeId" column="wife_id"/>
<result property="wife.userId" column="user_id"/>
<result property="wife.wifeName" column="wife_name"/>
</resultMap>
如果我的博客对你有帮助,欢迎进行评论✏️✏️、点赞👍👍、收藏⭐️⭐️,满足一下我的虚荣心💖🙏🙏🙏 。