实现一对一查询
resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,创建一个pojo类(VO),继承查询字段较多的po类,再增加需要的属性,即可完成映射。
如果没有对查询结果有特殊要求建议使用resultType
作用:
将查询结果按照sql列名pojo属性名一致性映射到pojo中
场合:
常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)
resultMap:需要单独定义resultMap,实现有点麻烦,如果有对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo属性中。
resultMap可以实现延迟加载,resultType无法实现延迟加载。
使用association和collection完成一对一和一对多高级映射(对结果有特殊映射要求)
association:
作用:
将关联查询信息映射到一个pojo对象中。
场合:
为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中:比如查询订单及关联用户信息。
使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需要,选择使用resultType和resultMap。
collection:
作用:
将关联查询信息映射到一个list集合中。
场合:
为了方便查询遍历相关信息可以使用collection将关联信息映射到list集合中,比如:查询用户极限范围模块及模块下的菜单,可使用collection,将模块映射到模块list中,将菜单列表映射到模块对象的菜单list属性中,这样的作用目的也是方便对查询结果进行遍历查询。
如果使用resultType无法将查询结果映射到List集合中。
使用resultType实现步骤:
1.创建一个Vo类,添加需要映射出来的属性(可以继承查询字段较多的POJO类)
例如查询用户和其所在部门的信息
package cn.mybatis.model;
//通过此类映射用户和部门查询的结果,让此类继承查询字段较多的pojo类
public class UserVo extends User{
// 添加关联查询的部门的属性
private String deptname;
private String description;
public String getDeptname() {
return deptname;
}
public void setDeptname(String deptname) {
this.deptname = deptname;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
2.编写UserMapper.xml,增加statement----findAllByResultType
<select id="findAllByResultType" resultType="cn.mybatis.model.UserVo">
select
user.*,
dept.deptname,
dept.description
from
user,
dept
where user.deptid = dept.did
</select>
3.编写UserMapper接口,增加 findAllByResultType()方法
public List<UserVo> findAllByResultType()throws Exception;
4.编写测试类方法
@Test
public void testFindAllByResultType() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建usermapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 调用UserMapper的方法
List<UserVo> userList = userMapper.findAllByResultType();
System.out.println(userList);
sqlSession.close();
}
打断点可以看到userList中有查询结果
使用resultMap实现步骤:
1.编写UserMapper.xml,增加一个resultMap,配置相关属性
<resultMap type="cn.mybatis.model.User" id="BaseResultMap">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="age" property="age"/>
<result column="deptid" property="deptid"/>
<!-- 配置映射的关联部门信息 -->
<!-- association用于映射关联查询单个对象的信息
property:要将关联查询的用户信息映射到表中对应属性
-->
<association property="dept" javaType="cn.mybatis.model.Dept">
<!-- id:关联查询的部门的唯一标志 -->
<!-- column:指定唯一标志部门的列 -->
<!-- javaTypey:映射到dept对应属性 -->
<id column="did" property="did"/>
<result column="deptname" property="deptname"/>
<result column="description" property="description"/>
</association>
</resultMap>
2.编写UserMapper.xml,增加statement---findAllByResultMap
<select id="findAllByResultMap" resultMap="BaseResultMap">
select
user.*,
dept.deptname,
dept.description
from
user,
dept
where user.deptid = dept.did
</select>
3.编写UserMapper接口,增加findAllByResultMap()方法
public List<User> findAllByResultMap()throws Exception;
4.编写测试类方法
@Test
public void testFindAllByResultMap() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建usermapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 调用UserMapper的方法
List<User> userList = userMapper.findAllByResultMap();
System.out.println(userList);
sqlSession.close();
}
打断点可以看到userList中有查询结果
延迟加载
resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。
延迟加载:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度快。
实现查询用户和关联查询部门信息时,延迟加载部门信息。
1.编写UserMapper.xml,新增resultMap
<!-- 延迟加载的resultMap -->
<resultMap type="cn.mybatis.model.User" id="UserLazyloadMap">
<!-- 对用户信息配置 -->
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="age" property="age"/>
<result column="deptid" property="deptid"/>
<!-- select:指定延迟加载需要执行的statement的id(根据部门id查询部门信息的statement) -->
<!-- 要使用DeptMapper.xml中的selectByPrimaryKey完成根据部门id查询部门信息,如果不在本mapper.xml中,需要前面加namespace -->
<!-- column:用户信息中关联部门信息查询的列 -->
<association property="dept" javaType="cn.mybatis.model.Dept" select="cn.mybatis.dao.DeptMapper.findDeptByDid" column="deptid">
<!-- 实现对部门信息延迟加载 -->
</association>
</resultMap>
2.编写UserMapper.xml,增加statement---findUserLazyLoading
<!-- 查询用户信息,所在部门信息延迟加载 -->
<select id="findUserLazyLoading" resultMap="UserLazyloadMap">
select * from user
</select>
3.编写DeptMaper.xml,增加statement---findDeptByDid
<?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="cn.mybatis.dao.DeptMapper" >
<select id="findDeptByDid" parameterType="int" resultType="Dept" >
select * from dept where did = #{value}
</select>
</mapper>
4.编写UserMapper接口---新增方法findUserLazyLoading()
// 查询用户,延迟加载部门信息
public List<User> findUserLazyLoading()throws Exception;
5.配置SqlMapConfig.xml中延迟加载开关
<!-- 全局配置参数 -->
<settings>
<!-- 打开延迟的开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 将积极加载改为消极加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 配置日志 -->
<setting name="logImpl" value="LOG4J"/>
</settings>
6.编写测试类方法
@Test
public void testFindAllLazyLoading() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建usermapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 调用UserMapper的方法
List<User> userList = userMapper.findUserLazyLoading();
for(User user:userList){
// 执行getDept()实现延迟加载
Dept dept = user.getDept();
System.out.println(dept.getDeptname());
}
sqlSession.close();
}