Mybatis的延迟加载及缓存

概述:

    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     @Test14     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执行数据库查询(不清空缓存))。

 

计算机