redis:
host: 127.0.0.1
password:
port: 6379
database: 0
lettuce:
pool:
max-idle: 8
min-idle: 0
max-active: 8
max-wait: -1ms
timeout: 10000ms
package com.example.springbootdemo.config;
import com.example.springbootdemo.utils.RedisObjectSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
/**
*
- @author rstyro
- @time 2017-07-31
*/
@Configuration
@EnableCaching // 开启缓存支持
public class RedisConfig extends CachingConfigurerSupport {
@Resource
private LettuceConnectionFactory lettuceConnectionFactory;
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuffer sb = new StringBuffer();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
// 缓存管理器
@Bean
public CacheManager cacheManager() {
RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder
.fromConnectionFactory(lettuceConnectionFactory);
@SuppressWarnings("serial")
Set<String> cacheNames = new HashSet<String>() {
{
add("codeNameCache");
}
};
builder.initialCacheNames(cacheNames);
return builder.build();
}
/**
* RedisTemplate配置
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
// 设置序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置redisTemplate
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);// key序列化
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
/**
* RedisTemplate配置
*/
@Bean
public RedisTemplate<String, ?> redisTemplates(RedisConnectionFactory factory) {
RedisTemplate<String, ?> template = new RedisTemplate();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new RedisObjectSerializer());
return template;
}
}
package com.example.springbootdemo.config;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
/**
- redisson 配置,下面是单节点配置:
- 官方wiki地址:https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95#26-%E5%8D%95redis%E8%8A%82%E7%82%B9%E6%A8%A1%E5%BC%8F
*/
@Configuration
public class RedissonConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private String port;
@Value("${spring.redis.password}")
private String password;
@Bean
public RedissonClient redissonClient(){
Config config = new Config();
//单节点
config.useSingleServer().setAddress("redis://" + host + ":" + port);
if(StringUtils.isEmpty(password)){
config.useSingleServer().setPassword(null);
}else{
config.useSingleServer().setPassword(password);
}
//添加主从配置
// config.useMasterSlaveServers().setMasterAddress("").setPassword("").addSlaveAddress(new String[]{"",""});
// 集群模式配置 setScanInterval()扫描间隔时间,单位是毫秒, //可以用"rediss://"来启用SSL连接
// config.useClusterServers().setScanInterval(2000).addNodeAddress(“redis://127.0.0.1:7000”, “redis://127.0.0.1:7001”).addNodeAddress(“redis://127.0.0.1:7002”);
return Redisson.create(config);
}
}
package com.example.springbootdemo.utils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestHash {
@Autowired
private RedisTemplate<String,String> redisTemplate;
@Test
public void testHash(){
//创建对象
HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
//存储一条数据
opsForHash.put("orderInfo","orderId","11");
//获取一条数据
String value = opsForHash.get("orderInfo", "orderId");
System.out.println(value);
//存储多条数据
Map<String,String> map = new HashMap<>();
map.put("createTime","2018-06-21");
map.put("orderSn","888888");
opsForHash.putAll("orderInfo",map);
//获取多条数据
List<String> listKey = new ArrayList<>();
listKey.add("createTime");
listKey.add("orderSn");
List<String> info = opsForHash.multiGet("orderInfo", listKey);
for (String s : info) {
System.out.println(s);
}
}
}
package com.example.springbootdemo.utils;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestString {
@Autowired
private RedisTemplate stringRedisTemplate;
@Autowired
private RedisTemplate<String, User> objectRedisTemplate;
@Autowired
private RedisTemplate<String, List<User>> listRedisTemplate;
@Autowired
private RedisTemplate<String, List<Map<String,Object>>> mapRedisTemplate;
@Test
public void test1(){
//JsonObjectMapper jsonMapper = JsonObjectMapper.getInstance();
//trSync = jsonMapper.fromJson(jsonStr, TrSync.class);
//操作String类型的数据
ValueOperations<String, String> valueStr = stringRedisTemplate.opsForValue();
valueStr.set("goodsProdu","长安");
//存储一条数据
valueStr.set("goodsProdu","长安");
//获取一条数据并输出
String goodsName = valueStr.get("goodsProdu");
System.out.println(goodsName);
//存储多条数据
Map<String,String> map = new HashMap<>();
map.put("goodsName","福特汽车");
map.put("goodsPrice","88888");
map.put("goodsId","88");
valueStr.multiSet(map);
//获取多条数据
System.out.println("========================================");
List<String> list = new ArrayList<>();
list.add("goodsName");
list.add("goodsPrice");
list.add("goodsId");
list.add("goodsProdu");
List<String> listKeys = valueStr.multiGet(list);
for (String key : listKeys) {
System.out.println(key);
}
String goodsNames = valueStr.get("goodsProdu");
if(valueStr.get("goodsProdu").equals("长安test")){
valueStr.set("goodsProdu","长安test");
}
System.out.println(goodsName);
}
@Test
public void test2() throws Exception {
// 保存字符串
stringRedisTemplate.opsForValue().set("url", "www.lrshuai.top");
Assert.assertEquals("www.lrshuai.top", stringRedisTemplate.opsForValue().get("url"));
// 保存对象
User user = new User("C++", 40);
objectRedisTemplate.opsForValue().set(user.getUsername(), user);
user = new User("Java", 30);
objectRedisTemplate.opsForValue().set(user.getUsername(), user);
user = new User("Python", 20);
objectRedisTemplate.opsForValue().set(user.getUsername(), user);
Assert.assertEquals(20, objectRedisTemplate.opsForValue().get("Python").getAge());
Assert.assertEquals(30, objectRedisTemplate.opsForValue().get("Java").getAge());
Assert.assertEquals(40, objectRedisTemplate.opsForValue().get("C++").getAge());
}
@Test
public void test3() throws Exception{
List<User> us = new ArrayList<>();
User u1 = new User("rs1", 21);
User u2 = new User("rs2", 22);
User u3 = new User("rs3", 23);
us.add(u1);
us.add(u2);
us.add(u3);
listRedisTemplate.opsForValue().set("key_ul", us);
System.out.println("放入缓存》。。。。。。。。。。。。。。。。。。。");
System.out.println("=============================");
List<User> redisList = listRedisTemplate.opsForValue().get("key_ul");
System.out.println("redisList="+redisList);
}
@Test
public void test4() throws Exception{
// List<Map<String,Object>> ms = new ArrayList<>();
// Map<String,Object> map = new HashMap<>();
// map.put(“name”, “rs”);
// map.put(“age”, 20);
//
// Map<String,Object> map1 = new HashMap<>();
// map1.put(“name”, “rs1”);
// map1.put(“age”, 21);
//
// Map<String,Object> map2 = new HashMap<>();
// map2.put(“name”, “rs2”);
// map2.put(“age”, 22);
//
// ms.add(map);
// ms.add(map1);
// ms.add(map2);
// mapRedisTemplate.opsForValue().set(“key_ml”, ms);
// System.out.println(“放入缓存》。。。。。。。。。。。。。。。。。。。”);
System.out.println("=============================");
List<Map<String,Object>> mls = mapRedisTemplate.opsForValue().get(“key_ml”);
for (Map<String,Object> map3:mls) {
System.out.println(“value******”+map3.get(“name”).toString());
System.out.println(“value&&&&&&”+map3.get(“age”).toString());
}
}
}
xml文件
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
<groupId>top.lrshuai</groupId>
<artifactId>springboot-redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-redis</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Test.class
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRedisApplicationTests {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private RedisTemplate<String, User> redisTemplate;
@Autowired
private RedisTemplate<String, List<User>> rt;
@Autowired
private RedisTemplate<String, List<Map<String,Object>>> rm;
@Test
public void test() throws Exception {
// 保存字符串
stringRedisTemplate.opsForValue().set("url", "www.lrshuai.top");
Assert.assertEquals("www.lrshuai.top", stringRedisTemplate.opsForValue().get("url"));
// 保存对象
User user = new User("C++", 40);
redisTemplate.opsForValue().set(user.getUsername(), user);
user = new User("Java", 30);
redisTemplate.opsForValue().set(user.getUsername(), user);
user = new User("Python", 20);
redisTemplate.opsForValue().set(user.getUsername(), user);
Assert.assertEquals(20, redisTemplate.opsForValue().get("Python").getAge());
Assert.assertEquals(30, redisTemplate.opsForValue().get("Java").getAge());
Assert.assertEquals(40, redisTemplate.opsForValue().get("C++").getAge());
}
@Test
public void test1() throws Exception{
List<User> us = new ArrayList<>();
User u1 = new User("rs1", 21);
User u2 = new User("rs2", 22);
User u3 = new User("rs3", 23);
us.add(u1);
us.add(u2);
us.add(u3);
rt.opsForValue().set("key_ul", us);
System.out.println("放入缓存》。。。。。。。。。。。。。。。。。。。");
System.out.println("=============================");
List<User> redisList = rt.opsForValue().get("key_ul");
System.out.println("redisList="+redisList);
}
@Test
public void test2() throws Exception{
List<Map<String,Object>> ms = new ArrayList<>();
Map<String,Object> map = new HashMap<>();
map.put("name", "rs");
map.put("age", 20);
Map<String,Object> map1 = new HashMap<>();
map1.put("name", "rs1");
map1.put("age", 21);
Map<String,Object> map2 = new HashMap<>();
map2.put("name", "rs2");
map2.put("age", 22);
ms.add(map);
ms.add(map1);
ms.add(map2);
rm.opsForValue().set("key_ml", ms);
System.out.println("放入缓存》。。。。。。。。。。。。。。。。。。。");
System.out.println("=============================");
List<Map<String,Object>> mls = rm.opsForValue().get("key_ml");
System.out.println("mls="+mls);
}
}
application.properties
#server.port=80
redis db number default number is 0
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.timeout=0
config
RedisObjectSerializer.java
public class RedisObjectSerializer implements RedisSerializer {
private Converter<Object, byte[]> serializer = new SerializingConverter();
private Converter<byte[], Object> deserializer = new DeserializingConverter();
static final byte[] EMPTY_ARRAY = new byte[0];
public Object deserialize(byte[] bytes) {
if (isEmpty(bytes)) {
return null;
}
try {
return deserializer.convert(bytes);
} catch (Exception ex) {
throw new SerializationException("Cannot deserialize", ex);
}
}
public byte[] serialize(Object object) {
if (object == null) {
return EMPTY_ARRAY;
}
try {
return serializer.convert(object);
} catch (Exception ex) {
return EMPTY_ARRAY;
}
}
private boolean isEmpty(byte[] data) {
return (data == null || data.length == 0);
}
}
@Configuration
public class RedisConfig {
@Value("${spring.redis.database}")
private int database;
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.pool.max-idle}")
private int maxidle;
@Value("${spring.redis.pool.min-idle}")
private int minidle;
@Value("${spring.redis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.pool.max-wait}")
private long maxWait;
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisPoolConfig config = new JedisPoolConfig();
// 最大空闲连接数, 默认8个
config.setMaxIdle(maxidle);
// 最小空闲连接数, 默认0
config.setMinIdle(minidle);
// 最大连接数, 默认8个
config.setMaxTotal(maxActive);
// 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1
config.setMaxWaitMillis(maxWait);
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setDatabase(database);
factory.setHostName(host);
factory.setPort(port);
factory.setTimeout(timeout);
factory.setPoolConfig(config);
return factory;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Bean
public RedisTemplate<String, ?> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, ?> template = new RedisTemplate();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new RedisObjectSerializer());
return template;
}
}
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String username;
private int age;
public User() {
super();
}
public User(String username, int age) {
super();
this.username = username;
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [username=" + username + ", age=" + age + "]";
}
}
启动类
@SpringBootApplication
public class SpringbootRedisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootRedisApplication.class, args);
}
}
xml文件
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
<groupId>top.lrshuai</groupId>
<artifactId>springboot-redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-redis</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Test.class
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRedisApplicationTests {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private RedisTemplate<String, User> redisTemplate;
@Autowired
private RedisTemplate<String, List<User>> rt;
@Autowired
private RedisTemplate<String, List<Map<String,Object>>> rm;
@Test
public void test() throws Exception {
// 保存字符串
stringRedisTemplate.opsForValue().set("url", "www.lrshuai.top");
Assert.assertEquals("www.lrshuai.top", stringRedisTemplate.opsForValue().get("url"));
// 保存对象
User user = new User("C++", 40);
redisTemplate.opsForValue().set(user.getUsername(), user);
user = new User("Java", 30);
redisTemplate.opsForValue().set(user.getUsername(), user);
user = new User("Python", 20);
redisTemplate.opsForValue().set(user.getUsername(), user);
Assert.assertEquals(20, redisTemplate.opsForValue().get("Python").getAge());
Assert.assertEquals(30, redisTemplate.opsForValue().get("Java").getAge());
Assert.assertEquals(40, redisTemplate.opsForValue().get("C++").getAge());
}
@Test
public void test1() throws Exception{
List<User> us = new ArrayList<>();
User u1 = new User("rs1", 21);
User u2 = new User("rs2", 22);
User u3 = new User("rs3", 23);
us.add(u1);
us.add(u2);
us.add(u3);
rt.opsForValue().set("key_ul", us);
System.out.println("放入缓存》。。。。。。。。。。。。。。。。。。。");
System.out.println("=============================");
List<User> redisList = rt.opsForValue().get("key_ul");
System.out.println("redisList="+redisList);
}
@Test
public void test2() throws Exception{
List<Map<String,Object>> ms = new ArrayList<>();
Map<String,Object> map = new HashMap<>();
map.put("name", "rs");
map.put("age", 20);
Map<String,Object> map1 = new HashMap<>();
map1.put("name", "rs1");
map1.put("age", 21);
Map<String,Object> map2 = new HashMap<>();
map2.put("name", "rs2");
map2.put("age", 22);
ms.add(map);
ms.add(map1);
ms.add(map2);
rm.opsForValue().set("key_ml", ms);
System.out.println("放入缓存》。。。。。。。。。。。。。。。。。。。");
System.out.println("=============================");
List<Map<String,Object>> mls = rm.opsForValue().get("key_ml");
System.out.println("mls="+mls);
}
}
application.properties
#server.port=80
redis db number default number is 0
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.timeout=0
config
RedisObjectSerializer.java
public class RedisObjectSerializer implements RedisSerializer {
private Converter<Object, byte[]> serializer = new SerializingConverter();
private Converter<byte[], Object> deserializer = new DeserializingConverter();
static final byte[] EMPTY_ARRAY = new byte[0];
public Object deserialize(byte[] bytes) {
if (isEmpty(bytes)) {
return null;
}
try {
return deserializer.convert(bytes);
} catch (Exception ex) {
throw new SerializationException("Cannot deserialize", ex);
}
}
public byte[] serialize(Object object) {
if (object == null) {
return EMPTY_ARRAY;
}
try {
return serializer.convert(object);
} catch (Exception ex) {
return EMPTY_ARRAY;
}
}
private boolean isEmpty(byte[] data) {
return (data == null || data.length == 0);
}
}
@Configuration
public class RedisConfig {
@Value("${spring.redis.database}")
private int database;
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.pool.max-idle}")
private int maxidle;
@Value("${spring.redis.pool.min-idle}")
private int minidle;
@Value("${spring.redis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.pool.max-wait}")
private long maxWait;
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisPoolConfig config = new JedisPoolConfig();
// 最大空闲连接数, 默认8个
config.setMaxIdle(maxidle);
// 最小空闲连接数, 默认0
config.setMinIdle(minidle);
// 最大连接数, 默认8个
config.setMaxTotal(maxActive);
// 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1
config.setMaxWaitMillis(maxWait);
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setDatabase(database);
factory.setHostName(host);
factory.setPort(port);
factory.setTimeout(timeout);
factory.setPoolConfig(config);
return factory;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Bean
public RedisTemplate<String, ?> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, ?> template = new RedisTemplate();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new RedisObjectSerializer());
return template;
}
}
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String username;
private int age;
public User() {
super();
}
public User(String username, int age) {
super();
this.username = username;
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [username=" + username + ", age=" + age + "]";
}
}
启动类
@SpringBootApplication
public class SpringbootRedisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootRedisApplication.class, args);
}
}
或者
pom.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.7.RELEASE
top.lrshuai
cache
0.0.1-SNAPSHOT
cache
Demo project for Spring Boot
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- 添加mybatis 依赖 -->
<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>
</dependency>
<!-- druid 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.19</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.26</version>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
application.yml
spring:
profiles:
active: dev
application-dev.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Hongkong&autoReconnect=true&allowPublicKeyRetrieval=true
username: rstyro
password: rstyro
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
# druid config
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
filters: ‘stat,wall,log4j’
initialSize: 5
maxActive: 20
maxPoolPreparedStatementPerConnectionSize: 20
maxWait: 60000
minEvictableIdleTimeMillis: 300000
minIdle: 5
poolPreparedStatements: true
testOnBorrow: false
testOnReturn: false
testWhileIdle: true
timeBetweenEvictionRunsMillis: 60000
validationQuery: SELECT 1 FROM DUAL
redis:
password:
database: 0
port: 6379
host: 127.0.0.1
lettuce:
pool:
max-idle: 8
min-idle: 0
max-active: 8
max-wait: -1ms
timeout: 10000ms
cache:
redis:
cache-null-values: false
use-key-prefix: true
time-to-live: 20s
mybatis:
mapper-locations:
- classpath:mapper//.xml
- classpath*:mapper///*.xml
驼峰命名
configuration:
map-underscore-to-camel-case: true
demo.sql
/*
Navicat MySQL Data Transfer
Source Server : 本地
Source Server Type : MySQL
Source Server Version : 80016
Source Host : localhost:3306
Source Schema : demo
Target Server Type : MySQL
Target Server Version : 80016
File Encoding : 65001
Date: 08/08/2019 22:58:42
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
– Table structure for act_acticle
DROP TABLE IF EXISTS act_acticle
;
CREATE TABLE act_acticle
(
id
bigint(20) NOT NULL AUTO_INCREMENT,
title
varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT ‘标题’,
content
text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT ‘内容’,
tag_id
bigint(20) NULL DEFAULT 1,
create_by
bigint(20) NULL DEFAULT NULL COMMENT ‘创建人ID’,
create_time
datetime(0) NULL DEFAULT NULL COMMENT ‘创建时间’,
modify_by
bigint(20) NULL DEFAULT NULL,
modify_time
datetime(0) NULL DEFAULT NULL,
PRIMARY KEY (id
) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
– Records of act_acticle
INSERT INTO act_acticle
VALUES (1, ‘SpringBoot缓存Cacheable整合’, ‘SpringBoot缓存Cacheable整合’, 0, 1, ‘2019-08-08 17:03:59’, 1, ‘2019-08-08 17:04:02’);
INSERT INTO act_acticle
VALUES (3, ‘测试’, ‘阿道夫士大夫ssff’, 1, 1, ‘2019-08-08 17:22:38’, 1, ‘2019-08-08 17:22:38’);
INSERT INTO act_acticle
VALUES (4, ‘abc’, ‘阿道夫士大夫ssff’, 2, 1, ‘2019-08-08 17:47:13’, 1, ‘2019-08-08 17:47:13’);
SET FOREIGN_KEY_CHECKS = 1;
logback-spring.xml
<logger name="top.lrshuai.cache" level="DEBUG" />
启动类
package top.lrshuai.cache;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan(basePackages = {“top.lrshuai.cache.*.mapper”})
@SpringBootApplication
public class CacheApplication {
public static void main(String[] args) {
SpringApplication.run(CacheApplication.class, args);
}
}
config类
package top.lrshuai.cache.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.sql.SQLException;
@Configuration
public class DruidConfig {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Value("${spring.datasource.url}")
private String dbUrl;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.initialSize}")
private int initialSize;
@Value("${spring.datasource.minIdle}")
private int minIdle;
@Value("${spring.datasource.maxActive}")
private int maxActive;
@Value("${spring.datasource.maxWait}")
private long maxWait;
@Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
private int timeBetweenEvictionRunsMillis;
@Value("${spring.datasource.minEvictableIdleTimeMillis}")
private int minEvictableIdleTimeMillis;
@Value("${spring.datasource.validationQuery}")
private String validationQuery;
@Value("${spring.datasource.testWhileIdle}")
private boolean testWhileIdle;
@Value("${spring.datasource.testOnBorrow}")
private boolean testOnBorrow;
@Value("${spring.datasource.testOnReturn}")
private boolean testOnReturn;
@Value("${spring.datasource.poolPreparedStatements}")
private boolean poolPreparedStatements;
@Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
private int maxPoolPreparedStatementPerConnectionSize;
@Value("${spring.datasource.filters}")
private String filters;
@Value("{spring.datasource.connectionProperties}")
private String connectionProperties;
@Bean //声明其为Bean实例
@Primary //在同样的DataSource中,首先使用被标注的DataSource
public DataSource dataSource(){
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(this.dbUrl);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
//configuration
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setTestOnReturn(testOnReturn);
datasource.setPoolPreparedStatements(poolPreparedStatements);
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
try {
datasource.setFilters(filters);
} catch (SQLException e) {
logger.error("druid configuration initialization filter", e);
}
datasource.setConnectionProperties(connectionProperties);
return datasource;
}
@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean reg = new ServletRegistrationBean();
reg.setServlet(new StatViewServlet());
reg.addUrlMappings("/druid/*");
reg.addInitParameter("allow", "127.0.0.1,192.168.1.83"); //白名单
reg.addInitParameter("deny",""); //黑名单
reg.addInitParameter("loginUsername", "admin");//查看监控的用户名
reg.addInitParameter("loginPassword", "nimda");//密码
return reg;
}
@Bean public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
}
package top.lrshuai.cache.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import javax.annotation.Resource;
import java.time.Duration;
/**
*
- @author rstyro
- @time 2018-07-31
*/
@Configuration
@EnableCaching // 开启缓存支持
public class RedisConfig extends CachingConfigurerSupport {
@Resource
private LettuceConnectionFactory lettuceConnectionFactory;
/**
* 配置CacheManager
* @return
*/
@Bean
public CacheManager cacheManager() {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
CacheAutoConfiguration
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题)
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
// .entryTtl(Duration.ZERO)
.entryTtl(Duration.ofSeconds(20)) //设置缓存失效时间
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(lettuceConnectionFactory)
.cacheDefaults(config)
.build();
return cacheManager;
}
/**
* RedisTemplate配置
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
// 设置序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置redisTemplate
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);// key序列化
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
controller
package top.lrshuai.cache.act.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.lrshuai.cache.act.entity.Acticle;
import top.lrshuai.cache.act.service.IActicleService;
@RestController
@RequestMapping("/act")
public class ActicleController {
@Autowired
private IActicleService acticleService;
@GetMapping("/list")
public Object list() throws Exception{
return acticleService.list();
}
@GetMapping("/add")
public Object add(Acticle acticle) throws Exception{
return acticleService.save(acticle);
}
@GetMapping("/del/{id}")
public Object del(@PathVariable("id") Long id) throws Exception{
return acticleService.del(id);
}
@GetMapping("/delall")
public Object delAll() throws Exception{
return acticleService.delAll();
}
@GetMapping("/get/id/{id}")
public Object getActicleById(@PathVariable("id") Long id) throws Exception{
return acticleService.queryById(id);
}
@GetMapping("/get/title/{title}")
public Object getActicleByTitle(@PathVariable("title") String title) throws Exception{
return acticleService.queryByTitle(title);
}
@GetMapping("/get/tag/{tagId}")
public Object getActicleByTag(@PathVariable("tagId") Long tagId) throws Exception{
return acticleService.queryByTag(tagId);
}
@GetMapping("/update/{id}")
public Object update(Acticle acticle) throws Exception{
return acticleService.update(acticle);
}
}
service及serviceimpl
package top.lrshuai.cache.act.service;
import top.lrshuai.cache.act.entity.Acticle;
import java.util.List;
public interface IActicleService {
public List list() throws Exception;
public Acticle save(Acticle acticle) throws Exception;
public int del(Long id) throws Exception;
public int delAll() throws Exception;
public Acticle update(Acticle acticle) throws Exception;
public Acticle queryById(Long id) throws Exception;
public Acticle queryByTitle(String title) throws Exception;
public Acticle queryByTag(Long tagId) throws Exception;
}
package top.lrshuai.cache.act.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;
import top.lrshuai.cache.act.entity.Acticle;
import top.lrshuai.cache.act.mapper.ActicleMapper;
import top.lrshuai.cache.act.service.IActicleService;
import java.time.LocalDateTime;
import java.util.List;
@CacheConfig(cacheNames = “act”)
@Service
public class ActicleService implements IActicleService {
@Autowired
private ActicleMapper acticleMapper;
/**
* @Cacheable
* 1、先查缓存,
* 2、若没有缓存,就执行方法
* 3、若有缓存。则返回,不执行方法
*
* 所以@Cacheable 不能使用result
*
* @return
* @throws Exception
*/
@Cacheable(key = "#root.methodName")
public List<Acticle> list() throws Exception {
return acticleMapper.getActicleList();
}
/**
* @CachePut 更新并刷新缓存
* 1、先调用目标方法
* 2、把结果缓存
* @param acticle
* @return
* @throws Exception
*/
@CachePut(key = "#result.id" ,unless = "#result.id == null" )
public Acticle save(Acticle acticle) throws Exception {
acticle.setCreateBy(1l);
acticle.setCreateTime(LocalDateTime.now());
acticle.setModifyBy(1l);
acticle.setModifyTime(LocalDateTime.now());
acticleMapper.save(acticle);
System.out.println("acticle="+acticle);
return acticle;
}
/**
* 删除指定key 的缓存
* beforeInvocation=false 缓存的清除是否在方法之前执行
* 默认是在方法之后执行
* @param id
* @return
* @throws Exception
*/
@CacheEvict(key = "#id",beforeInvocation = true)
public int del(Long id) throws Exception {
int isDel = 0;
isDel = acticleMapper.del(id);
return isDel;
}
/**
* 删除所有缓存
* @return
* @throws Exception
*/
@CacheEvict(allEntries = true)
public int delAll() throws Exception {
return 1;
}
@CachePut(key = "#result.id" ,unless = "#result.id == null" )
public Acticle update(Acticle acticle) throws Exception {
acticle.setModifyBy(1l);
acticle.setModifyTime(LocalDateTime.now());
return acticleMapper.update(acticle);
}
@Cacheable(key = "#id",condition = "#id > 0")
public Acticle queryById(Long id) throws Exception {
return acticleMapper.queryById(id);
}
/**
* @Caching复杂组合缓存注解
*
* @param title
* @return
* @throws Exception
*/
@Caching(cacheable = { @Cacheable(key = "#title")},
put = {@CachePut(key = "#result.id"),
// @CachePut(key = “T(String).valueOf(#page).concat(’-’).concat(#pageSize)”)
@CachePut(key = “T(String).valueOf(‘tag’).concat(’-’).concat(#result.tagId)”)
})
public Acticle queryByTitle(String title) throws Exception {
return acticleMapper.queryByTitle(title);
}
@Cacheable(key = "T(String).valueOf('tag').concat('-').concat(#tagId)")
public Acticle queryByTag(Long tagId) throws Exception {
return null;
}
}
mapping
package top.lrshuai.cache.act.mapper;
import org.springframework.stereotype.Component;
import top.lrshuai.cache.act.entity.Acticle;
import java.util.List;
@Component
public interface ActicleMapper {
public int save(Acticle acticle) throws Exception;
public int del(Long id) throws Exception;
public Acticle update(Acticle acticle) throws Exception;
public Acticle queryById(Long id) throws Exception;
public Acticle queryByTitle(String title) throws Exception;
public List getActicleList();
}
实体类
package top.lrshuai.cache.act.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@Data
public class Acticle {
private Long id;
private String title;
private String content;
private Long tagId;
private Long createBy;
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
private Long modifyBy;
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime modifyTime;
}
resource/mapping/act
<?xml version="1.0" encoding="UTF-8"?><insert id="save" parameterType="top.lrshuai.cache.act.entity.Acticle" keyProperty="id" useGeneratedKeys="true">
insert into act_acticle(
title,
content,
create_time,
create_by,
modify_time,
modify_by
)values(
#{title},
#{content},
#{createTime},
#{createBy},
#{modifyTime},
#{modifyBy}
)
</insert>
<update id="update">
update act_acticle
set
title=#{title},
content=#{content},
modify_by=#{modifyBy},
modify_time=#{modifyTime}
where
id=#{id}
</update>
<delete id="del">
delete from act_acticle where id=#{id}
</delete>
<select id="queryById" resultType="top.lrshuai.cache.act.entity.Acticle">
select * from act_acticle where id=#{id}
</select>
<select id="queryByTitle" resultType="top.lrshuai.cache.act.entity.Acticle">
select * from act_acticle where title like concat('%',#{title},'%')
</select>
<select id="getActicleList" resultType="top.lrshuai.cache.act.entity.Acticle">
select * from act_acticle
</select>