Mybatis的延迟加载及缓存

泪湿孤枕 提交于 2019-12-01 08:16:05

概述:

    Mybatis中的延迟加载,也称为懒加载,是指设置表的关联查询时,按照设置表的延迟规则推迟对关联对象的select查询。例如在进行一对多的关联查询时,之查询出一方,当程序需要多方数据时。Mybatis再发出sql进行查询。这样以来,延迟加载就可以减轻数据库的压力。Mybatis的延迟加载,只是对关联对象的延迟设置,对于主加载对象都是直接执行查询语句进行查询的。

一.加载时机

 

  1.直接加载:

    执行完之加载对象的select语句后,直接对关联对象的select进行查询。

  2.侵入式延迟:

    执行主对象的查询时,不会执行对关联对象的查询。当程序访问之加载对象的详情属性时,立即进行对关联对象的select查询。

  3.深度延迟:

    执行主对象的查询时,不会执行对关联对象的查询。当程序访问之加载对象的详情属性时,也不会进行对关联对象的select查询。当访问关联对象的详情时,才会执行对关联对象进行select查询。

 

 

  侵入式延迟加载的配置方法:

    1.编写mybatis_config.xml大配置文件

    

 

 

 

  2.实体类:

    

  1 package com.wdy.entity;
  2 
  3 import javax.persistence.*;
  4 import java.sql.Timestamp;
  5 import java.util.List;
  6 
  7 
  8 public class SmbmsRole {
  9     private Integer id;
 10     private String roleCode;
 11     private String roleName;
 12     private Long createdBy;
 13     private Timestamp creationDate;
 14 
 15     public SmbmsRole() {
 16     }
 17 
 18     @Override
 19     public String toString() {
 20         return "SmbmsRole{" +
 21                 "id=" + id +
 22                 ", roleCode='" + roleCode + '\'' +
 23                 ", roleName='" + roleName + '\'' +
 24                 ", createdBy=" + createdBy +
 25                 ", creationDate=" + creationDate +
 26                 ", users=" + users +
 27                 ", modifyBy=" + modifyBy +
 28                 ", modifyDate=" + modifyDate +
 29                 '}';
 30     }
 31 
 32     private List<SmbmsUser> users;
 33 
 34     public SmbmsRole(Integer id, String roleCode, String roleName, Long createdBy, Timestamp creationDate, List<SmbmsUser> users, Long modifyBy, Timestamp modifyDate) {
 35         this.id = id;
 36         this.roleCode = roleCode;
 37         this.roleName = roleName;
 38         this.createdBy = createdBy;
 39         this.creationDate = creationDate;
 40         this.users = users;
 41         this.modifyBy = modifyBy;
 42         this.modifyDate = modifyDate;
 43     }
 44 
 45     private Long modifyBy;
 46 
 47     public Integer getId() {
 48         return id;
 49     }
 50 
 51     public void setId(Integer id) {
 52         this.id = id;
 53     }
 54 
 55     public String getRoleCode() {
 56         return roleCode;
 57     }
 58 
 59     public void setRoleCode(String roleCode) {
 60         this.roleCode = roleCode;
 61     }
 62 
 63     public String getRoleName() {
 64         return roleName;
 65     }
 66 
 67     public void setRoleName(String roleName) {
 68         this.roleName = roleName;
 69     }
 70 
 71     public Long getCreatedBy() {
 72         return createdBy;
 73     }
 74 
 75     public void setCreatedBy(Long createdBy) {
 76         this.createdBy = createdBy;
 77     }
 78 
 79     public Timestamp getCreationDate() {
 80         return creationDate;
 81     }
 82 
 83     public void setCreationDate(Timestamp creationDate) {
 84         this.creationDate = creationDate;
 85     }
 86 
 87     public List<SmbmsUser> getUsers() {
 88         return users;
 89     }
 90 
 91     public void setUsers(List<SmbmsUser> users) {
 92         this.users = users;
 93     }
 94 
 95     public Long getModifyBy() {
 96         return modifyBy;
 97     }
 98 
 99     public void setModifyBy(Long modifyBy) {
100         this.modifyBy = modifyBy;
101     }
102 
103     public Timestamp getModifyDate() {
104         return modifyDate;
105     }
106 
107     public void setModifyDate(Timestamp modifyDate) {
108         this.modifyDate = modifyDate;
109     }
110 
111     private Timestamp modifyDate;
112 
113 }

 

