文章目錄
1.在Spring Boot中集成Redis
1)添加依賴
pom.xml
添加的依賴包含Redis,Mysql,MyBatis,fastjson,junit
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
2)配置application.properties
application.properties
配置mysql,redis服務器
spring.datasource.url=jdbc:mysql://127.0.0.1/book?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true
spring.datasource.initialization-mode=always
spring.datasource.schema=classpath:db/schema.sql
# Redis數據庫索引(默認爲0)
spring.redis.database=1
# Redis服務器地址
spring.redis.host=127.0.0.1
# Redis服務器連接端口
spring.redis.port=6379
# Redis服務器連接密碼(默認爲空)
spring.redis.password=
# 連接池最大連接數(使用負值表示沒有限制)
spring.redis.jedis.pool.max-active=8
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.jedis.pool.max-wait=-1
# 連接池中的最大空閒連接
spring.redis.jedis.pool.max-idle=8
# 連接池中的最小空閒連接
spring.redis.jedis.pool.min-idle=0
# 連接超時時間(毫秒)
spring.redis.timeout=5000
3)在入口類加上@EnableCaching註解,開啓緩存支持
RedisDemoApplication.java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class RedisDemoApplication {
public static void main(String[] args) {
SpringApplication.run(RedisDemoApplication.class, args);
}
}
4)建立下面的項目結構
2.配置Redis類
要想啓動Spring緩存支持,需要創建一個CacheManager的Bean。
RedisConfig.java
package com.example.demo.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.lang.reflect.Method;
@Configuration
public class RedisConfig extends CachingConfigurerSupport{
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
@SuppressWarnings("rawtypes")
@Bean
//緩存管理器
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheManager cacheManager = RedisCacheManager.create(connectionFactory);
//設置緩存過期時間
return cacheManager;
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
//配置連接工廠
StringRedisTemplate template = new StringRedisTemplate(factory);
//使用Jackson2JsonRedisSerializer來序列化和反序列化redis 的value值
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
//指定要序列化的域,field,get和set,以及修飾符範圍
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//指定序列化輸入的類型,類必須是非final類
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(om);
//序列化配置爲String格式
template.setValueSerializer(new StringRedisSerializer());
//
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
關於Redis Template中序列化和反序列化配置的解釋
關於數據的“序列化/反序列化”,提供了多種可選擇策略(RedisSerializer)
序列化/發序列化 | 解釋 |
---|---|
JdkSerializationRedisSerializer | POJO對象的存取場景,使用JDK本身序列化機制,將pojo類通過ObjectInputStream/ObjectOutputStream進行序列化操作,最終redis-server中將存儲字節序列。 |
StringRedisSerializer | 適用於Key或者value爲字符串的場景,根據指定的charset對數據的字節序列編碼成string |
JacksonJsonRedisSerializer | 提供了javabean與json之間的轉換能力,可以將pojo實例序列化成json格式存儲在redis中,也可以將json格式的數據轉換成pojo實例。 |
OxmSerializer | 提供了將javabean與xml之間的轉換能力,目前可用的三方支持包括jaxb,apache-xmlbeans;redis存儲的數據將是xml工具。 |
上面4種策略中:
JdkSerializationRedisSerializer
和StringRedisSerializer
是最基礎的策略,在設計時仍然不推薦直接使用後面兩種,即JacksonJsonRedisSerializer
和OxmSerializer
,因爲無論是json還是xml,他們本身仍然是String。
如果數據需要被第三方工具解析,那麼數據應該使用StringRedisSerializer
而不是JdkSerializationRedisSerializer
。
如果數據格式必須爲json或者xml,那麼在編程級別,在redisTemplate配置中仍然使用StringRedisSerializer
,在存儲之前或者讀取之後,使用“SerializationUtils”工具轉換轉換成json或者xml
3.創建測試實體類
User.java
package com.example.demo.model;
import lombok.Data;
import java.io.Serializable;
@Data
public class User implements Serializable {
private String id;
private String name;
private int age;
}
這裏需要注意的是spring boot在啓動時會自動創建user表
在項目的resources目錄下新建db目錄,並添加schema.sql文件,寫入創建user表的sql語句
當然還需要配置數據庫連接,並加上數據表初始化的配置(配置工作前面的文件中已經包含)
這裏是schema.sql
DROP TABLE IF EXISTS user;
--IF object_id('user','U') is not NULL drop table 'user';
CREATE TABLE user(
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(255) DEFAULT NULL,
age int(11) DEFAULT NULL,
PRIMARY KEY (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
4.實現實體和數據表的映射關係
UserMapper.java
package com.example.demo.mapper;
import com.example.demo.model.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;
@Repository
@Mapper
public interface UserMapper {
@Insert("insert into user(name,age) values(#{name},#{age})")
int addUser(@Param("name")String name,@Param("age")String age);
@Select("select * from user where id=#{id}")
User findById(@Param("id")String id);
@Update("update user set name=#{name},age=#{age} where id=#{id}")
int updateById(User user);
@Delete("delete from user where id=#{id}")
void deleteById(@Param("id")String id);
}
5.創建Redis緩存服務器
創建Redis緩存服務器,即緩存在服務器層面
UserService.java
代碼解釋
@Cacheable:將查詢結果緩存到Redis中
key="#p0":指定傳入的第一個參數作爲Redis的key
@CachePut:指定key,將更新的結果同步到Redis中
@CacheEvict:指定key,刪除緩存數據
allEntries:方法調用後將立即清除緩存
package com.example.demo.service;
import com.example.demo.model.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
//Redis緩存服務層
@Service
@CacheConfig(cacheNames = "users")
public class UserService {
@Autowired
UserMapper userMapper;
@Cacheable(key="#p0")
public User selectUser(String id){
System.out.println("select");
return userMapper.findById(id);
}
@CachePut(key="#p0")
public void updateById(User user){
System.out.println("uddate");
userMapper.updateById(user);
}
//如果allEntries指定爲true,則調用CacheEvict方法後將立即清空所有緩存
@CacheEvict(key="#p0",allEntries = true)
public void deleteById(String id){
System.out.println("delete");
userMapper.deleteById(id);
}
}
6.完成增刪改查測試API
RedisController.java
package com.example.demo.controller;
import com.example.demo.service.UserService;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class RedisController {
@Autowired
UserService userService;
@RequestMapping("/{id}")
public User ForTest(@PathVariable String id){
return userService.selectUser(id);
}
@RequestMapping( "/update/")
public String update(User user){
userService.updateById(user);
return "success";
}
@RequestMapping( "/delete/{id}")
public String delete (@PathVariable String id){
userService.deleteById(id);
return "delete success";
}
}
7.啓動測試
1)啓動Redis服務
由於沒有設置環境變量,需要手動進入到Redis安裝目錄cd /d D:\Redis-x64-3.2.100
,然後啓動服務
redis-server.exe redis.windows.conf
在cmd窗口打開的情況下,運行項目
2)多次訪問
http://localhost:8080/user/2
第一次時控制檯會出現select信息,代表對數據庫進行了查詢操作。後面再訪問則不會出現提示,表示沒有對數據庫執行操作,而是使用Redis中的緩存數據。