目录
1.懒加载
就是在真正使用的时候才会去执行查询与语句
要进行配置
全局配置中要加上,不然懒加载是不会执行的
2.Mybatis一级、二级缓存
Mybatis的缓存,包括一级缓存和二级缓存,一级缓存是默认使用的。二级缓存需要手动开启。
(1)一级缓存
一级缓存指的就是sqlsession,在sqlsession中有一个数据区域,是map结构,这个区域就是一级缓存区域。一级缓存中的key是由sql语句、条件、statement等信息组成一个唯一值。一级缓存中的value,就是查询出的结果对象。
(2)二级缓存
二级缓存指的就是同一个namespace下的mapper,二级缓存中,也有一个map结构,这个区域就是一级缓存区域。一级缓存中的key是由sql语句、条件、statement等信息组成一个唯一值。一级缓存中的value,就是查询出的结果对象。
简单来说,一级缓存就是假设一开始我们已经对一个东西进行查询,后面的方法如果需要到相同的查询,就不会去查询数据库,而是直接在缓存区中拿数据,但要是进行了增删改并进行了提交,一级缓存区就会被清空,就需要重新进行数据库的查询
二级缓存就是sqlsessionfactory的缓存,在同一个namespace中的mapper中,如果创建了多个session,例如session1,session2,session1进行了查询后关闭了(注意这里要关闭后才会缓存到二级缓存中去),session2需要查询的方法与session1中结果相同时,便会直接拿到二级缓存中的数据
一级缓存是默认开启的,二级缓存需要手动开启
一级缓存
原理:
测试1:
测试2:
二级缓存
原理:
我们这里的二级缓存可以使用第三方缓存
测试:
整合ehcache
Mybatis本身是一个持久层框架,它不是专门的缓存框架,所以它对缓存的实现不够好,不能支持分布式。
Ehcache是一个分布式的缓存框架。
什么是分布式
系统为了提高性能,通常会对系统采用分布式部署(集群部署方式)
整合思路
Cache是一个接口,它的默认实现是mybatis的PerpetualCache。如果想整合mybatis的二级缓存,那么实现Cache接口即可。
添加jar包
在src下添加ehcache的配置文件
memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)
- maxElementsInMemory :设置基于内存的缓存中可存放的对象最大数目
- eternal:设置对象是否为永久的,true表示永不过期,此时将忽略
- timeToIdleSeconds 和 timeToLiveSeconds属性; 默认值是false
- timeToIdleSeconds:设置对象空闲最长时间,以秒为单位, 超过这个时间,对象过期。当对象过期时,EHCache会把它从缓存中清除。如果此值为0,表示对象可以无限期地处于空闲状态。
- timeToLiveSeconds:设置对象生存最长时间,超过这个时间,对象过期。如果此值为0,表示对象可以无限期地存在于缓存中. 该属性值必须大于或等于 timeToIdleSeconds 属性值
- overflowToDisk:设置基于内在的缓存中的对象数目达到上限后,是否把溢出的对象写到基于硬盘的缓存中
- diskPersistent 当jvm结束时是否持久化对象 true false 默认是false
- diskExpiryThreadIntervalSeconds 指定专门用于清除过期对象的监听线程的轮询时间
二级缓存应用场景
使用场景:对于访问响应速度要求高,但是实时性不高的查询,可以采用二级缓存技术。
注意:在使用二级缓存的时候,要设置一下刷新间隔(cache标签中有一个flashInterval属性)来定时刷新二级缓存,这个刷新间隔根据具体需求来设置,比如设置30分钟、60分钟等,单位为毫秒。
局限性
Mybatis二级缓存对细粒度的数据,缓存实现不好。
场景:
对商品信息进行缓存,由于商品信息查询访问量大,但是要求用户每次查询都是最新的商品信息,此时如果使用二级缓存,就无法实现当一个商品发生变化只刷新该商品的缓存信息而不刷新其他商品缓存信息,因为二级缓存是mapper级别的,当一个商品的信息发送更新,所有的商品信息缓存数据都会清空。
解决此类问题,需要在业务层根据需要对数据有针对性的缓存。
比如可以对经常变化的 数据操作单独放到另一个namespace的mapper中。
3.逆向工程
简介
简单点说,就是通过数据库中的单表,自动生成java代码。
Mybatis官方提供了逆向工程
可以针对单表自动生成mybatis代码(mapper.java\mapper.xml\po类)
企业开发中,逆向工程是个很常用的工具。
下载逆向工程
https://github.com/mybatis/generator/releases/tag/mybatis-generator-1.3.2
使用方法
- 创建简单的java项目
- 导入jar包,创建generator配置文件;
- 使用java类来执行逆向工程;
- 把生成的代码拷贝到项目中。
- 在正式项目中使用逆向工程生成的代码
逆向工程创建后只有一些简单的crud的方法使用,如果需要到复杂的sql语句需要自己重新增加
第一步:创建generator配置文件
在classpath下,创建generator.xml配置文件:(文件内容可以从逆向工程的jar包中docs目录下的index.html中找到相关代码)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="mysqlTable" targetRuntime="MyBatis3">
<!-- 1.数据连接参数 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatis"
userId="root"
password="123456">
</jdbcConnection>
<!-- 2.默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL
和 NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 3.生成模型的位置 -->
<javaModelGenerator targetPackage="com.gyf.backoffice.domain" targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 4.targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.gyf.backoffice.mapper" targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 5. targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.gyf.backoffice.mapper"
targetProject=".\src">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 6.要生成的表 ,这里的话是表的类名就是属性名-->
<table tableName="items"/>
<table tableName="orderdetail"/>
<table tableName="orders"/>
<table tableName="user"/>
</context>
</generatorConfiguration>
第二步:使用java类来执行逆向工程
需要导入mysql的驱动包和mybatis的逆向工程包
public class Generator {
public static void main(String[] args) throws Exception{
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("config/generator.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
callback, warnings);
myBatisGenerator.generate(null);
}
}
第三步:把生成的代码拷贝到项目中
如果正式项目中已经有po类所在的包了,那么就只需要拷贝po类到指定包下就可以。
如果正式项目中没有po包,那么就把逆向工程中整个po类的包拷贝过去。
Mapper.xml和mapper.java的拷贝与po类一样。
自动生成的example是用来查询使用的
第四步:测试
逆向工程提供了很多查询方法,可以不用写sql,这个根hibernate有点类似