Spring Boot 整合 Redis 注解实现简单 CRUD
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
一、项目搭建
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
1.1 添加依赖
xml
<!-- pom.xml -->
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
1.2 配置文件
yaml
# application.yml
spring:
redis:
host: localhost
port: 6379
database: 0
server:
port: 8080
二、实体类
kotlin
package com.example.entity;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;
import org.springframework.data.redis.core.index.Indexed;
import java.io.Serializable;
/**
* @RedisHash: 声明实体类,value指定Redis中的key前缀
* 存储格式: user:{id}
*/
@Data
@RedisHash("user")
public class User implements Serializable {
@Id
private Long id; // 主键
@Indexed
private String username; // 创建索引,可以按username查询
private String email;
private Integer age;
}
三、Repository 接口
java
package com.example.repository;
import com.example.entity.User;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
/**
* CrudRepository 提供基本的CRUD方法
* 可以根据方法名自动生成查询
*/
@Repository
public interface UserRepository extends CrudRepository<User, Long> {
// 根据用户名查询(精确匹配)
List<User> findByUsername(String username);
// 根据邮箱查询
Optional<User> findByEmail(String email);
// 根据年龄范围查询
List<User> findByAgeBetween(Integer minAge, Integer maxAge);
// 删除指定用户名的用户
Long deleteByUsername(String username);
}
四、Service 层
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
kotlin
package com.example.service;
import com.example.entity.User;
import com.example.repository.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Slf4j
@Service
@CacheConfig(cacheNames = "user") // 类级别缓存配置
public class UserService {
@Autowired
private UserRepository userRepository;
/**
* @Cacheable: 查询缓存
* 1. 先查缓存,有则直接返回
* 2. 无则执行方法,将结果存入缓存
*/
@Cacheable(key = "#id")
public User findById(Long id) {
log.info("查询数据库,用户ID: {}", id);
return userRepository.findById(id).orElse(null);
}
/**
* 查询所有用户
*/
public List<User> findAll() {
return (List<User>) userRepository.findAll();
}
/**
* 根据用户名查询
*/
public List<User> findByUsername(String username) {
return userRepository.findByUsername(username);
}
/**
* @CachePut: 更新缓存
* 每次都会执行方法,并将结果更新到缓存
*/
@CachePut(key = "#user.id")
public User save(User user) {
log.info("保存用户: {}", user.getUsername());
return userRepository.save(user);
}
/**
* @CacheEvict: 删除缓存
* 方法执行后删除指定key的缓存
*/
@CacheEvict(key = "#id")
public void deleteById(Long id) {
log.info("删除用户,ID: {}", id);
userRepository.deleteById(id);
}
/**
* 更新用户
*/
@Caching(
put = @CachePut(key = "#user.id"),
evict = @CacheEvict(key = "'list'") // 清除列表缓存
)
public User update(User user) {
log.info("更新用户: {}", user.getId());
return userRepository.save(user);
}
/**
* 缓存用户列表
*/
@Cacheable(key = "'list'")
public List<User> findAllWithCache() {
log.info("查询所有用户(带缓存)");
return (List<User>) userRepository.findAll();
}
}
五、Controller 层
less
package com.example.controller;
import com.example.entity.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
// 新增用户
@PostMapping
public User createUser(@RequestBody User user) {
return userService.save(user);
}
// 根据ID查询用户
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.findById(id);
}
// 查询所有用户
@GetMapping
public List<User> getAllUsers() {
return userService.findAllWithCache();
}
// 根据用户名查询
@GetMapping("/search")
public List<User> getUserByUsername(@RequestParam String username) {
return userService.findByUsername(username);
}
// 更新用户
@PutMapping("/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id);
return userService.update(user);
}
// 删除用户
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable Long id) {
userService.deleteById(id);
return "删除成功";
}
}
六、主启动类
typescript
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching // 开启缓存支持
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
七、测试示例
7.1 使用 Postman 测试
1. 新增用户
bash
POST http://localhost:8080/api/users
Content-Type: application/json
{
"username": "张三",
"email": "zhangsan@example.com",
"age": 25
}
2. 查询用户
bash
GET http://localhost:8080/api/users/1
3. 查询所有用户
bash
GET http://localhost:8080/api/users
4. 更新用户
bash
PUT http://localhost:8080/api/users/1
Content-Type: application/json
{
"username": "张三",
"email": "zhangsan_new@example.com",
"age": 26
}
5. 删除用户
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
bash
DELETE http://localhost:8080/api/users/1
八、注解总结
| 注解 | 作用 | 示例 |
|---|---|---|
@RedisHash |
实体类映射到Redis Hash | @RedisHash("user") |
@Id |
标记主键字段 | @Id private Long id; |
@Indexed |
创建二级索引,支持字段查询 | @Indexed private String username; |
@EnableCaching |
启用缓存(主类上) | @EnableCaching |
@Cacheable |
方法结果缓存 | @Cacheable(key = "#id") |
@CachePut |
更新缓存 | @CachePut(key = "#user.id") |
@CacheEvict |
删除缓存 | @CacheEvict(key = "#id") |
@Caching |
组合多个缓存操作 | 见上面Service中的update方法 |
九、运行效果
- 第一次查询用户(1) :控制台打印日志"查询数据库"
- 第二次查询用户(1) :直接从缓存返回,不打印日志
- 更新用户(1) :更新数据库,并更新缓存
- 删除用户(1) :删除数据库记录,并清除缓存
十、注意事项
零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目
- 实体类必须实现
Serializable接口 - 缓存注解的方法必须是
public的 - 同一个类内部调用缓存注解的方法不会生效
- Redis 需要提前安装并启动
这个示例包含了最基本的 Redis 注解 CRUD 操作,可以直接运行使用。