Spring Boot整合Spring Cache和 Spring Data Redis
Spring Boot整合Spring Cache和 Spring Data Redis
最近学习Spring Boot相关的实战,花了些时间把Spring Boot中整合Spring Cache和Spring Data Redis的过程配置了一下。
项目使用的框架:MySQL+Redis+MyBatis+Spring Boot(Web,Cache,Spring Data Redis)。
下图是项目结构,我没有编写controller层。
引入依赖(pom.xml)
<dependencies>
<!--Spring Cache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!--Spring Data Redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--Spring Web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--MyBatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!--MySQL Connector-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
配置application.properties
#数据源的配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test_mybatis?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=12345678
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#显示sql查询过程
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#Redis(Jedis)配置
#Redis数据库索引
spring.redis.database=0
#Redis服务器地址
spring.redis.host=192.168.152.129
#Redis服务器端口
spring.redis.port=7001
#Redis服务器连接密码(默认为空)
spring.redis.password=
#Redis连接超时(ms)
spring.redis.timeout=1200
#Redis Pool
#连接池最大连接数
spring.redis.jedis.pool.max-active=8
#连接池最大阻塞等待时间(负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
#最小空闲连接
spring.redis.jedis.pool.min-idle=0
#最大空闲连接
spring.redis.jedis.pool.max-idle=8
创建实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
/**
* 实体类需要实现序列化
*/
public class User implements Serializable {
int id;
String name;
int age;
}
创建Mapper
这里Mapper使用了MyBatis的动态代理,相当于传统的DAO。
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE id=#{id}")
public User getUserById(int id);
@Select("SELECT * FROM user")
public List<User> getAllUsers();
@Insert("INSERT INTO user(name,age) VALUES(#{name},#{age})")
public int addUser(User user);
@Update("UPDATE user set name=#{name},age=#{age} WHERE id=#{id}")
public int updateUser(User user);
@Delete("DELETE FROM user WHERE id=#{id}")
public int deleteUserById(int id);
}
创建RedisConfig
要实现Spring Cache对Redis的缓存管理需要配置CacheManager,如果需要使用RedisTemplate完成Redis缓存的访问还要配置RedisTemplate。
@Configuration
//启用Spring Cache
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
/**
* 缓存管理器配置
*
* @param redisConnectionFactory
* @return
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
CacheManager cacheManager = RedisCacheManager.create(redisConnectionFactory);
return cacheManager;
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
@Bean
public StringRedisTemplate getStringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
创建service
service层使用注解的形式完成缓存的管理,Spring Cache是基于AOP实现该功能的。
@CacheConfig(cacheNames = "users")
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserMapper userMapper;
@Override
@Cacheable(key = "#p0")
public User getUserById(int id) {
return userMapper.getUserById(id);
}
@Override
@Cacheable(cacheNames = "user::list")
public List<User> getAllUsers() {
return userMapper.getAllUsers();
}
@Override
public int addUser(User user) {
return userMapper.addUser(user);
}
@Override
@CachePut(key = "#user.id")
public User updateUser(User user) {
userMapper.updateUser(user);
return user;
}
@Override
@CacheEvict(key ="#id")
public int deleteUserById(int id) {
return userMapper.deleteUserById(id);
}
}
测试代码
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserServiceTest {
@Autowired
UserService userService;
@Test
public void getUserById() {
int id = 16;
User user = userService.getUserById(id);
System.out.println(user);
//第二次查询
user = userService.getUserById(id);
System.out.println(user);
}
@Test
public void getAllUsers() {
List<User> users = userService.getAllUsers();
System.out.println(users.size());
users = userService.getAllUsers();
System.out.println(users.size());
}
@Test
public void addUser() {
//添加用户直接是到数据库的,不需要缓存
}
@Test
public void updateUser() {
User user = new User();
int id = 47;
user.setId(id);
user.setName("TestTestTest3");
user.setAge(14);
userService.updateUser(user);
//查看缓存是否更新
user.setName("Liu");
user = userService.getUserById(id);
System.out.println(user);
}
@Test
public void deleteUser() {
int id = 47;
int result = userService.deleteUserById(id);
System.out.println(result);
}
}
参考
《Spring Boot实战派》
https://www.cnblogs.com/lzhdonald/p/11560002.html
https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/integration.html#cache
https://docs.spring.io/spring-data/redis/docs/2.3.1.RELEASE/reference/html/#redis:sentinel