mybatis 中应用二级缓存(使用框架本身实现的缓存机制)
2017-11-17 13:06
746 查看
mybatis 中应用二级缓存(使用框架本身实现的缓存机制)
1. 在mybatis的配置文件中,开启二级缓存(cacheEnabled设置为 true).
在mybatis_config.xml文件中,设置如下:
2. 在实体映射文件中,应用二级缓存:
flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。
readOnly(只读)属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
eviction配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会导致冲突。可用的收回策略有, 默认的是 LRU:
1. LRU – 最近最少使用的:移除最长时间不被使用的对象。
2. FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
3. SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
4. WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
3. 缓存对象执行序列化
由于二级缓存的数据不一定都是存储到内存中,它的存储介质多种多样,所以需要给缓存的对象执行序列化。
如果该类存在父类,那么父类也要实现序列化,类似如下写法:
public class Emp implements Serializable {
}
到这里,二级缓存配置完成。
在应用二级缓存过程中,我们还可以禁用二级缓存:
该statement中设置userCache=false可以禁用当前select语句的二级缓存,即每次查询都是去数据库中查询,默认情况下是true,即该statement使用二级缓存.
还可以刷新二级缓存:
下面是演示案例:
在mysql数据库中建一张emp表,表的字段如下:
本人演示的项目是Maven项目:
项目结构如下:
IEmpDAO.java为接口,提供查询emp的方法,EmpDAOImpl.java为接口的实现类,MybatisSqlSessionFactory.java为本人创建的获取sqlSession的工具类,Emp.java为实体类,Emp.xml为映射文件,log4j.properties为mybatis打印日志,mybatis_cfg.xml为mybatis主配置文件,Test.java为测试类,pom.xml为maven引入依赖的文件。
我在项目中使用二级缓存,测试的方法是根据员工的编号查询员工的信息。
1、IEmpDAO.java (提供一个根据员工编号查询员工信息的接口方法)
[java] view
plain copy
<span style="font-size:18px;">package cn.sz.hcq.dao;
import cn.sz.hcq.pojo.Emp;
public interface IEmpDAO {
/**
* 根据员工编号查询员工信息
*
* @param empno
* @return
*/
public Emp findAllByEmpno(Integer empno);
}
</span>
2、EmpDAOImpl.java 为接口的实现类
[java] view
plain copy
<span style="font-size:18px;">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;
}
}
</span>
3、MybatisSqlSessionFactory.java 为本人创建的获取sqlSession的工具类
[java] view
plain copy
<span style="font-size:18px;">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.SqlSessionFactory;
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);
}
}
</span>
4、Emp.java为实体类
[java] view
plain copy
<span style="font-size:18px;">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;
}
}
</span>
5、Emp.xml为映射文件
6、log4j.properties为mybatis打印日志
[plain] view
plain copy
<span style="font-size:18px;">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</span>
7、mybatis_cfg.xml为mybatis主配置文件
8、pom.xml为maven引入依赖的文件
[html] view
plain copy
<span style="font-size:18px;"><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>
</dependencies>
</project></span>
9、Test.java为测试类
[java] view
plain copy
<span style="font-size:18px;">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());
}
}
</span>
在测试中我们两次调用查询方法,在控制台的日志信息中发现我们的sql语句只是执行了一次,因为第二次查询的时候数据从二级缓存中取出(第一次查询时将数据保存到了二级缓存中)。
下面是日志的截图:
1. 在mybatis的配置文件中,开启二级缓存(cacheEnabled设置为 true).
在mybatis_config.xml文件中,设置如下:
<settings> <!-- 开启二级缓存,默认为true(默认二级缓存是开启的) --> <setting name="cacheEnabled" value="true"/> </settings>
2. 在实体映射文件中,应用二级缓存:
<cache eviction='FIFO' flushInterval='60000' size='512' readOnly='true'/>其中各项属性代表的含义为:
flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。
readOnly(只读)属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
eviction配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会导致冲突。可用的收回策略有, 默认的是 LRU:
1. LRU – 最近最少使用的:移除最长时间不被使用的对象。
2. FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
3. SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
4. WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
3. 缓存对象执行序列化
由于二级缓存的数据不一定都是存储到内存中,它的存储介质多种多样,所以需要给缓存的对象执行序列化。
如果该类存在父类,那么父类也要实现序列化,类似如下写法:
public class Emp implements Serializable {
}
到这里,二级缓存配置完成。
在应用二级缓存过程中,我们还可以禁用二级缓存:
<!-- 查询全部员工信息 --> <select id="findAllEmp" resultType="cn.sz.hcq.pojo.Emp" useCache="false"> select empno, ename, job, mgr, hiredate, sal, comm from emp </select>
该statement中设置userCache=false可以禁用当前select语句的二级缓存,即每次查询都是去数据库中查询,默认情况下是true,即该statement使用二级缓存.
还可以刷新二级缓存:
<!-- 查询全部员工信息 --> <select id="findAllEmp" resultType="cn.sz.hcq.pojo.Emp" flushCache="true"> select empno, ename, job, mgr, hiredate, sal, comm from emp </select>
下面是演示案例:
在mysql数据库中建一张emp表,表的字段如下:
本人演示的项目是Maven项目:
项目结构如下:
IEmpDAO.java为接口,提供查询emp的方法,EmpDAOImpl.java为接口的实现类,MybatisSqlSessionFactory.java为本人创建的获取sqlSession的工具类,Emp.java为实体类,Emp.xml为映射文件,log4j.properties为mybatis打印日志,mybatis_cfg.xml为mybatis主配置文件,Test.java为测试类,pom.xml为maven引入依赖的文件。
我在项目中使用二级缓存,测试的方法是根据员工的编号查询员工的信息。
1、IEmpDAO.java (提供一个根据员工编号查询员工信息的接口方法)
[java] view
plain copy
<span style="font-size:18px;">package cn.sz.hcq.dao;
import cn.sz.hcq.pojo.Emp;
public interface IEmpDAO {
/**
* 根据员工编号查询员工信息
*
* @param empno
* @return
*/
public Emp findAllByEmpno(Integer empno);
}
</span>
2、EmpDAOImpl.java 为接口的实现类
[java] view
plain copy
<span style="font-size:18px;">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;
}
}
</span>
3、MybatisSqlSessionFactory.java 为本人创建的获取sqlSession的工具类
[java] view
plain copy
<span style="font-size:18px;">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.SqlSessionFactory;
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);
}
}
</span>
4、Emp.java为实体类
[java] view
plain copy
<span style="font-size:18px;">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;
}
}
</span>
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 eviction='FIFO' flushInterval='60000' size='512' readOnly='true' /> <!-- 根据员工编号查询员工信息 --> <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、log4j.properties为mybatis打印日志
[plain] view
plain copy
<span style="font-size:18px;">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</span>
7、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> <!-- 配置的参数 --> <settings> <!-- 开启二级缓存,默认为true(默认二级缓存是开启的) --> <setting name="cacheEnabled" value="true" /> </settings> <!--数据源 --> <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>
8、pom.xml为maven引入依赖的文件
[html] view
plain copy
<span style="font-size:18px;"><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>
</dependencies>
</project></span>
9、Test.java为测试类
[java] view
plain copy
<span style="font-size:18px;">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());
}
}
</span>
在测试中我们两次调用查询方法,在控制台的日志信息中发现我们的sql语句只是执行了一次,因为第二次查询的时候数据从二级缓存中取出(第一次查询时将数据保存到了二级缓存中)。
下面是日志的截图:
相关文章推荐
- mybatis整合ehcache分布式二级缓存框架的使用
- Mybatis使用OSCache和EHcache实现二级缓存
- (spring-data-redis)SSM框架下使用redis作为mybatis的二级缓存
- SSM框架day02-MyBatis——059 查询缓存管理-增删改对二级缓存的影响、060 查询缓存管理-二级缓存的配置、061 查询缓存管理-二级缓存的使用原则
- Mybatis使用OSCache和EHcache实现二级缓存
- 深入理解mybatis原理(六) MyBatis缓存机制的设计与实现如何细粒度地控制你的MyBatis二级缓存
- 《深入理解mybatis原理(六)》 MyBatis缓存机制的设计与实现如何细粒度地控制你的MyBatis二级缓存
- 《深入理解mybatis原理(六)》 MyBatis缓存机制的设计与实现如何细粒度地控制你的MyBatis二级缓存
- 使用hibernate二级缓存优化你的应用
- 三大框架使用二级缓存执行executeUpdate()
- 一种高效的对象缓存机制在测试框架中的应用
- [笔记] ASP.NET本身的缓存实现机制,基于Cache的实现。提供按分类进行管理的缓存功能
- 基于V4L2视频采集缓存机制应用与实现
- hibernate4.1.2使用ehcache2.4.3实现二级缓存时报错
- SpringMVC+Spring+mybatis 实现登录过程(使用后台验证框架)
- SilverLight企业应用框架设计【五】客户端调用服务端(使用JSON传递数据,自己实现RESTful Web服务)
- hibernate4.1.2使用ehcache2.4.3实现二级缓存时报错
- GridView实战二:使用ObjectDataSource数据源控件(自定义缓存机制实现Sort)
- Google应用在Android上的Push机制以及C2DM框架的底层实现
- Google应用在Android上的Push机制以及C2DM框架的底层实现