罗里吧嗦
延迟加载:
就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载,按需加载。
延迟加载对应的是立即加载:不管用不用,只要一调用方法,马上发起查询。
好处:
先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。
坏处:
因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗
时间,所以可能造成用户等待时间变长,造成用户体验下降
实际开发过程中很多时候我们并不需要总是在加载用户信息时就一定要加载他的账户信息。 此时就是我们所说的延迟加载。
在对应的四种表关系中:一对多,多对一,一对一,多对多
一对多,多对多:通常情况下我们都是采用延迟加载。
多对一,一对一:通常情况下我们都是采用立即加载。
概要
1.打开延迟加载
<configuration>
<settings>
<!-- 延迟加载的开关 默认是false -->
<setting name="lazyLoadingEnabled" value="true"></setting>
<!-- 将积极加载改为按需加载,默认是false,即在这里配不配置都一样 -->
<!--<setting name="aggressiveLazyLoading" value="false"></setting>-->
</settings>
2.在mapper映射文件的配置,以及一些简单的注意事项

个人案例
基于:一对多查询
1.创建maven项目,导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http:///POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http:///POM/4.0.0 http:///xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cong</groupId>
<artifactId>mybatis_lazyLoad</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
2.两个类
package com.cong.pojo;
public class Account {
private int aid;
private int uid;
private double money;
//从表实体应该包含一个主表实体的对象引用
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public int getAid() {
return aid;
}
public void setAid(int aid) {
this.aid = aid;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"aid=" + aid +
", uid=" + uid +
", money=" + money +
'}';
}
}
package com.cong.pojo;
import java.util.List;
public class User {
private int uid;
private String name;
private char sex;
private String addr;
//一对多关系映射:主表实体应该包含从表实体的集合引用
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
@Override
public String toString() {
return "User{" +
"uid=" + uid +
", name='" + name + '\'' +
", sex=" + sex +
", addr='" + addr + '\''+
'}';
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getName() {
return name;
}
public void setName(String name) {
= name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
}
3.mybatis配置文件
<?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>
<settings>
<!-- 延迟加载的开关 默认是false -->
<setting name="lazyLoadingEnabled" value="true"></setting>
<!-- 将积极加载改为按需加载,默认是false,即在这里配不配置都一样 -->
<!--<setting name="aggressiveLazyLoading" value="false"></setting>-->
</settings>
<typeAliases>
<package name="com.cong.pojo"></package>
</typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/rainbow?characterEncoding=UTF-8"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</dataSource>
</environment>
</environments>
<mappers>
<!--<mapper class="com.cong.mapper.UserMapper"></mapper>-->
<package name="com.cong.mapper"></package>
</mappers>
</configuration>
4.两个映射文件
下面是AccountMapper.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.cong.mapper.AccountMapper">
<!-- 定义封装account和user的resultMap -->
<resultMap id="accountUserMap" type="account">
<id property="aid" column="aid"></id>
<result column="uid" property="uid"></result>
<result column="money" property="money"></result>
<!--
一对一的延迟加载
select: 填写我们要调用的 select 映射的 id,使用全限定类名
column : 填写我们要传递给 select 映射的参数
-->
<association property="user" column="uid" javaType="user"
select="com.cong.mapper.UserMapper.findById">
</association>
</resultMap>
<!-- 查询所有account,并且关联到它所属于的user-->
<select id="findAll" resultMap="accountUserMap">
select * from account
</select>
<select id="findByUid" resultType="account">
select * from account where uid = #{uid};
</select>
</mapper>
下面是usermapper.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.cong.mapper.UserMapper">
<!-- 定义User的resultMap-->
<resultMap id="userAccountMap" type="user">
<id property="uid" column="uid"></id>
<result property="name" column="name"></result>
<result property="addr" column="addr"></result>
<result property="sex" column="sex"></result>
<!--
一对多的延迟加载
ofType 用于指定集合元素的数据类型
select 用于指定查询account的sql语句,所以填写的是该sql语句映射的id
column 用于指定 select 属性的 sql 语句的参数来源,
-->
<collection property="accounts" ofType="account" notNullColumn="aid"
column="uid" select="com.cong.mapper.AccountMapper.findByUid"
>
</collection>
</resultMap>
<!-- 查询所有user,以及它拥有的account -->
<select id="findAll" resultMap="userAccountMap">
select * from user
</select>
<select id="findById" resultType="user" parameterType="int">
select * from user where uid = #{uid};
</select>
</mapper>
5.测试类
import com.cong.mapper.AccountMapper;
import com.cong.mapper.UserMapper;
import com.cong.pojo.Account;
import com.cong.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class TestTables {
private InputStream inputStream;
private SqlSession sqlSession;
private AccountMapper accountMapperr;
private UserMapper userMapper;
@Test
public void findAllAccount(){
List<Account> accounts = accountMapperr.findAll();
for (Account account : accounts) {
System.out.println("-------------一个account的信息--------------------");
System.out.println(account.toString());
System.out.println(account.getUser());
}
}
@Test
public void findAllUser(){
List<User> users = userMapper.findAll();
for (User user : users) {
System.out.println("------------------一个user的信息-----------------------");
System.out.println(user.toString());
if(!user.getAccounts().isEmpty()){
for (Account account : user.getAccounts()) {
System.out.println("\t" + account);
}
}
}
}
@Before
public void init() throws Exception{
inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = factory.openSession();
accountMapperr = sqlSession.getMapper(AccountMapper.class);
userMapper = sqlSession.getMapper(UserMapper.class);
}
@After
public void destroy() throws Exception{
sqlSession.commit();
sqlSession.close();
inputStream.close();
}
}
















