Spring Data Redis 教程2
上篇《Spring Data Redis 教程》 已经提及如何使用spring data 访问redis,但仅仅用了Spring data 提供的template,template在存储POJO很方便,但有时我们需要更灵活。本文一起了解Spring data 的另一个组件Operations,并通过Spring boot从头搭建web示例进行详细说明。
1. Redis
Redis是基于内存数据结构的存储实现,可选持久化的分布式内存键值数据库。可用作数据库、缓存或消息代理。Redis支持不同类型抽象数据类型,如字符串、列表、映射、集合、有序集合(strings, lists, maps, sets, sorted sets), HyperLogLogs, bitmaps, streams, spatial indexes等(这些数据结构功能强大,觉得翻译后就没味了,保留不翻)。
Redis是ANSI C 语言实现,速度非常快,在大多数POSIX系统(如 Linux, *BSD, OS X 等)安装无需其他依赖。Redis 有内置复制、lua脚本、LRU缓存机制、事务以及不同级别的磁盘持久化功能。Redis最适合作为分布式缓存系统,在微服务的大潮下Redis缓存非常有用。
首先,我们需搭建并启动Redis服务器,然后配置连接相关属性如,主机、端口、密码等。假如我们已经在本地安装了Redis服务器,读者可以参考官方文档。
2. Spring Data Redis
2.1. 依赖
使用Spring Boot搭建示例,需要引入相关依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
Jedis是非常小且高效Java客户端,spring-boot-starter-data-redis是Spring data对Redis操作抽象封装。spring-boot-starter-web是实现web应用测试CRUD操作。
2.2. Spring Boot Redis 配置
首先需要定义两个Spring bean:JedisConnectionFactory 和 RedisTemplate:
@Configuration
public class BeanConfig {
@Bean
JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration("localhost", 6379);
redisStandaloneConfiguration.setPassword(RedisPassword.of("password"));
return new JedisConnectionFactory(redisStandaloneConfiguration);
}
@Bean
public RedisTemplate redisTemplate() {
RedisTemplate template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
}
JedisConnectionFactory 设置主机方法已经不建议使用,因此需要使用RedisStandaloneConfiguration配置JedisConnectionFactory。我们也可以使用属性文件进行配置:
spring.redis.host=127.0.0.1
spring.redis.password=password
spring.redis.port=6379
我们也可以配置连接池相关属性。
2.3. CRUD操作
首先定义Respository类,实现所有put、get、delete等操作,这里需要注入hashOperations和redisTemplate:
@Repository
public class RedisUserRepository {
private HashOperations hashOperations;
private RedisTemplate redisTemplate;
public RedisUserRepository(RedisTemplate redisTemplate){
this.redisTemplate = redisTemplate;
this.hashOperations = this.redisTemplate.opsForHash();
}
...
}
Redis PUT操作
Redis的插入操作,如put, putIfAbsent, putAll 需要三个参数,下面是put的语法:
void put(H key, HK hashKey, HV value);
key可作为Redis缓存的一部分,用于缓存不同类型的数据。下面示例使key为USER保存用户信息。
hashKey用户保存用户属性值,不能重复。下面是java代码实现使用唯一的用户ID缓存用户对象:
public void save(User user) {
hashOperations.put("USER", user.getId(), user);
}
Redis GET操作
get操作取给定key的值,返回Java对象。因此需要显示转换对象为User,但需要User类实现Serializable接口:
public User findById(String id){
return (User) hashOperations.get("USER", id);
}
Redis DELETE操作
删除操作根据key删除缓存对象中的属性值。它仅删除User缓存中内容,如果需要删除缓存USER,则需要RedisTemplate实现:
public void delete(String id){
hashOperations.delete("USER", id);
}
Redis VALUES 操作
Redis VALUES 操作返回缓存中所有值。下面实现返回对象集合,也有其他方法返回键值对:
public List findAll(){
return hashOperations.values("USER");
}
Redis MultiGet操作
multiGet()允许一次提供多个key获取缓存值。但需要注意的是其返回值是list中存储list,因此需要解析返回值为有意义的集合类型。我们需要根据传入key的顺序进行解析:
public Map<String, List<User>> multiGetUsers(List<String> userIds){
Map<String, List<User>> userMap = new HashMap<>();
List<Object> users = hashOperations.multiGet("USER", userIds);
for (int i = 0; i < userIds.size(); i++) {
userMap.put(userIds.get(i), (List<User>) users.get(i));
}
return userMap;
}
完整CRUD代码如下:
@Repository
public class RedisUserRepository {
private HashOperations hashOperations;
private RedisTemplate redisTemplate;
public RedisUserRepository(RedisTemplate redisTemplate){
this.redisTemplate = redisTemplate;
this.hashOperations = this.redisTemplate.opsForHash();
}
public void save(User user){
hashOperations.put("USER", user.getId(), user);
}
public List findAll(){
return hashOperations.values("USER");
}
public User findById(String id){
return (User) hashOperations.get("USER", id);
}
public void update(User user){
save(user);
}
public void delete(String id){
hashOperations.delete("USER", id);
}
}
2.4. Controller 实现
下面定义Controller 实现用于测试CRUD:
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private RedisUserRepository userRepository;
@PostMapping
public User save(@RequestBody User user){
userRepository.save(user);
return user;
}
@GetMapping
public List list(){
return userRepository.findAll();
}
@GetMapping("/{id}")
public User getUser(@PathVariable String id){
return userRepository.findById(id);
}
@PutMapping
public User update(@RequestBody User user){
userRepository.update(user);
return user;
}
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable String id){
userRepository.delete(id);
return id;
}
}
2.5. 通过web接口进行测试
PUT测试
Method : POST
URL : http://localhost:8080/users
Body :
{
"name":"tom",
"age": 23,
"id":"1234"
}s
GET测试
Method : GET
URL : http://localhost:8080/users
UPDATE测试
HTTP Method : PUT
URL : http://localhost:8080/users
Body :
{
"name":"tom",
"age": 24,
"id":"1234"
}
DELETE测试
HTTP Method : DELETE
URL : http://localhost:8080/users/1234
上面实现Redis自身作为存储User数据库,这对于不使用其他数据库存储数据时很有用。实际应用中一般需把数据存储在RDBMS中,使用Redis作为缓存数据库,那么实现则需要使用 spring-boot-starter-data-jpa 模块进行关系型数据库操作。对缓存操作也可以使用Spring提供的注解@Cacheable进行实现,这里不进行展开。
3. 总结
本文我们讨论Spring data redis提供另一个组件Operations,并通过Spring Boot示例展示CRUD功能。
本文参考链接:https://blog.csdn.net/neweastsun/article/details/103743216