Mybatis的延迟加载和立即加载
Mybatis的延迟加载和立即加载
示例:在一对多中,当我们有一个用户,他有100个帐户
问题1:在查询用户时,要不要把关联的账户查出来?
问题2:在查询账户时,要不要把关联的用户信息查出来?
问题1:在查询用户时,要不要把关联的账户查出来?
用户和帐户之间的关系应该是一对多的关系,一个用户对应多个账户,如果在查询用户时,同时查询到他关联的帐户,那么这些查询到的账户信息就会占据很大的内存,所以应该是是么时候使用,是么时候才查询帐户信息。
问题2:在查询账户时,要不要把关联的用户信息查出来?
帐户和用户之间的关系应该是一对一的,一个帐户应该对应一个用户,如果查询账户时,账户的所属用户信息应该是随着一起查询出来的,且用户信息占据内存很小。
延迟加载:(应用于一对多,多对多,即关联的对象为“多”时)
在真正使用数据时才发起查询,不用的时候不查询,按需加载(懒加载)。
立即加载:(应用于多对一,一对一,即关联的对象为“一”时)
不管用不用,在调用方法的时候就立即执行,马上发起查询。
一对一实现延迟:account-user 的一对一延迟加载
帐户account实体类
package com.itheima.domain;
import java.io.Serializable;
/**
* @Author: lijiahao
* @Description:
* @Data: Create in 12:23 2020/2/26
* @Modified By:
*/
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//从表实体应该包含一个主表实体的对象引用
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "account{" +
"id=" + id +
", uid=" + uid +
", money=" + money +
'}';
}
}
user的接口
package com.itheima.dao;
import com.itheima.domain.User;
import java.util.List;
/**
* @Author: lijiahao
* @Description: 用户的持久层接口
* @Data: Create in 21:42 2020/2/22
* @Modified By:
*/
public interface IUserDao {
//查询所有用户,同时获取到用户下所有账户的信息
List<User> findAll();
//根据id查询用户信息
User findById(Integer userId);
}
主配置文件
<?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">
<!--mybatis的主配置文件-->
<configuration>
<!--配置连接池-->
<properties resource="jdbcConfig.properties"/>
<!--配置参数-->
<settings>
<!--开启mybatis延迟加载,默认为false-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--开启立即加载,mybatis3.4.1以上默认为false-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!--配置别名 类名就是别名,不区分大小写-->
<typeAliases>
<package name="com.itheima.domain" ></package>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql的环境-->
<environment id="mysql">
<!--配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)-->
<dataSource type="POOLED">
<!--配置数据库的四个基本信息-->
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!--指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件-->
<mappers>
<package name="com.itheima.dao"></package>
</mappers>
</configuration>
帐户映射配置文件IAccountDao.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.itheima.dao.IAccountDao">
<!--定义封装account和user的ResultMap account为主表,user为从表,实现一对一-->
<resultMap id="accountUserMap" type="account">
<!--主键配置,property为属性名,column为数据库列名(sql语句起了别名as后面的,下方sql语句可以搜索到的)-->
<!--aid为-->
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--一对一的关系映射,配置封装user的内容
select属性指定的内容:查询用户的唯一标识
column属性指定的内容:用户根据id查询时,所需要的参数的值-->
<association property="user" column="uid" javaType="user" select="com.itheima.dao.IUserDao.findById">
</association>
</resultMap>
<!--查询所有-->
<select id="findAll" resultMap="accountUserMap">
select * from account
</select>
</mapper>
测试类
package com.itheima;
import com.itheima.dao.IAccountDao;
import com.itheima.domain.Account;
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.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @Author: lijiahao
* @Description:
* @Data: Create in 22:56 2020/2/22
* @Modified By:
*/
public class AccountTest {
private InputStream in;
private SqlSession sqlSession;
private IAccountDao accountDao;
@Before
public void init() throws IOException {
//1.读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
sqlSession = sqlSessionFactory.openSession(true);
//3.使用工厂生产dao对象
accountDao = sqlSession.getMapper(IAccountDao.class);
}
@After
public void destory() throws IOException {
in.close();
}
@Test
public void testFindAll() throws IOException {
//5.使用代理对象执行方法
List<Account> accounts = accountDao.findAll();
for (Account account : accounts) {
System.out.println(account);
System.out.println(account.getUser());
}
}
}
一对多实现延迟加载:user-account 的一对多的延迟加载
用户user实体类
package com.itheima.domain;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @Author: lijiahao
* @Description:
* @Data: Create in 21:37 2020/2/22
* @Modified By:
*/
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//一对多关系映射,主表实体应该包含从表实体的集合引用
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
account的接口
package com.itheima.dao;
import com.itheima.domain.Account;
import java.util.List;
/**
* @Author: lijiahao
* @Description:
* @Data: Create in 12:25 2020/2/26
* @Modified By:
*/
public interface IAccountDao {
/**
* @Author Lijiahao
* @Description 查询所有账户, 同时还要获取到当前账户的所有信息
* @Date 16:32 2020/2/26
* @Param []
* @return java.util.List<com.itheima.domain.Account>
**/
List<Account> findAll();
//根据用户id查询帐户信息
List<Account> findAccountByUid(Integer uid);
}
主配置文件
package com.itheima.domain;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @Author: lijiahao
* @Description:
* @Data: Create in 21:37 2020/2/22
* @Modified By:
*/
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//一对多关系映射,主表实体应该包含从表实体的集合引用
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
用户映射配置文件IUserDao.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.itheima.dao.IUserDao">
<!--定义user的resultMap user为主表,account为从表,构成一对多关系-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!--配置user对象中accounts集合的映射
select 后面即为延迟 后的查询语句,根据user中的id查询-->
<collection property="accounts" ofType="account" select="com.itheima.dao.IAccountDao.findAccountByUid" column="id">
</collection>
</resultMap>
<select id="findAll" resultMap="userAccountMap">
select * from user
</select>
<!--根据id查找一个用户的信息-->
<select id="findById" parameterType="INT" resultType="user">
select * from user where id = #{userid}
</select>
</mapper>
测试类
package com.itheima;
import com.itheima.dao.IUserDao;
import com.itheima.domain.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.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @Author: lijiahao
* @Description:
* @Data: Create in 22:56 2020/2/22
* @Modified By:
*/
public class UserTest {
private InputStream in;
private SqlSession sqlSession;
private IUserDao userDao;
@Before
public void init() throws IOException {
//1.读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
sqlSession = sqlSessionFactory.openSession(true);
//3.使用工厂生产dao对象
userDao = sqlSession.getMapper(IUserDao.class);
}
@After
public void destory() throws IOException {
in.close();
}
@Test
public void testFindAll() throws IOException {
//5.使用代理对象执行方法
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
System.out.println(user.getAccounts());
}
}
}
Mybatis的延迟加载和立即加载的更多相关文章
- Mybatis源码解析(二) —— 加载 Configuration
Mybatis源码解析(二) -- 加载 Configuration 正如上文所看到的 Configuration 对象保存了所有Mybatis的配置信息,也就是说mybatis-config. ...
- Hibernate之加载策略(延迟加载与即时加载)和抓取策略(fetch)
假设现在有Book和Category两张表,表的关系为双向的一对多,表结构如下: 假设现在我想查询id为2的那本书的书名,使用session.get(...)方法: Session session=H ...
- EF如何操作内存中的数据以及加载相关联表的数据:延迟加载、贪婪加载、显示加载
之前的EF Code First系列讲了那么多如何配置实体和数据库表的关系,显然配置只是辅助,使用EF操作数据库才是每天开发中都需要用的,这个系列讲讲如何使用EF操作数据库.老版本的EF主要是通过Ob ...
- EF 延迟加载和预先加载
最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精 本节探讨延迟加载和预先加载 Entity Frame ...
- Entity Framework关联查询以及数据加载(延迟加载,预加载)
数据加载分为延迟加载和预加载 EF的关联实体加载有三种方式:Lazy Loading,Eager Loading,Explicit Loading,其中Lazy Loading和Explicit Lo ...
- EF如何操作内存中的数据和加载外键数据:延迟加载、贪婪加载、显示加载
EF如何操作内存中的数据和加载外键数据:延迟加载.贪婪加载.显示加载 之前的EF Code First系列讲了那么多如何配置实体和数据库表的关系,显然配置只是辅助,使用EF操作数据库才是每天开发中都需 ...
- 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性)
一. 简介 上一个章节中,也介绍了立即加载和延迟加载,但上一个章节是针对单表而言的,不含外键,立即也好,延迟也好,都是指单表中的数据.但本章节重点介绍的三种加载方式均是针对含(导航属性.外键)的情况下 ...
- ASP.NET MVC深入浅出(被替换) 第一节: 结合EF的本地缓存属性来介绍【EF增删改操作】的几种形式 第三节: EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery ) 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性) 第十节: EF的三种追踪
ASP.NET MVC深入浅出(被替换) 一. 谈情怀-ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态 ...
- NHibernate 延迟加载与立即加载 (第七篇)
NHibernate 延迟加载与立即加载 (第七篇) 一.延迟加载 延迟加载可以理解为:当需要用的时候才加载. 假设我们数据库有一个Person对象,一个Country对象,其中Person属于Cou ...
随机推荐
- conCat()的应用
编写一个Java应用程序,从键盘读取用户输入两个字符串,并重载3个函数分别实现这两个字符串的拼接.整数相加和浮点数相加.要进行异常处理,对输入的不符合要求的字符串提示给用户: package com. ...
- 使用CStatic显示图片(bmp、ico、png)
一.显示bmp及ico //h文件 CStatic m_static; //cpp文件 CBitmap bitmap; bitmap.LoadBitmapW(IDB_BITMAP); //加载位图 B ...
- 《Python学习手册 第五版》 -第12章 if测试和语法规则
本章节的内容,主要讲解if语句,if语句是三大复合语句之一(其他两个是while和for),能处理编程中大多数逻辑运算 本章的重点内容如下: 1.if语句的基本形式(多路分支) 2.布尔表达式 3.i ...
- tomcat-windows10环境搭建
1.进入Tomcat官网Apache Tomcat® - Welcome! 2.根据操作系统选择合适的版本下载 zip用于windows操作系统, tar.gz用于unix和linux操作系统 Bin ...
- 一口气说出Redis 5种数据结构及对应使用场景,面试要加分的
整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 更多优选 一口气说出 9种 分布式ID生成方式,面试官有点懵了 ...
- num06---代理模式
代理模式,比较好理解,关键点就是,被代理类 和 代理类 实现同一个接口,接口中定义着想要实现的被代理的方法,在代理类中引入 被代理类 对象, 最后直接调用代理类的方法即可实现代理功能.
- Go语言实现:【剑指offer】连续子数组的最大和
该题目来源于牛客网<剑指offer>专题. HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向 ...
- 【Debian】 Debian 安装源配置
Debian 安装源配置 所有的Linux安装完后第一件事,就是要更新安装源 安装源是什么呢,安装源又称软件源,是指把软件的安装源地址放在一个pool里面,用一条命令(比如apt-get instal ...
- pytorch --Rnn语言模型(LSTM,BiLSTM) -- 《Recurrent neural network based language model》
论文通过实现RNN来完成了文本分类. 论文地址:88888888 模型结构图: 原理自行参考论文,code and comment: # -*- coding: utf-8 -*- # @time : ...
- python 安装自己下载的whl依赖
下载好之后保存到相应的地方,如下载了xxxx.whl文件并将它保存在D:\python\project目录下,然后 pip install D:\python\project\xxxx.whl即可