目录
- resultMap的作用
- 创建一对一数据库表
- 创建一对多数据库
- 创建实体Bean对象
- 一对多,立即加载
- 一对多,懒加载
- 双向关联
resultMap的作用
原来我们查询都是返回一个简单的JavaBean对象。我们可以直接使用ResultType定义返回在的类型。
但是如果我们查询的结果返回在的JavaBean中,又包含一个javaBean,或者包含一个javaBean对象的集合。
那么这个时候,只能使用ResultMap来自定义返回的结果。
创建一对一数据库表
## 一对一数据表
## 创建锁表
create table t_lock(
`id` int primary key auto_increment,
`name` varchar(50)
);
## 创建钥匙表
create table t_key(
`id` int primary key auto_increment,
`name` varchar(50),
`lock_id` int ,
foreign key(`lock_id`) references t_lock(`id`)
);
## 插入初始化数据
insert into t_lock(`name`) values('淘宝');
insert into t_lock(`name`) values('京东');
insert into t_lock(`name`) values('拼多多');
insert into t_key(`name`,`lock_id`) values('天猫',1);
insert into t_key(`name`,`lock_id`) values('狗东',2);
insert into t_key(`name`,`lock_id`) values('拼夕夕',3);
创建实体对象
锁实体Bean
public class Lock {
private int id;
private String name;
钥匙实体Bean
public class Key {
private int id;
private String name;
private Lock lock;
一对一 级联属性 使用
1、创建KeyMapper接口
public interface KeyMapper {
public Key queryKeyByIdForSample(int id);
}
2、创建KeyMapper.xml配置文件:
<?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="com.ddh.dao.KeyMapper">
<!-- resultMap标签可以自定义结果集。定义成你需要的bean对象的结果
type属性表示当前这个ResultMap会封装什么对象返回
id 属性定义一个唯一的标识,方便别人使用。
-->
<resultMap type="com.ddh.pojo.Key" id="queryKeyByIdForSample_resultMap">
<!--
id专门用来映射id主键列
-->
<id column="id" property="id"/>
<!--
result标签映射非主键列
-->
<result column="name" property="name"/>
<!-- 级联映射 -->
<result column="lock_id" property="lock.id"/>
<result column="lock_name" property="lock.name"/>
</resultMap>
<!-- public Key queryKeyByIdForSample(int id); -->
<!--
当前select查询,结果是 resultMap所指向的id对应的resultMap集合
-->
<select id="queryKeyByIdForSample" resultMap="queryKeyByIdForSample_resultMap">
select
t_key.*,t_lock.name lock_name
from
t_key left join t_lock
on
t_key.lock_id = t_lock.id
where
t_key.id = #{id}
</select>
</mapper>
3、<association /> 嵌套结果集映射配置
<resultMap type="com.ddh.pojo.Key" id="queryKeyByIdForSample_resultMap2">
<!--
id专门用来映射id主键列
-->
<id column="id" property="id"/>
<!--
result标签映射非主键列
-->
<result column="name" property="name"/>
<!-- association 标签专门 映射Bean对象中的子对象(一个Bean)
专门用来配置一对一标签
-->
<association property="lock" javaType="com.ddh.pojo.Lock">
<!-- 把lock_id列注入到lock属性对象中的id属性值 -->
<id column="lock_id" property="id"/>
<!-- 把查询的lock_name列的值给lock子对象中的name属性 -->
<result column="lock_name" property="name"/>
</association>
</resultMap>
4、<association /> 定义分步查询
在KeyMapper接口中创建一个分步查询方法:
public Key queryKeyByIdForTwoStep(int id);
创建LockMapper接口
public interface LocKMapper {
public Lock queryLockById(int lockId);
}
5、在keyMapper.xml配置文件中:
<resultMap type="com.ddh.pojo.Key" id="queryKeyByIdForTwoStep_resultMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!--
association 标签是推荐用来映射一对一关联
property是你要映射的子对象的变量名
javaType 表示你要映射的这个子对象的具体类型
select 属性表示你要执行的查询语句
column 属性设置你要传递给select设置的查询语句用的参数列
-->
<association property="lock" javaType="com.ddh.pojo.Lock"
select="com.ddh.dao.LocKMapper.queryLockById" column="lock_id"
/>
</resultMap>
<!-- public Key queryKeyByIdForTwoStep(int id); -->
<select id="queryKeyByIdForTwoStep" resultMap="queryKeyByIdForTwoStep_resultMap">
select id,name,lock_id from t_key where id = #{id}
</select>
6、创建LockMapper.xml配置文件内容如下:
<!-- public Lock queryLockById(int lockId); -->
<select id="queryLockById" resultType="com.ddh.pojo.Lock">
select id,name from t_lock where id = #{id}
</select>
延迟加载
延迟加载在一定程序上可以减少很多没有必要的查询。给数据库服务器提升性能上的优化。
要启用延迟加载,需要在mybatis-config.xml配置文件中,添加如下两个全局的settings配置。
<!-- 打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 将积极加载改为消极加载 按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
懒加载功能,mybatis3.2.8版本,需要同时引入两个jar包
cglib-2.2.2.jar asm-3.3.1.jar
创建一对多数据库
### 创建班级表
create table t_clazz(
`id` int primary key auto_increment,
`name` varchar(50)
);
## 插入班级信息
insert into t_clazz(`name`) values('javaEE20170228');
insert into t_clazz(`name`) values('javaEE20170325');
insert into t_clazz(`name`) values('javaEE20170420');
insert into t_clazz(`name`) values('javaEE20170515');
## 创建学生表
create table t_student(
`id` int primary key auto_increment,
`name` varchar(50),
`clazz_id` int,
foreign key(`clazz_id`) references t_clazz(`id`)
);
## 插入班级信息
insert into t_student(`name`,`clazz_id`) values('stu0228_1',1);
insert into t_student(`name`,`clazz_id`) values('stu0228_2',1);
insert into t_student(`name`,`clazz_id`) values('stu0228_3',1);
insert into t_student(`name`,`clazz_id`) values('stu0325_1',2);
insert into t_student(`name`,`clazz_id`) values('stu0325_2',2);
insert into t_student(`name`,`clazz_id`) values('stu0420_1',3);
创建实体Bean对象
学生
public class Student {
private int id;
private String name;
班级
public class Clazz {
private int id;
private String name;
private List<Student> stuList;
一对多,立即加载
1、创建ClazzMapper接口
public interface ClazzMapper {
public Clazz queryClazzByIdForSample(int id);
}
2、编写ClazzMapper.xml配置文件:
<resultMap type="com.ddh.pojo.Clazz" id="queryClazzByIdForSample_resultMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!--
collection 标签专门用来映射集合属性
property 表示你要映射的集合属性名是什么
-->
<collection property="stuList" ofType="com.ddh.pojo.Student">
<id column="stu_id" property="id"/>
<result column="stu_name" property="name"/>
</collection>
</resultMap>
<!-- public Clazz queryClazzByIdForSample(int id); -->
<select id="queryClazzByIdForSample" resultMap="queryClazzByIdForSample_resultMap">
select
t_clazz.*,t_student.id stu_id,t_student.name stu_name
from
t_clazz left join t_student
on
t_clazz.id = t_student.clazz_id
where
t_clazz.id = #{id}
</select>
一对多,懒加载
1、再创建一个StudentMapper接口
public interface StudentMapper {
public List<Student> queryStudentsByClazzId(int clazzId);
}
2、创建StudentMapper.xml配置文件:
<!-- public List<Student> queryStudentsByClazzId(int clazzId); -->
<select id="queryStudentsByClazzId" resultType="com.ddh.pojo.Student">
select id,name from t_student where clazz_id = #{clazzid}
</select>
3、在ClazzMapper接口中添加一个方法实现懒加载
public Clazz queryClazzByIdForTwoStepLazy(int id);
4、在ClazzMapper.xml中进行配置:
<resultMap type="com.ddh.pojo.Clazz" id="queryClazzByIdForTwoStepLazy_resultMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!--
collection 是专门映射集合的标签
property 属性设置你要设置和集合的属性名
ofType是 这个集合中每个元素的具体类型
select 是你要查询的语句
column 属性设置你要执行的select对应的查询语句需要的参数列
-->
<collection property="stuList" ofType="com.ddh.pojo.Student"
select="com.ddh.dao.StudentMapper.queryStudentsByClazzId"
column="id"
/>
</resultMap>
<!-- public Clazz queryClazzByIdForTwoStepLazy(int id); -->
<select id="queryClazzByIdForTwoStepLazy" resultMap="queryClazzByIdForTwoStepLazy_resultMap">
select id,name from t_clazz where id = #{id}
</select>
双向关联
1、在StudentMapper接口中添加一个懒加载的方法:
public List<Student> queryStudentByClazzIdForLazy(int clazzId);
2、然后在StudentMapper.xml配置文件中
<resultMap type="com.ddh.pojo.Student" id="queryStudentByClazzIdForLazy_resultMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!-- association标签是专门用来映射了个子对象的标签 -->
<association property="clazz" javaType="com.ddh.pojo.Clazz"
select="com.ddh.dao.ClazzMapper.queryClazzByIdForTwoStepLazy"
column="clazz_id"
/>
</resultMap>
<!-- public List<Student> queryStudentByClazzIdForLazy(int clazzId); -->
<select id="queryStudentByClazzIdForLazy" resultMap="queryStudentByClazzIdForLazy_resultMap">
select id,name,clazz_id from t_student where clazz_id = #{clazzId}
</select>
3、再修改原来懒加载查询班级里,懒加载学生的select属性
<resultMap type="com.ddh.pojo.Clazz" id="queryClazzByIdForTwoStepLazy_resultMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!--
collection 是专门映射集合的标签
property 属性设置你要设置和集合的属性名
ofType是 这个集合中每个元素的具体类型
select 是你要查询的语句
column 属性设置你要执行的select对应的查询语句需要的参数列
-->
<collection property="stuList" ofType="com.ddh.pojo.Student"
select="com.ddh.dao.StudentMapper.queryStudentByClazzIdForLazy"
column="id"
/>
</resultMap>
如果双向关联出现死循环,如何防止双向关联呢?
1、不要调用toString方法
2、在你需要终止关联的时候,最后一次查询使用resultType