概述
要弄清楚resultMap的用法我们首先要了解Mybatis与数据库之间的联系.
当前我们常用的ORM框架有2种, Hibernate和Mybatis, 两者之间有不少区别, 其中在对于数据库的映射上面一个重要的区别是: Hibernate是映射整个的数据表, 而Mybatis则是映射我们通过sql语句查询到的结果, 一个典型的例子如下:
<select id="selectById" resultType="com.itheima.domain.School">
select CLASS_NO classNo, CLASS_NAME className
from school_a
where CLASS_NO = #{id}
</select>
<!--
1. school_a数据库中有多列, 但是我们只查找class_no, class_name, 因此最后只会将这两列数据映射并封装到school的pojo对象里面. 这就是mybatis的对象关系映射.
2. 但是在school pojo类中, 没有查到的对应的列名, 只有classNo, className这两个变量, 因此我们需要将名字映射对应起来, 有多种手段, 其中一个就是最重要的resultMap.
-->
resultType: 把查询结果封装到简单pojo类型中,但pojo类的属性名和查询到的数据库表的字段名一致
resultMap:
association: 把查询结果封装到复杂pojo类型中, 并且将列字段与属性不一致的对应起来
collection: 定义集合的封装规则, 将对象封装到集合
案例准备:
- 两个数据表, 其中st_class是school.class_no外键;
- 两个对应的pojo类, 其中score里面有school变量;
public class Score {
private Integer stId;
private Integer stMath;
private School school;
}
public class School {
private Integer classNo;
private String className;
private List<Score> scoreList;
}
需求一: 查出数学分数大于50的班级信息
分析: 为一对一查询, 一个学生分数及其所在班级, 使用association
级联查询
score里面的school里的属性, 来间接关联字段
<!-- ScoreMapper -->
<!-- dao interface通过namespace找到对应的mapper, 通过select id找到对应的select标签 -->
<mapper namespace="com.itheima.dao.ScoreMapper"></mapper>
<!--
id唯一标识, 与select绑定
type 通过resultMap映射的pojo对象
-->
<resultMap id="baseResultMap01" type="com.itheima.domain.Score">
<!--
id 表示主键, mybatis会对id标签进行优化;
column 表示数据库查询结果中的字段
jdbcType 表示字段类型
property 表示pojo对应的属性名
-->
<id column="ST_ID" jdbcType="INTEGER" property="stId"/>
<result column="ST_MATH" jdbcType="INTEGER" property="stMath"/>
<result column="CLASS_NO" jdbcType="INTEGER" property="school.classNo"/>
<result column="CLASS_NAME" jdbcType="VARCHAR" property="school.className"/>
</resultMap>
嵌套查询
association标签, 通过标签association来定义封装规则, 关联属性
<resultMap id="baseResultMap02" type="com.itheima.domain.Score">
<id column="ST_ID" jdbcType="INTEGER" property="stId"/>
<result column="ST_MATH" jdbcType="INTEGER" property="stMath"/>
<!--
property 关联属性
javaType 关联的pojo对象类型
-->
<association property="school" javaType="com.itheima.domain.School">
<id column="class_no" jdbcType="INTEGER" property="classNo"/>
<result column="class_name" jdbcType="VARCHAR" property="className"/>
</association>
</resultMap>
分步查询
association标签, 通过scoreMapper进行简单查询, 将查询到的ST_CLASS给到SchoolMapper再来查询school对象
<resultMap id="baseResultMap03" type="com.itheima.domain.Score">
<id column="ST_ID" jdbcType="INTEGER" property="stId"/>
<result column="ST_MATH" jdbcType="INTEGER" property="stMath"/>
<!--
select 通过ID引用另一个加载复杂类型的映射语句, 将column作为参数查询property
-->
<association property="school"
select="com.itheima.dao.SchoolMapper.selectById"
column="st_class">
</association>
</resultMap>
需求二: 查出某个班所有的分数情况, 一对多
分析: 为一对多查询, 一个班级所有学生分数情况, 使用collection
嵌套查询
collection标签, 定义列属性与集合中的对象属性关联的规则
<resultMap id="baseResultMap01" type="com.itheima.domain.School">
<id column="class_no" jdbcType="INTEGER" property="classNo"/>
<result column="class_name" jdbcType="VARCHAR" property="className"/>
<!--
property 关联属性, 为实体对象中的集合
javaType 关联属性的类型, 集合的类型, 一般是ArrayList
association 关联属性
ofType 需要映射的pojo实体对象
-->
<collection property="list" javaType="ArrayList"
ofType="com.itheima.domain.Score">
<id column="st_id" jdbcType="INTEGER" property="stId"/>
<result column="st_math" jdbcType="INTEGER" property="stMath"/>
</collection>
</resultMap>
分步查询
collection标签, 通过SchoolMapper查询到class_no, 给到ScoreMapper, 在ScoreMapper.selectByIdStep里面, 直接得到一个集合, 返回给到scoreList.
<resultMap id="baseResultMap02" type="com.itheima.domain.School">
<id column="class_no" jdbcType="INTEGER" property="classNo"/>
<result column="class_name" jdbcType="VARCHAR" property="className"/>
<collection property="scoreList" javaType="ArrayList"
ofType="com.itheima.domain.Score"
select="com.itheima.dao.ScoreMapper.selectByIdStep"
column="class_no">
</collection>
</resultMap>
注意事项:
-
查询结果中一定要包含resultMap里面的column列字段.
-
在mybatis-config.xml里面配置延迟加载, 使关联查询的结果在需要时再加载
<settings> <setting name="jdbcTypeForNull" value="NULL"/> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/></settings>
lazyLoadingEnabled: 全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。
aggressiveLazyLoading: 当设置为‘true’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。
上面说的是全局lazy加载, 我们还可以单独对collection和association设置lazy加载, 在里面添加fetchType=“lazy(延迟加载)”, “eager(立即加载)”
-
关联查询里面的column还可以添加多列参数, 形式为column = “{key1= column1, key2 = column2}” 其中key1是待执行语句的#{key1}, column1是已经查到的字段
最后
以上就是伶俐大山为你收集整理的resultMap用法详解--association, collection复杂查询的全部内容,希望文章能够帮你解决resultMap用法详解--association, collection复杂查询所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复