mybatis 应用第三方缓存框架ehcache
2017-11-17 12:44
465 查看
mybatis 应用第三方缓存框架ehcache
ehcache是一个分布式缓存框架,EhCache 是一个纯Java的进程内缓存框架,是一种广泛使用的开源Java分布式缓存,具有快速、精干等特点,是Hibernate中默认的CacheProvider。
mybatis提供了一个cache接口,如果要实现自己的缓存逻辑,实现cache接口开发即可。
mybatis和ehcache整合,mybatis和ehcache整合包中提供了一个cache接口的实现类:
1. 准备jar包
mybatis-ehcache-1.0.3.jar
ehcache-core-2.6.8.jar
slf4j-api-1.6.1.jar
其中,mybatis本身已经带了slf4j-api包,所以只需要拷贝前两个jar包即可
2. 整合Ehcache
在项目的src目录下,新建ehcache.xml文件,文件内容如下:
3. sql映射文件中配置cache:
打开需要缓存的实体映射文件(比如Emp.xml),加上cache,并指定处理缓存的实现类:
这个配置是会带上cache执行的日志,如果不要带日志可以把LogginEhcache改成EhcacheCache,如下:
到这里,ehcache缓存就配置完成了。
补充知识点:
如果与spring集成,除了需要完成上面的三步以外,还需要在spring的配置文件里面加上一段配置:
<bean id="manager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml"></property>
</bean>
最后,这个mapper.xml里面的操作是全局,默认为useCache="true" 都会有作用,
假如某个业务是不要缓存的,可以在当前业务下加上useCache="false"
下面是演示案例:
在mysql数据库中建一张emp表,表的字段如下:
本人演示的项目是Maven项目:
项目结构如下:
IEmpDAO.java为接口,提供查询emp的方法,EmpDAOImpl.java为接口的实现类,MybatisSqlSessionFactory.java为本人创建的获取sqlSession的工具类,Emp.java为实体类,Emp.xml为映射文件,ehcache.xml为二级缓存配置文件,log4j.properties为mybatis打印日志,mybatis_cfg.xml为mybatis主配置文件,Test.java为测试类,pom.xml为maven引入依赖的文件。
我在项目中使用二级缓存,测试的方法是根据员工的编号查询员工的信息。
1、IEmpDAO.java (提供一个根据员工编号查询员工信息的接口方法)
2、EmpDAOImpl.java 为接口的实现类
3、MybatisSqlSessionFactory.java 为本人创建的获取sqlSession的工具类
4、Emp.java为实体类
5、Emp.xml为映射文件
6、ehcache.xml为二级缓存配置文件
7、log4j.properties为mybatis打印日志
8、mybatis_cfg.xml为mybatis主配置文件
9、pom.xml为maven引入依赖的文件
10、Test.java为测试类
在测试中我们两次调用查询方法,在控制台的日志信息中发现我们的sql语句只是执行了一次,因为第二次查询的时候数据从二级缓存中取出(第一次查询时将数据保存到了二级缓存中)。
下面是日志的截图:
ehcache是一个分布式缓存框架,EhCache 是一个纯Java的进程内缓存框架,是一种广泛使用的开源Java分布式缓存,具有快速、精干等特点,是Hibernate中默认的CacheProvider。
mybatis提供了一个cache接口,如果要实现自己的缓存逻辑,实现cache接口开发即可。
mybatis和ehcache整合,mybatis和ehcache整合包中提供了一个cache接口的实现类:
1. 准备jar包
mybatis-ehcache-1.0.3.jar
ehcache-core-2.6.8.jar
slf4j-api-1.6.1.jar
其中,mybatis本身已经带了slf4j-api包,所以只需要拷贝前两个jar包即可
2. 整合Ehcache
在项目的src目录下,新建ehcache.xml文件,文件内容如下:
<ehcache> <!--表示硬盘上保存缓存的位置。默认是临时文件夹。--> <diskStore path="java.io.tmpdir"/> <!--默认缓存配置,如果类没有做特定的设置,则使用这里配置的缓存属性。 maxInMemory - 设置缓存中允许保存的最大对象(pojo)数量 eternal -设置对象是否永久保存,如果为true,则缓存中的数据永远不销毁,一直保存。 timeToIdleSeconds - 设置空闲销毁时间。只有eternal为false时才起作用。表示从现在到上次访问时间如果超过这个值,则缓存数据销毁 timeToLiveSeconds-设置活动销毁时间。表示从现在到缓存创建时间如果超过这个值,则缓存自动销毁 overflowToDisk - 设置是否在超过保存数量时,将超出的部分保存到硬盘上。--> <defaultCache maxElementsInMemory="1500" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="300" overflowToDisk="true"/> <!-- 也可以通过name设置针对某个类的缓存配置 <cache name="cn.sz.po.Emp" maxElementsInMemory="1000" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="false" />--> </ehcache>
3. sql映射文件中配置cache:
打开需要缓存的实体映射文件(比如Emp.xml),加上cache,并指定处理缓存的实现类:
<cache type="org.mybatis.caches.ehcache.LoggingEhcache" > <property name="timeToIdleSeconds" value="3600"/> <property name="timeToLiveSeconds" value="3600"/> <!-- 同ehcache参数maxElementsInMemory--> <property name="maxEntriesLocalHeap" value="1000"/> <!-- 同ehcache参数maxElementsOnDisk --> <property name="maxEntriesLocalDisk" value="10000000"/> <property name="memoryStoreEvictionPolicy" value="LRU"/> </cache>
这个配置是会带上cache执行的日志,如果不要带日志可以把LogginEhcache改成EhcacheCache,如下:
<!-- 如果不需要缓存日志,也可以改为EhCacheCache --> <cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
到这里,ehcache缓存就配置完成了。
补充知识点:
如果与spring集成,除了需要完成上面的三步以外,还需要在spring的配置文件里面加上一段配置:
<bean id="manager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml"></property>
</bean>
最后,这个mapper.xml里面的操作是全局,默认为useCache="true" 都会有作用,
假如某个业务是不要缓存的,可以在当前业务下加上useCache="false"
下面是演示案例:
在mysql数据库中建一张emp表,表的字段如下:
本人演示的项目是Maven项目:
项目结构如下:
IEmpDAO.java为接口,提供查询emp的方法,EmpDAOImpl.java为接口的实现类,MybatisSqlSessionFactory.java为本人创建的获取sqlSession的工具类,Emp.java为实体类,Emp.xml为映射文件,ehcache.xml为二级缓存配置文件,log4j.properties为mybatis打印日志,mybatis_cfg.xml为mybatis主配置文件,Test.java为测试类,pom.xml为maven引入依赖的文件。
我在项目中使用二级缓存,测试的方法是根据员工的编号查询员工的信息。
1、IEmpDAO.java (提供一个根据员工编号查询员工信息的接口方法)
package cn.sz.hcq.dao; import cn.sz.hcq.pojo.Emp; public interface IEmpDAO { /** * 根据员工编号查询员工信息 * * @param empno * @return */ public Emp findAllByEmpno(Integer empno); }
2、EmpDAOImpl.java 为接口的实现类
package cn.sz.hcq.dao.impl; import org.apache.ibatis.session.SqlSession; import cn.sz.hcq.dao.IEmpDAO; import cn.sz.hcq.factory.MybatisSqlSessionFactory; import cn.sz.hcq.pojo.Emp; public class EmpDAOImpl implements IEmpDAO { public Emp findAllByEmpno(Integer empno) { SqlSession sqlSession = null; try { sqlSession = MybatisSqlSessionFactory.getMySqlSession(); return sqlSession.selectOne("cn.sz.hcq.pojo.Emp.findEmpByEmpno", empno); } catch (Exception e) { e.printStackTrace(); } finally { MybatisSqlSessionFactory.closeSqlSession(); } return null; } }
3、MybatisSqlSessionFactory.java 为本人创建的获取sqlSession的工具类
package cn.sz.hcq.factory; import java.io.IOException; import java.io.Reader; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSes f240 sionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class MybatisSqlSessionFactory { // 配置文件 private static final String RESOURCE = "mybatis_cfg.xml"; private static Reader reader = null; private static SqlSessionFactoryBuilder builder = null; private static SqlSessionFactory factory = null; // 可以在同一个线程范围内,共享一个对象 private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>(); // 静态代码块(类加载的时候执行一次) static { try { reader = Resources.getResourceAsReader(RESOURCE); builder = new SqlSessionFactoryBuilder(); factory = builder.build(reader); } catch (IOException e) { e.printStackTrace(); } } public static SqlSession getMySqlSession() { // 从本地线程中获取session连接 SqlSession sqlSession = threadLocal.get(); // 连接为空则创建连接,并将该连接添加到本地线程中去 if (sqlSession == null) { if (factory == null) { rebuildFactory(); } sqlSession = factory.openSession(); } threadLocal.set(sqlSession); return sqlSession; } // 创建工厂 public static void rebuildFactory() { try { reader = Resources.getResourceAsReader(RESOURCE); builder = new SqlSessionFactoryBuilder(); factory = builder.build(reader); } catch (IOException e) { e.printStackTrace(); } } // 关闭连接 public static void closeSqlSession() { SqlSession sqlSession = threadLocal.get(); if (sqlSession != null) { // 关闭session sqlSession.close(); } // 同时将本地线程中置为null(防止用户再次调用时出现空的session) threadLocal.set(null); } }
4、Emp.java为实体类
package cn.sz.hcq.pojo; import java.io.Serializable; import java.util.Date; public class Emp implements Serializable { private Integer empno; private String ename; private String job; private Integer mgr; private Date hiredate; private Double sal; private Double comm; public Integer getEmpno() { return empno; } public void setEmpno(Integer empno) { this.empno = empno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public Integer getMgr() { return mgr; } public void setMgr(Integer mgr) { this.mgr = mgr; } public Date getHiredate() { return hiredate; } public void setHiredate(Date hiredate) { this.hiredate = hiredate; } public Double getSal() { return sal; } public void setSal(Double sal) { this.sal = sal; } public Double getComm() { return comm; } public void setComm(Double comm) { this.comm = comm; } }
5、Emp.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="cn.sz.hcq.pojo.Emp"> <!-- 日志缓存 --> <!-- <cache type="org.mybatis.caches.ehcache.LoggingEhcache"> <property name="timeToIdleSeconds" value="36000" /> <property name="timeToLiveSeconds" value="3600" /> 同ehcache参数maxElementsInMemory <property name="maxEntriesLocalHeap" value="1000" /> 同ehcache参数maxElementsOnDisk <property name="maxEntriesLocalDisk" value="10000000" /> <property name="memoryStoreEvictionPolicy" value="LRU" /> </cache> --> <!-- 普通缓存 --> <cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache> <!-- 根据员工编号查询员工信息 --> <select id="findEmpByEmpno" parameterType="java.lang.Integer" resultType="cn.sz.hcq.pojo.Emp" useCache="true"> select empno,ename,job,mgr,sal,comm,hiredate from emp where empno=#{empno} </select> </mapper>
6、ehcache.xml为二级缓存配置文件
<ehcache> <!--表示硬盘上保存缓存的位置。默认是临时文件夹。--> <diskStore path="java.io.tmpdir"/> <!--默认缓存配置,如果类没有做特定的设置,则使用这里配置的缓存属性。 maxElementsInMemory - 设置缓存中允许保存的最大对象(pojo)数量 eternal -设置对象是否永久保存,如果为true,则缓存中的数据永远不销毁,一直保存。 timeToIdleSeconds - 设置空闲销毁时间。只有eternal为false时才起作用。表示从现在到上次访问时间如果超过这个值,则缓存数据销毁 timeToLiveSeconds-设置活动销毁时间。表示从现在到缓存创建时间如果超过这个值,则缓存自动销毁 overflowToDisk - 设置是否在超过保存数量时,将超出的部分保存到硬盘上。--> <defaultCache maxElementsInMemory="1500" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="300" overflowToDisk="true"/> <!-- 也可以通过name设置针对某个类的缓存配置--> <!-- <cache name="cn.sz.hcq.pojo.Emp" maxElementsInMemory="1000" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="false" /> --> </ehcache>
7、log4j.properties为mybatis打印日志
log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %m%n log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=d:/log.txt log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %m%n log4j.rootLogger=debug,file,stdout #fatal-->error-->warn-->info-->debug log4j.logger.com.ibatis=DEBUG log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG log4j.logger.java.sql.Connection=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG
8、mybatis_cfg.xml为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> <!--数据源 --> <environments default="myconn"> <environment id="myconn"> <!--事务管理方式 --> <transactionManager type="JDBC"></transactionManager> <!--数据库连接参数 --> <dataSource type="POOLED"> <!-- type:数据源连接的方式 ,POOLED:连接池方式, UNPOOLED: 非连接池的方式 ,JNDI:java命名与目录接口方式 --> <property name="driver" value="org.gjt.mm.mysql.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/db"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </dataSource> </environment> </environments> <!-- 引入实体映射文件 --> <mappers> <mapper resource="cn/sz/hcq/pojo/Emp.xml" /> </mappers> </configuration>
9、pom.xml为maven引入依赖的文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.sz.hcq.pro</groupId> <artifactId>Mybatis_ehcache_06</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!-- mysql数据库驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.0.8</version> </dependency> <!--mybatis依赖 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.3</version> </dependency> <!-- 日志记录 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency> <!-- ehcache依赖 --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>2.6.8</version> </dependency> <dependency> <groupId>org.mybatis.caches</groupId> <artifactId>mybatis-ehcache</artifactId> <version>1.0.3</version> </dependency> </dependencies> </project>
10、Test.java为测试类
package cn.sz.hcq.test; import cn.sz.hcq.dao.IEmpDAO; import cn.sz.hcq.dao.impl.EmpDAOImpl; import cn.sz.hcq.pojo.Emp; public class Test { public static void main(String[] args) { IEmpDAO empDAO = new EmpDAOImpl(); // 查询编号为7788的员工 // 这里我们连续调用两次方法,发现sql语句就执行一次 empDAO.findAllByEmpno(7788); Emp emp = empDAO.findAllByEmpno(7788); System.out.println("姓名:" + emp.getEname() + ",员工号:" + emp.getEmpno()); } }
在测试中我们两次调用查询方法,在控制台的日志信息中发现我们的sql语句只是执行了一次,因为第二次查询的时候数据从二级缓存中取出(第一次查询时将数据保存到了二级缓存中)。
下面是日志的截图:
相关文章推荐
- mybatis二级缓存应用及与ehcache整合
- mybatis 中应用二级缓存(使用框架本身实现的缓存机制)
- mybatis二级缓存应用及与ehcache整合
- mybatis二级缓存应用及与ehcache整合
- MyBatis中使用Ehcache缓存框架
- ehcache缓存框架基本应用
- mybatis整合ehcache分布式二级缓存框架的使用
- mybatis学习教程中级(十)mybatis和ehcache缓存框架整合(重点)
- 【MyBatis框架】查询缓存-二级缓存-整合ehcache
- [原创]mybatis中整合ehcache缓存框架的使用
- 【MyBatis框架】查询缓存-二级缓存-整合ehcache
- mybatis详解-(22)整合第三方缓存Ehcache
- mybatis中整合ehcache缓存框架的使用
- mybatis整合ehcache分布式缓存框架
- MyBatis中如何合理的使用EhCache缓存框架
- mybatis和ehcache缓存框架整合
- Mybatis学习(十四)mybatis框架下整合分布式缓存ehcache
- 【MyBatis框架】查询缓存-二级缓存-整合ehcache
- 【MyBatis框架】查询缓存-二级缓存-整合ehcache
- MyBatis框架——二级缓存-整合ehcache 缓存框架