User实体类:  
  1 package com.wdy.entity;
  2 
  3 import javax.persistence.*;
  4 import java.sql.Date;
  5 import java.sql.Timestamp;
  6 import java.util.List;
  7 
  8 
  9 public class SmbmsUser {
 10     private Integer id;
 11     private String userCode;
 12     private String userName;
 13     private String userPassword;
 14     private Integer gender;
 15     private Date birthday;
 16     private String phone;
 17     private String address;
 18     private Integer userRole;
 19     private Long createdBy;
 20 
 21     @Override
 22     public String toString() {
 23         return "SmbmsUser{" +
 24                 "id=" + id +
 25                 ", userCode='" + userCode + '\'' +
 26                 ", userName='" + userName + '\'' +
 27                 ", userPassword='" + userPassword + '\'' +
 28                 ", gender=" + gender +
 29                 ", birthday=" + birthday +
 30                 ", phone='" + phone + '\'' +
 31                 ", address='" + address + '\'' +
 32                 ", userRole=" + userRole +
 33                 ", createdBy=" + createdBy +
 34                 ", creationDate=" + creationDate +
 35                 ", modifyBy=" + modifyBy +
 36                 ", modifyDate=" + modifyDate +
 37                 ", rolesList=" + rolesList +
 38                 '}';
 39     }
 40 
 41     private Timestamp creationDate;
 42 
 43     public SmbmsUser(Integer id, String userCode, String userName, String userPassword, Integer gender, Date birthday, String phone, String address, Integer userRole, Long createdBy, Timestamp creationDate, Long modifyBy, Timestamp modifyDate, List<SmbmsRole> rolesList) {
 44         this.id = id;
 45         this.userCode = userCode;
 46         this.userName = userName;
 47         this.userPassword = userPassword;
 48         this.gender = gender;
 49         this.birthday = birthday;
 50         this.phone = phone;
 51         this.address = address;
 52         this.userRole = userRole;
 53         this.createdBy = createdBy;
 54         this.creationDate = creationDate;
 55         this.modifyBy = modifyBy;
 56         this.modifyDate = modifyDate;
 57         this.rolesList = rolesList;
 58     }
 59 
 60     private Long modifyBy;
 61 
 62     public SmbmsUser() {
 63     }
 64 
 65     private Timestamp modifyDate;
 66 
 67     public Integer getId() {
 68         return id;
 69     }
 70 
 71     public void setId(Integer id) {
 72         this.id = id;
 73     }
 74 
 75     public String getUserCode() {
 76         return userCode;
 77     }
 78 
 79     public void setUserCode(String userCode) {
 80         this.userCode = userCode;
 81     }
 82 
 83     public String getUserName() {
 84         return userName;
 85     }
 86 
 87     public void setUserName(String userName) {
 88         this.userName = userName;
 89     }
 90 
 91     public String getUserPassword() {
 92         return userPassword;
 93     }
 94 
 95     public void setUserPassword(String userPassword) {
 96         this.userPassword = userPassword;
 97     }
 98 
 99     public Integer getGender() {
100         return gender;
101     }
102 
103     public void setGender(Integer gender) {
104         this.gender = gender;
105     }
106 
107     public Date getBirthday() {
108         return birthday;
109     }
110 
111     public void setBirthday(Date birthday) {
112         this.birthday = birthday;
113     }
114 
115     public String getPhone() {
116         return phone;
117     }
118 
119     public void setPhone(String phone) {
120         this.phone = phone;
121     }
122 
123     public String getAddress() {
124         return address;
125     }
126 
127     public void setAddress(String address) {
128         this.address = address;
129     }
130 
131     public Integer getUserRole() {
132         return userRole;
133     }
134 
135     public void setUserRole(Integer userRole) {
136         this.userRole = userRole;
137     }
138 
139     public Long getCreatedBy() {
140         return createdBy;
141     }
142 
143     public void setCreatedBy(Long createdBy) {
144         this.createdBy = createdBy;
145     }
146 
147     public Timestamp getCreationDate() {
148         return creationDate;
149     }
150 
151     public void setCreationDate(Timestamp creationDate) {
152         this.creationDate = creationDate;
153     }
154 
155     public Long getModifyBy() {
156         return modifyBy;
157     }
158 
159     public void setModifyBy(Long modifyBy) {
160         this.modifyBy = modifyBy;
161     }
162 
163     public Timestamp getModifyDate() {
164         return modifyDate;
165     }
166 
167     public void setModifyDate(Timestamp modifyDate) {
168         this.modifyDate = modifyDate;
169     }
170 
171     public List<SmbmsRole> getRolesList() {
172         return rolesList;
173     }
174 
175     public void setRolesList(List<SmbmsRole> rolesList) {
176         this.rolesList = rolesList;
177     }
178 
179     private List<SmbmsRole> rolesList;
180 
181 
182 }

 

