Redis快取配置及使用
阿新 • • 發佈:2018-11-08
Spring Boot整合Redis快取
Maven依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<!-- 不依賴redis的非同步客戶端 lettuce -->
<exclusion>
< groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入Redis的客戶端驅動jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId >
</dependency>
<!-- dbcp2連線池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency>
<!-- mabatis -->
<dependency>
<groupId>org.mybatis.spring.boot</ groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- fastJson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastJson</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
快取管理器配置
# redis快取管理配置
#設定快取型別位redis
spring.cache.type=redis
#配置快取名稱
spring.cache.cache-names=redisCache
#是否允許redis快取空值
spring.cache.redis.cache-null-values=true
#redis的鍵字首
spring.cache.redis.key.prefix=
#快取超時時間戳,配置為0則不設定超時時間
spring.cache.redis.time-to-live=0ms
#是否啟用redis的鍵字首
spring.cache.redis.use-key-preficx=true
這裡我們只需要配置兩個
# redis快取管理配置
spring.cache.type=redis
spring.cache.cache-names=redisCache
啟用快取機制
添加註解@EnableCaching
package com.lay.redis;
@SpringBootApplication
@MapperScan(basePackages = "com.lay.redis", annotationClass = Mapper.class)
@EnableCaching
public class SpringbootRedisApplication {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(SpringbootRedisApplication.class, args);
}
這樣就能驅動快取機制了。
下面我們整合mybatis框架來測試快取機制的使用
搭建環境
配置檔案
#資料庫配置
spring.datasource.url=jdbc:mysql://192.168.0.106:3306/springboot_database?useUnicode=true&characterEncoding=utf8
spring.datasource.username=developer
[email protected]$R
# spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#指定資料連線池的型別
spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
#最大等待連線中的數量,設定0為沒有限
spring.datasource.dbcp2.max-idle=10
#最大連線活動數
spring.datasource.dbcp2.max-total=50
#最大等待毫秒數,單位ms,超過時間會出錯誤資訊
spring.datasource.dbcp2.max-wait-millis=10000
#資料庫連線池初始化連線數
spring.datasource.dbcp2.initial-size=5
#設定預設的隔離級別為讀寫提交
spring.datasource.dbcp2.default-transaction-isolation=2
# mybatis配置
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package: com.lay.redis.entity
# 配置typehandler型別轉換的掃描包
mybatis.type-handlers-package=com.lay.redis.typehandler
#駝峰命名轉換
mybatis.configuration.mapUnderscoreToCamelCase=true
# 配置redis連線池屬性
spring.redis.jedis.pool.max-active=10
spring.redis.jedis.pool.max-idle=10
spring.redis.jedis.pool.max-wait=2000
spring.redis.jedis.pool.min-idle=5
#配置redis伺服器屬性
spring.redis.port=6379
spring.redis.host=192.168.0.106
spring.redis.password=123456
#redis連線超時時間
spring.redis.timeout=1000
#springmvc字符集
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
# redis快取管理配置
spring.cache.type=redis
spring.cache.cache-names=redisCache
#日誌級別
logging.level.root=debug
logging.level.org.springframework=debug
logging.level.org.org.org.mybatis=debug
使用者實體
package com.lay.redis.entity;
import java.io.Serializable;
import org.apache.ibatis.type.Alias;
import com.lay.redis.enumeration.SexEnum;
@Alias("person")
public class Person implements Serializable {
private static final long serialVersionUID = 3172000990909338544L;
private Long id = null;
private String personName = null;
//性別列舉,這裡需要使用typeHandler進行轉換
private SexEnum sex = null;//列舉
private String note = null;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public SexEnum getSex() {
return sex;
}
public void setSex(SexEnum sex) {
this.sex = sex;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}
mybatis操作介面
package com.lay.redis.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.lay.redis.entity.Person;
@Mapper
public interface PersonDao {
//獲取單個使用者
public Person getPerson(Long id);
//新增使用者
public int insertPerson(Person person);
//更新使用者
public int updatePerson(Person person);
//獲取全部使用者
public List<Person> getAllPersons();
//刪除使用者
public int deletePerson(Long id);
}
sql和對映關係mapper
<?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="com.lay.redis.dao.PersonDao">
<select id="getPerson" parameterType="long" resultType="person">
select id,person_name,sex,note from t_person where id=#{id}
</select>
<insert id="insertPerson" useGeneratedKeys="true" keyProperty="id" >
insert into t_person(person_name,sex,note) values(#{personName},#{sex},#{note})
</insert>
<update id="updatePerson">
update t_person
<set>
<if test="personName!=null">person_name=#{personName},</if>
<if test="sex!=null">sex=#{sex},</if>
<if test="note!=null">note=#{note}</if>
</set>
where id=#{id}
</update>
<select id="getAllPersons" resultType="person">
select id,person_name,sex,note from t_person
</select>
<delete id="deletePerson" parameterType="long">
delete from t_person where id=#{id}
</delete>
</mapper>
服務層Service
package com.lay.redis.service;
import java.util.List;
import com.lay.redis.entity.Person;
public interface PersonService {
//獲取單個使用者
public Person getPerson(Long id);
//新增使用者
public Person insertPerson(Person person);
//更新使用者名稱
public Person updatePerson(Long id, String personName);
//獲取全部使用者
public List<Person> getAllPersons();
//刪除使用者
public int deletePerson(Long id);
}
服務層實現
package com.lay.redis.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.lay.redis.dao.PersonDao;
import com.lay.redis.entity.Person;
import com.lay.redis.service.PersonService;
@Service
public class PersonServiceImpl implements PersonService {
@Autowired
PersonDao personDao;
//獲取id,取引數id快取使用者
@Override
@Transactional
@Cacheable(value = "redisCache", key = "'redis_person_'+#id")
public Person getPerson(Long id) {
return personDao.getPerson(id);
}
//插入使用者,最後mybatis會回填id,取結果id快取使用者
@Override
@Transactional(isolation = Isolation.READ_COMMITTED, timeout = 1, propagation = Propagation.REQUIRES_NEW)
@CachePut(value = "redisCache", key = "'redis_person_'+#result.id")
public Person insertPerson(Person person) {
System.out.println("===========sex==========" + person.getSex().getId());
personDao.insertPerson(person);
return person;
}
//更新資料後,更新快取,如果condition配置項使結果返回為Null,不快取
@Override
@Transactional
@CachePut(value = "redisCache", condition = "#result!='null'", key = "'redis_person_'+#id")
public Person updatePerson(Long id, String personName) {
Person person = this.getPerson(id);
if (person == null) {
return null;
}
person.setPersonName(personName);
personDao.updatePerson(person);
return person;
}
@Override
public List<Person> getAllPersons() {
return personDao.getAllPersons();
}
//移除快取
@Override
@Transactional
@CacheEvict(value = "redisCache", key = "'redis_person_'+#id", beforeInvocation = false)
public int deletePerson(Long id) {
return personDao.deletePerson(id);
}
}
- @CachePut:將方法結果返回存放到快取中
- @Cacheable:先從快取中通過定義的鍵查詢,如果可以查到資料,則返回,否則執行該方法,返回資料,並且將返回的結果儲存到快取中。
- @CacheEvict:通過定義的鍵移除快取,它有一個boolean型別的配置項
beforeInvocation
,表示在方法之前或者之後移除快取。預設是false
,所以預設為方法之後將快取移除。
value="redisCache"與在spring配置檔案中的快取名稱對應,這樣就能夠引用到對應的快取中去了。
測試快取註解
package com.lay.redis.controller;
@Controller
@RequestMapping(value = "/person")
public class PersonController {
@Autowired
PersonService personService;
@RequestMapping(value = "/getPerson")
@ResponseBody
public Person getPerson(@RequestParam("id") Long id) {
return personService.getPerson(id);
}
@RequestMapping(value = "/insertPerson")
@ResponseBody
public Person inserPerson(String personName, String sex, String note) {
Person person = new Person();
person.setPersonName(personName);
person.setSex(SexEnum.getEnumByName(sex));
person.setNote(note);
personService.insertPerson(person);
return person;
}
@RequestMapping(value = "/updatePersonName")
@ResponseBody
public Map<String, Object> updatePerson(Long id, String personName) {
Person person = personService.updatePerson(id, personName);
boolean flag = person != null;
String message = flag ? "更新成功" : "更新失敗";
return resultMap(flag, message);
}
@RequestMapping(value = "/getAllPerson")
@ResponseBody
public List<Person> getAllPerson() {
return personService.getAllPersons();
}
@RequestMapping(value = "/deletePerson")
@ResponseBody
public Map<String, Object> inserPerson(Long id) {
int result = personService.deletePerson(id);
boolean flag = result == 1;
String message = flag ? "更新成功" : "更新失敗";
return resultMap(flag, message);
}
private Map<String, Object> resultMap(boolean success, String message) {
Map<String, Object> result = new HashMap<String, Object>();
result.put("success", success);
result.put("message", message);
return result;
}
}
自定義快取序列化方式
redis預設快取為jdkserialize,我們改成熟悉的json
引入阿里巴巴的fastjson
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastJson</artifactId>
<version>1.2.17</version>
</dependency>
實現redis快取序列化方式
package com.lay.redis.utils;
/**
* 自定義redis快取序列化方式
* @Description TODO
* @ClassName FastJsonRedisSerializer
* @Date 2018年11月4日 下午9:51:25
* @Author lay
*/
public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
public FastJsonRedisSerializer(Class<T> clazz) {
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException {
if (t == null) {
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (bytes == null || bytes.length <= 0) {
return null;
}
String str =