二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。
下面是使用Ehcache来作为Mybatis二级缓存的实例:
application.properties开启mybatis中二级缓存
==mybatis.configuration.cache-enabled=true==
默认二级缓存是开启的
server.port=80
# 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/ssb_test
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
#连接池配置
#spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
#mybatis
#entity扫描的包名
mybatis.type-aliases-package=com.xiaolyuh.domain.model
#Mapper.xml所在的位置
mybatis.mapper-locations=classpath*:/mybaits/*Mapper.xml
#开启MyBatis的二级缓存
mybatis.configuration.cache-enabled=true
#pagehelper
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql
#日志配置
logging.level.com.xiaolyuh=debug
logging.level.org.springframework.web=debug
logging.level.org.springframework.transaction=debug
logging.level.org.mybatis=debug
debug=false
pom.xml
4.0.0
spring-boot-student-mybatis-ehcache
jar
spring-boot-student-mybatis-ehcache
Demo Mybatis ehcache for Spring Boot
com.xiaolyuh
spring-boot-student
0.0.1-SNAPSHOT
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.0
com.github.pagehelper
pagehelper-spring-boot-starter
1.1.1
com.alibaba
fastjson
1.2.31
net.sf.ehcache
ehcache
org.mybatis
mybatis-ehcache
1.0.0
Ehcache配置
在src\main\resources目录下创建ehcache.xml文件,内容如下:
Mapper文件
完整的Mapper文件,如下:
id, name, age, address
delete from person
where id = #{id,jdbcType=BIGINT}
SELECT LAST_INSERT_ID()
insert into person (name, age, address
)
values (#{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}, #{address,jdbcType=VARCHAR}
)
SELECT LAST_INSERT_ID()
insert into person
name,
age,
address,
#{name,jdbcType=VARCHAR},
#{age,jdbcType=INTEGER},
#{address,jdbcType=VARCHAR},
update person
name = #{name,jdbcType=VARCHAR},
age = #{age,jdbcType=INTEGER},
address = #{address,jdbcType=VARCHAR},
where id = #{id,jdbcType=BIGINT}
update person
set name = #{name,jdbcType=VARCHAR},
age = #{age,jdbcType=INTEGER},
address = #{address,jdbcType=VARCHAR}
where id = #{id,jdbcType=BIGINT}
实体类
package com.xiaolyuh.domain.model;
import java.io.Serializable;
public class Person implements Serializable {
private Long id;
/**
* 名称
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 地址
*/
private String address;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Mapper-类
package com.xiaolyuh.domain.mapper;
import com.github.pagehelper.Page;
import com.xiaolyuh.domain.model.Person;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper//声明成mybatis Dao层的Bean,也可以在配置类上使用@MapperScan("com.xiaolyuh.domain.mapper")注解声明
public interface PersonMapper {
int deleteByPrimaryKey(Long id);
int insert(Person record);
int insertSelective(Person record);
Person selectByPrimaryKey(Long id);
int updateByPrimaryKeySelective(Person record);
int updateByPrimaryKey(Person record);
/**
* 获取所有数据
* @return
*/
List findAll();
/**
* 分页查询数据
* @return
*/
Page findByPage();
}
Severice接口类
package com.xiaolyuh.service;
import com.github.pagehelper.Page;
import com.xiaolyuh.domain.model.Person;
import java.util.List;
/**
* Created by yuhao.wang on 2017/6/19.
*/
public interface PersonService {
List findAll();
/**
* 分页查询
* @param pageNo 页号
* @param pageSize 每页显示记录数
* @return
*/
Page findByPage(int pageNo, int pageSize);
void insert(Person person);
}
Severice实现类
package com.xiaolyuh.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.xiaolyuh.domain.mapper.PersonMapper;
import com.xiaolyuh.domain.model.Person;
import com.xiaolyuh.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* Created by yuhao.wang on 2017/6/19.
*/
@Service
@Transactional(readOnly = true)
public class PersonServiceImpl implements PersonService {
@Autowired
private PersonMapper personMapper;
@Override
public List findAll() {
return personMapper.findAll();
}
@Override
public Page findByPage(int pageNo, int pageSize) {
PageHelper.startPage(pageNo, pageSize);
return personMapper.findByPage();
}
@Override
@Transactional
public void insert(Person person) {
personMapper.insert(person);
}
}
测试类
package com.xiaolyuh;
import com.github.pagehelper.Page;
import com.xiaolyuh.domain.model.Person;
import com.xiaolyuh.service.PersonService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class PersonMapperTests {
private Logger logger = LoggerFactory.getLogger(PersonMapperTests.class);
@Autowired
private PersonService personService;
@Before
public void testInsert() {
Person person = new Person();
person.setName("测试");
person.setAddress("address");
person.setAge(10);
personService.insert(person);
Assert.assertNotNull(person.getId());
logger.debug(JSON.toJSONString(person));
}
@Test
public void testFindAll() {
List persons = personService.findAll();
Assert.assertNotNull(persons);
logger.debug(JSON.toJSONString(persons));
}
@Test
public void testFindByPage() {
Page persons = personService.findByPage(1, 2);
Assert.assertNotNull(persons);
logger.debug(persons.toString());
logger.debug(JSON.toJSONString(persons));
}
@Test
public void testCacheByPage() {
long begin = System.currentTimeMillis();
List persons = personService.findAll();
long ing = System.currentTimeMillis();
personService.findAll();
long end = System.currentTimeMillis();
logger.debug("第一次请求时间:" + (ing - begin) + "ms");
logger.debug("第二次请求时间:" + (end - ing) + "ms");
Assert.assertNotNull(persons);
logger.debug(persons.toString());
logger.debug(JSON.toJSONString(persons));
}
}
执行测试类,打印日志信息
Cache Hit Ratio [com.xiaolyuh.domain.mapper.PersonMapper]: 0.5
2017-06-28 10:15:32.214 DEBUG 10472 --- [ main] org.mybatis.spring.SqlSessionUtils : Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3f6c2763]
2017-06-28 10:15:32.214 DEBUG 10472 --- [ main] org.mybatis.spring.SqlSessionUtils : Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3f6c2763]
2017-06-28 10:15:32.214 DEBUG 10472 --- [ main] org.mybatis.spring.SqlSessionUtils : Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3f6c2763]
2017-06-28 10:15:32.214 DEBUG 10472 --- [ main] org.mybatis.spring.SqlSessionUtils : Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3f6c2763]
2017-06-28 10:15:32.223 DEBUG 10472 --- [ main] com.xiaolyuh.PersonMapperTests : 第一次请求时间:26ms
2017-06-28 10:15:32.223 DEBUG 10472 --- [ main] com.xiaolyuh.PersonMapperTests : 第二次请求时间:11ms
源码
https://github.com/wyh-spring-ecosystem-student/spring-boot-student/tree/releases
spring-boot-student-mybatis-ehcache工程