3.小配置文件

 

 

 

 

4.测试类

 1 package com.wdy.test;
 2 
 3 
 4 
 5 import com.wdy.dao.ISmbmsDao;
 6 import com.wdy.entity.SmbmsRole;
 7 import com.wdy.entity.SmbmsUser;
 8 import com.wdy.util.SqlSessionUtils;
 9 import org.apache.ibatis.session.SqlSession;
10 import org.junit.Test;
11 
12 public class SmbmsUserTest {
13     @Test
14     public void getRoleAndUserTest(){
15         SqlSession session = SqlSessionUtils.getSession();
16         ISmbmsDao mapper = session.getMapper(ISmbmsDao.class);
17         SmbmsRole roleAndUser = mapper.getRoleAndUser(3);
18 
19         System.out.println("职位:"+roleAndUser.getRoleName()+"\n人员:");
20         int xh=0;
21         for (SmbmsUser user:roleAndUser.getUsers()){
22             xh++;
23             System.out.print("\t序号"+xh+":"+user.getUserName()+"\n");
24         }
25 
26 
27     }
28 
29 }

 

执行结果如下:

 

 

 如果不访问关联对象的详细信息:

 

 

 则 执行结果 只会执行主查询对象(只执行查询Role的select语句 也就是 职位 )

执行结果:

 

 

 

二.缓存

  概述:   

    查询缓存的使用,主要是为了提高查询访问速度。将用户对同一数据的重复查询过程简化,不再每次均从数据库查询获取结果数据,从而提高访问速度。

  二.一(一级缓存)

    

一.缓存的划分

根据缓存区的作用域与生命周期课划分为:

一级缓存(大配置文件setting节点name属性)

 

 

二.一级缓存存在证明

同一个会话(SqlSession)执行两次相同的SQL,观察控制台发送了几条SQL

 

 

 

 

 

 

 

 

缓存的底层实现是一个Map,Map的key是查询的依据,使用的ORM框架不同,查询依据也不同,Mybatis查询依据为SQL的ID+SQL语句,hibernate的为查询结果对象的ID

 

三.增删改对一级缓存的影响

 

 

 

 

四.一级缓存结论

  1. Mybatis框架天然集成一级缓存

  2. 一级缓存查询依据为SQLID+SQL语句

  3. 增删改会清空一级缓存

 

  二.二(二级缓存)

    

 

 

   二.缓存说明

        MyBatis查询缓存的作用域是根据映射文件的namespace划分的,相同的namespace的mapper查询数据放在同一个缓存区域。不同namespace下的数据互不干扰。

    无论是一级缓存还是二级缓存,都是按照namespace进行分别存放的。

    一级、二级缓存的不同之处在于,SqlSession一旦关闭,则SqlSession中的数据将不存在,即一级缓存就不复存在。而二级缓存的生命周期与整个应用同步,与SqlSession是

    否关闭无关。换句话说,一级缓存是在同一线程(同一SqlSession)间共享数据,而二级缓存是在不同线程(不同的SqlSession)间共享数据。

1.在大配置文件中开启二级缓存,默认为开启

 

 

2.在Mapper小配置文件中,添加缓存标签<cache/>

 

 

 

 

3.实体实现Serializable(标志接口:没有任何方法)

 

 

 

4.测试类

 

 

执行结果如下:

 

 

增删改对二级缓存的影响

增删改同样会清空二级缓存

 

 

 

 

 

关闭刷新缓存(关闭后不再执行SQL查询)

在增删改对应小配置节点内,加入flushCache值为false

 

 

 

 

 

 

查询不应用缓存

不应用缓存代表会再次发送SQL查询数据

 

 

 

关于MyBatis缓存的小结:
 
   一级缓存: 在增删改情况下无论是否提交事务 都会重新发送SQL执行数据库查询(清空缓存)。
   二级缓存: 在增删改情况下
           如果提交事务会重新发送SQL执行数据库查询(清空缓存)。
           如果不提交事务则获取缓存数据(不会重新发送SQL执行数据库查询(不清空缓存))。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!