Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作高性能的key-value数据库、缓存和消息中间件,掌握它是程序员的必备技能,下面是一个springboot访问redis的demo。
新建一个springboot项目,这里取名spring-boot-demo
项目结构目录如下
pom.xml文件内容
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <modelVersion>4.0.0</modelVersion>
6
7 <groupId>com.carry</groupId>
8 <artifactId>spring-boot-demo</artifactId>
9 <version>0.0.1-SNAPSHOT</version>
10 <packaging>jar</packaging>
11
12 <name>spring-boot-demo</name>
13 <description>Demo project for Spring Boot</description>
14
15 <parent>
16 <groupId>org.springframework.boot</groupId>
17 <artifactId>spring-boot-starter-parent</artifactId>
18 <version>2.0.2.RELEASE</version>
19 <relativePath /> <!-- lookup parent from repository -->
20 </parent>
21
22 <properties>
23 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
24 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
25 <java.version>1.8</java.version>
26 <mybatis.version>1.3.2</mybatis.version>
27 </properties>
28
29 <dependencies>
30 <dependency>
31 <groupId>org.springframework.boot</groupId>
32 <artifactId>spring-boot-starter-data-redis</artifactId>
33 </dependency>
34 <dependency>
35 <groupId>org.springframework.boot</groupId>
36 <artifactId>spring-boot-starter-web</artifactId>
37 </dependency>
38 <dependency>
39 <groupId>org.mybatis.spring.boot</groupId>
40 <artifactId>mybatis-spring-boot-starter</artifactId>
41 <version>${mybatis.version}</version>
42 </dependency>
43 <dependency>
44 <groupId>org.apache.commons</groupId>
45 <artifactId>commons-pool2</artifactId>
46 </dependency>
47 <dependency>
48 <groupId>org.springframework.boot</groupId>
49 <artifactId>spring-boot-devtools</artifactId>
50 <scope>runtime</scope>
51 </dependency>
52 <dependency>
53 <groupId>mysql</groupId>
54 <artifactId>mysql-connector-java</artifactId>
55 <scope>runtime</scope>
56 </dependency>
57 <dependency>
58 <groupId>org.springframework.boot</groupId>
59 <artifactId>spring-boot-starter-test</artifactId>
60 <scope>test</scope>
61 </dependency>
62 </dependencies>
63
64 <build>
65 <plugins>
66 <plugin>
67 <groupId>org.springframework.boot</groupId>
68 <artifactId>spring-boot-maven-plugin</artifactId>
69 <configuration>
70 <fork>true</fork>
71 </configuration>
72 </plugin>
73 </plugins>
74 </build>
75
76
77 </project>
下面我们来配置redis,因为需要用到mysql数据库,这里使用mybatis访问
application.yml文件内容
1 #mybatis配置
2 mybatis:
3 mapper-locations: classpath:mapper/*Mapper.xml
4 type-aliases-package: com.carry.domain
5 #数据源
6 spring:
7 datasource:
8 url: jdbc:mysql://192.168.68.100:3306/test
9 driver-class-name: com.mysql.jdbc.Driver
10 username: root
11 password: 123456
12 #jackson时间格式化
13 jackson:
14 time-zone: GMT+8
15 date-format: yyyy-MM-dd HH:mm:ss
16 #redis配置
17 redis:
18 cluster:
19 nodes: 192.168.68.100:7000,192.168.68.100:7001,192.168.68.101:7000,192.168.68.101:7001,192.168.68.102:7000,192.168.68.102:7001
20 timeout: 6000ms
21 password: 123456
22 lettuce:
23 pool:
24 max-active: 8
25 max-wait: -1ms
26 max-idle: 8
27 min-idle: 0
28 database: 0
新建文件RedisConfig.java,内容如下
1 package com.carry.config;
2
3 import com.fasterxml.jackson.annotation.JsonAutoDetect;
4 import com.fasterxml.jackson.annotation.PropertyAccessor;
5 import com.fasterxml.jackson.databind.ObjectMapper;
6 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
7 import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
8 import org.springframework.context.annotation.Bean;
9 import org.springframework.context.annotation.Configuration;
10 import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
11 import org.springframework.data.redis.core.RedisTemplate;
12 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
13
14 @Configuration
15 @AutoConfigureAfter(RedisAutoConfiguration.class)
16 public class RedisConfig {
17
18 @Bean
19 public RedisTemplate<String, Object> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) {
20 //redis序列化器
21 Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
22 ObjectMapper om = new ObjectMapper();
23 om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
24 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
25 jackson2JsonRedisSerializer.setObjectMapper(om);
26 RedisTemplate<String, Object> template = new RedisTemplate<>();
27 template.setConnectionFactory(redisConnectionFactory);
28 template.setKeySerializer(jackson2JsonRedisSerializer);
29 template.setValueSerializer(jackson2JsonRedisSerializer);
30 template.setHashKeySerializer(jackson2JsonRedisSerializer);
31 template.setHashValueSerializer(jackson2JsonRedisSerializer);
32 return template;
33 }
34 }
最后在项目启动类SpringBootDemoApplication上加上注解@EnableCaching开启缓存
配置至此结束,下面我们来通过代码来访问redis集群
先写一个访问mysql的mapper,其中只包含一个方法List<User> findAll();
对应SQL语句为select * from user
User实体类跟user表字段一一对应
UserServiceImpl代码内容
1 package com.carry.service.impl;
2
3 import java.util.List;
4
5 import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.cache.annotation.Cacheable;
7 import org.springframework.stereotype.Service;
8
9 import com.carry.domain.User;
10 import com.carry.mapper.UserMapper;
11 import com.carry.service.UserService;
12
13 @Service
14 public class UserServiceImpl implements UserService {
15
16 @Autowired
17 private UserMapper userMapper;
18
19 @Cacheable(value = "findAll", key = "'test'")
20 public List<User> findAll() {
21 System.out.println("如果没打印这句话,说明走了缓存!");
22 return userMapper.findAll();
23 }
24 }
UserController代码内容
1 package com.carry.controller;
2
3 import java.util.List;
4
5 import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.web.bind.annotation.GetMapping;
7 import org.springframework.web.bind.annotation.RestController;
8
9 import com.carry.domain.User;
10 import com.carry.service.UserService;
11
12 @RestController
13 public class UserController {
14
15 @Autowired
16 private UserService userService;
17
18 @GetMapping("/getUsers")
19 public List<User> getUsers(){
20 return userService.findAll();
21 }
22
23 }
最后启动项目在浏览器中访问http://localhost:8080/getUsers
第一次访问控制台输出“如果没打印这句话,说明走了缓存!”
再次访问控制台则没有输出。
我们通过redis-cli连接redis会发现key值是一个很奇怪的值
其实就是我们在@Cacheable注解配的值拼起来的
需要注意的是key的值需要用单引号''引起来不然会报错
最后写了几个test case,读者自己去运行看看控制台会输出什么
1 package com.carry;
2
3 import java.util.Date;
4 import java.util.HashSet;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Set;
8 import java.util.concurrent.ExecutorService;
9 import java.util.concurrent.Executors;
10 import java.util.stream.IntStream;
11
12 import org.junit.Test;
13 import org.junit.runner.RunWith;
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
16 import org.springframework.beans.factory.annotation.Autowired;
17 import org.springframework.boot.test.context.SpringBootTest;
18 import org.springframework.data.redis.core.Cursor;
19 import org.springframework.data.redis.core.DefaultTypedTuple;
20 import org.springframework.data.redis.core.HashOperations;
21 import org.springframework.data.redis.core.ListOperations;
22 import org.springframework.data.redis.core.RedisTemplate;
23 import org.springframework.data.redis.core.ScanOptions;
24 import org.springframework.data.redis.core.SetOperations;
25 import org.springframework.data.redis.core.StringRedisTemplate;
26 import org.springframework.data.redis.core.ValueOperations;
27 import org.springframework.data.redis.core.ZSetOperations;
28 import org.springframework.test.context.junit4.SpringRunner;
29
30 import com.carry.domain.User;
31
32 @RunWith(SpringRunner.class)
33 @SpringBootTest
34 public class SpringBootDemoApplicationTests {
35
36 private static final Logger log = LoggerFactory.getLogger(SpringBootDemoApplicationTests.class);
37
38
39 @Autowired
40 private StringRedisTemplate stringRedisTemplate;
41
42 @Autowired
43 private RedisTemplate<String, Object> redisCacheTemplate;
44
45
46 @Test
47 public void redisTest() {
48 ExecutorService executorService = Executors.newFixedThreadPool(1000);
49 IntStream.range(0, 1000).forEach(i ->
50 executorService.execute(() -> stringRedisTemplate.opsForValue().increment("kk", 1))
51 );
52 }
53
54 @Test
55 public void redisTestString() {
56 stringRedisTemplate.opsForValue().set("carry", "chan");
57 final String v1 = stringRedisTemplate.opsForValue().get("carry");
58 log.info("[字符缓存结果] - [{}]", v1);
59 }
60
61 @Test
62 public void redisTestObject() {
63 //以下只演示整合,具体Redis命令可以参考官方文档,Spring Data Redis 只是改了个名字而已,Redis支持的命令它都支持
64 String key = "carry:user:1";
65 ValueOperations<String, Object> valueOperations = redisCacheTemplate.opsForValue();
66 valueOperations.set(key, new User(1, "carry", new Date(), "longhua"));
67 //对应 String(字符串)
68 final User user = (User) valueOperations.get(key);
69 log.info("[对象缓存结果] - [{}]", user);
70 }
71
72 @Test
73 public void redisTestList() {
74 ListOperations<String, Object> listOperations = redisCacheTemplate.opsForList();
75 listOperations.trim("key1", 1, 0);
76 List<Object> list = listOperations.range("key1", 0, -1);
77 log.info("[对象缓存结果] - {}", list);
78 listOperations.leftPush("key1", 1);
79 listOperations.leftPush("key1", 2);
80 listOperations.rightPush("key1", 3);
81 list = listOperations.range("key1", 0, -1);
82 log.info("[对象缓存结果] - {}", list);
83 }
84
85 @Test
86 public void redisTestHash() {
87 HashOperations<String, Object, Object> hashOperations = redisCacheTemplate.opsForHash();
88 hashOperations.put("hkey", "k1", "v1");
89 hashOperations.put("hkey", "k2", "v2");
90 hashOperations.put("hkey", "k3", "v3");
91 Map<Object, Object> map = hashOperations.entries("hkey");
92 log.info("[对象缓存结果] - [{}]", map);
93 }
94
95 @Test
96 public void redisTestSet() {
97 SetOperations<String, Object> setOperations = redisCacheTemplate.opsForSet();
98 setOperations.add("skey", "v1", "v2", "v3", "v4");
99 Cursor<Object> cursor = setOperations.scan("skey", ScanOptions.NONE);
100 while (cursor.hasNext()) {
101 System.out.println(cursor.next());
102 }
103 log.info("[对象缓存结果] - [{}]", cursor);
104 }
105
106 @Test
107 public void redisTestZSet() {
108 ZSetOperations<String, Object> zSetOperations = redisCacheTemplate.opsForZSet();
109 ZSetOperations.TypedTuple<Object> tuple1 = new DefaultTypedTuple<>("v1", 9.6);
110 ZSetOperations.TypedTuple<Object> tuple2 = new DefaultTypedTuple<>("v2", 9.9);
111 Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<>();
112 tuples.add(tuple1);
113 tuples.add(tuple2);
114 zSetOperations.add("zkey", tuples);
115 Set<Object> set = zSetOperations.range("zkey", 0, -1);
116 log.info("[对象缓存结果] - {}", set);
117 }
118 }
来源:oschina
链接:https://my.oschina.net/u/4274927/blog/3885993