一、延迟加载
resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。
延迟加载:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。
在mybatis核心配置文件中配置:
lazyLoadingEnabled、aggressiveLazyLoading
设置项 |
描述 |
允许值 |
默认值 |
lazyLoadingEnabled |
全局性设置懒加载。如果设为‘false',则所有相关联的都会被初始化加载。 |
true | false |
false |
aggressiveLazyLoading |
当设置为‘true'的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。 |
true | false |
true |
1
2
3
4
|
<settings>
<setting name= "lazyLoadingEnabled" value= "true" />
<setting name= "aggressiveLazyLoading" value= "false" />
</settings>
|
场合:
当只有部分记录需要关联查询其它信息时,此时可按需延迟加载,需要关联查询时再向数据库发出sql,以提高数据库性能。
当全部需要关联查询信息时,此时不用延迟加载,直接将关联查询信息全部返回即可,可使用resultType或resultMap完成映射。
二:案例:(在部门和员工一对多)
源码介绍:
1.Dept.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package cn.zhang.entity;
import java.util.HashSet;
import java.util.Set;
public class Dept {
private Integer deptno;
private String deptname;
private Set<Emp> emp = new HashSet<Emp>();
@Override
public String toString() {
return "Dept [deptno=" + deptno + ", deptname=" + deptname + ", emp="
+ emp + "]" ;
}
public Integer getDeptno() {
return deptno;
}
public void setDeptno(Integer deptno) {
this .deptno = deptno;
}
public String getDeptname() {
return deptname;
}
public void setDeptname(String deptname) {
this .deptname = deptname;
}
public Set<Emp> getEmp() {
return emp;
}
public void setEmp(Set<Emp> emp) {
this .emp = emp;
}
}
|
2.Emp.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package cn.zhang.entity;
public class Emp {
private Integer empno;
private String empname;
@Override
public String toString() {
return "Emp [empno=" + empno + ", empname=" + empname + "]" ;
}
public Integer getEmpno() {
return empno;
}
public void setEmpno(Integer empno) {
this .empno = empno;
}
public String getEmpname() {
return empname;
}
public void setEmpname(String empname) {
this .empname = empname;
}
}
|
3.MybatisUtil.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package cn.zhang.util;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/**
* 工具类
*
*/
public class MybatisUtil {
private static String config = "mybatis-config.xml" ;
static Reader reader;
static {
try {
reader = Resources.getResourceAsReader(config);
} catch (IOException e) {
e.printStackTrace();
}
}
private static SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(reader);
// 提供一个可以获取到session的方法
public static SqlSession getSession() throws IOException {
SqlSession session = factory.openSession();
return session;
}
}
|
4.DeptDao.java
1
2
3
4
5
6
7
8
9
10
11
|
package cn.zhang.dao;
import java.io.IOException;
import cn.zhang.entity.Dept;
public interface DeptDao {
/**
* 查询指定记录
* @return
* @throws IOException
*/
public Dept findById(Integer id) throws IOException;
}
|
5.DeptDAO.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<?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.zhang.dao.DeptDao" >
<!-- 3 .根据员工id查询员工信息 -->
<select id= "selectEmpByDeptNo" resultType= "Emp" >
select empno,empname
from emp where deptno=#{deptno}
</select>
<!-- 2 .对部门实体的映射 -->
<resultMap type= "Dept" id= "deptMapper" >
<id property= "deptno" column= "deptno" />
<result property= "deptname" column= "deptname" />
<!-- 一对多部门关联的员工 -->
<!--select:关联员工查询 -->
<!--column:关联员工查询所需要的条件(来源于 1 ) -->
<collection property= "emp" ofType= "Emp" select= "selectEmpByDeptNo"
column= "deptno" />
</resultMap>
<!-- 1 .根据部门id查询部门信息 -->
<select id= "findById" resultMap= "deptMapper" >
select deptno,deptname from dept
where deptno=#{deptno}
</select>
</mapper>
|
6.mybatis-config.xml (延迟加载的配置在此)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
<?xml version= "1.0" encoding= "UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd" >
<configuration>
<!--lazyLoadingEnabled:设置懒加载,默认为 false 。如果为 false :则所有相关联的都会被初始化加载。
aggressiveLazyLoading:默认为 true 。当设置为 true 时,懒加载的对象可能被任何懒属性全部加载;否则,每个属性按需加载。 -->
<settings>
<!-- 打开延迟加载的开关 -->
<setting name= "lazyLoadingEnabled" value= "true" />
<!-- 将积极加载改为消息加载即按需加载 -->
<setting name= "aggressiveLazyLoading" value= "false" />
</settings>
<!-- 配置别名 -->
<typeAliases>
<!--方式一: 按类型名定制别名 -->
<!--方式二: 拿当前指定包下的简单类名作为别名 -->
< package name= "cn.zhang.entity" />
</typeAliases>
<environments default = "oracle" >
<environment id= "oracle" >
<!-- 使用jdbc的事务 -->
<transactionManager type= "JDBC" />
<!-- 使用自带的连接池 -->
<dataSource type= "POOLED" >
<!-- 我用的Oracle数据库 -->
<property name= "driver" value= "oracle.jdbc.driver.OracleDriver" />
<property name= "url" value= "jdbc:oracle:thin:@localhost:1521:orcl" />
<property name= "username" value= "study" />
<property name= "password" value= "123" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource= "cn/zhang/dao/DeptDAO.xml" />
</mappers>
</configuration>
|
7.MyTest.java(测试类)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package cn.zhang.test;
//一对多
import java.io.IOException;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;
import cn.zhang.dao.DeptDao;
import cn.zhang.entity.Dept;
import cn.zhang.util.MybatisUtil;
public class MyTest {
DeptDao dao;
@Before
public void initData() throws IOException{
SqlSession session = MybatisUtil.getSession();
dao = session.getMapper(DeptDao. class );
}
/**
* 查询指定记录
* @throws IOException
*/
@Test
public void findAll() throws IOException{
Dept dept = dao.findById( 1 );
System.out.println(dept);
}
}
|
测试结果:
在下面位置打断点
情况一:在mybatis-config.xml中不做配置情况
情况二:在mybatis-config.xml中配置
1
2
3
4
5
6
|
<settings>
<!-- 打开延迟加载的开关 -->
<setting name= "lazyLoadingEnabled" value= "true" />
<!-- 将积极加载改为消息加载即按需加载 -->
<setting name= "aggressiveLazyLoading" value= "false" />
</settings>
|
下一步:
F6下步:
F6下步:打出员工的名字
情况三:
F6下一步:
F6下一步:打印出员工名字
以上所述是小编给大家介绍的Mybatis中的延迟加载,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:http://www.cnblogs.com/zhangzongle/archive/2016/12/22/6210407.html