Mybatis中的延迟加载案例解析
一、延迟加载
resultmap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。
延迟加载:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。
在mybatis核心配置文件中配置:
lazyloadingenabled、aggressivelazyloading
设置项 |
描述 |
允许值 |
默认值 |
lazyloadingenabled |
全局性设置懒加载。如果设为‘false',则所有相关联的都会被初始化加载。 |
true | false |
false |
aggressivelazyloading |
当设置为‘true'的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。 |
true | false |
true |
<settings> <setting name="lazyloadingenabled" value="true"/> <setting name="aggressivelazyloading" value="false"/> </settings>
场合:
当只有部分记录需要关联查询其它信息时,此时可按需延迟加载,需要关联查询时再向数据库发出sql,以提高数据库性能。
当全部需要关联查询信息时,此时不用延迟加载,直接将关联查询信息全部返回即可,可使用resulttype或resultmap完成映射。
二:案例:(在部门和员工一对多)
源码介绍:
1.dept.java
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
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
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
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
<?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 (延迟加载的配置在此)
<?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(测试类)
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中配置
<settings> <!-- 打开延迟加载的开关 --> <setting name="lazyloadingenabled" value="true" /> <!-- 将积极加载改为消息加载即按需加载 --> <setting name="aggressivelazyloading" value="false" /> </settings>
下一步:
f6下步:
f6下步:打出员工的名字
情况三:
f6下一步:
f6下一步:打印出员工名字
以上所述是小编给大家介绍的mybatis中的延迟加载,希望对大家有所帮助