1.创建springboot-redis-cache项目,配置pom.xml添加依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.6.0</version> </dependency>
模拟:实现针对数据库的一套CRUD:
2.构建user实体类(entity)需要使用get和set方法,引入lombok声明是方法实现,需要安装lombok:
【安装完成要重启IDEA】
package com.cc.springbootrediscache.entity; import lombok.Getter; import lombok.Setter; //lombok提供的注解式提供get和set方法,直接声明处理 @Getter @Setter public class User { private Integer id; private String username; private String password; private Integer status; }
3.构建数据库操作,定义UserMapper底层数据库操作接口
package com.cc.springbootrediscache.mapper; import com.cc.springbootrediscache.entity.User; import org.apache.ibatis.annotations.*; import java.util.List; public interface UserMapper { /** * 使用注解的方式实现数据库操作,不在为接口做impl实现类 */ //添加方法 @Options(useGeneratedKeys = true,keyProperty = "id") //设置主键生成策略 @Insert("insert into user (username,password,status) values (#{username},#{password},#{status})")//id自增 Integer addUser(User user); //删除方法,id=#{0}取第一个参数作为删除key @Delete("delete form user where id=#{0}") Integer deleteUserById(Integer id); //修改方法 @Update("update user set username=#{username},password=#{password},status=#{status} where id=#{id}") Integer updateUser(User user); /** *所有查询语句不允许使用*符号 */ //条件查询方法 @Select("select username,password,status from user where id=#{0}") User getById(Integer id); //查询方法 @Select("select id,username,password,status from user") List<User> queryUserList(); }
4.构建UserService业务处理类
package com.cc.springbootrediscache.service; import com.cc.springbootrediscache.entity.User; import com.cc.springbootrediscache.mapper.UserMapper; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class UserService { @Resource private UserMapper userMapper; //添加和(更新)修改都调用此方法 public User save(User user){ if(null != user.getId()){ userMapper.updateUser(user); }else{ userMapper.addUser(user); } return user; } //查询业务 public User findUser(Integer id){ return userMapper.getById(id); } //删除用户 public boolean delUser(Integer id){ return userMapper.deleteUserById(id) > 0; } }
5.构建UserController业务操作类
package com.cc.springbootrediscache.controller; import com.cc.springbootrediscache.entity.User; import com.cc.springbootrediscache.service.UserService; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @RestController @RequestMapping("/user") public class UserController { @Resource private UserService userService; @PutMapping public User add(@RequestBody User user){ return userService.save(user); } @DeleteMapping("{id}") public boolean delete(@PathVariable Integer id){ return userService.delUser(id); } @GetMapping("{id}") public User getUser(@PathVariable Integer id){ return userService.findUser(id); } @PostMapping public User update(@RequestBody User user){ return userService.save(user); } }
6.配置application.properties:
server.port=9900 spring.datasource.driverClassName=org.h2.Driver //指定存入到文件中,重启不会丢失 spring.datasource.url=jdbc:h2:file:D:/user/data/h2:MODE=MYSQL; spring.datasource.username= spring.datasource.password=
7.使用测试用例来测试代码:
在test下构建配置文件
将实际项目配置与测试用例配置分开,并增加一些配置:
server.port=9900 spring.datasource.driverClassName=org.h2.Driver //指定存入到文件中,重启不会丢失(测试用例中此步做一个初始化表的过程) spring.datasource.url=jdbc:h2:file:D:/user/data/h2;MODE=MYSQL;INIT=RUNSCRIPT FROM './src/test/resources/init.sql' spring.datasource.username= spring.datasource.password= 定义初始化表的脚本文件: CREATE TABLE if NOT EXISTS user( id int not null PRIMARY KEY auto_increment, username VARCHAR (200), password VARCHAR (200), status int )
控制台输出:
测试通过;
8.通过postMan来测试接口:
完成没有问题!
*************************************************************************************************************************************************
开始在上述基础上实现redis缓存!
1.创建RedisCacheConfig类:
package com.cc.springbootrediscache.config; 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.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.cache.RedisCacheWriter; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import java.time.Duration; @Configuration @EnableCaching public class RedisCacheConfig extends CachingConfigurerSupport { //spring 2.X的方法 @Bean public CacheManager cacheManager (RedisConnectionFactory redisConnectionFactory){ //初始化一个RedisCacheWriter RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); //设置CacheManager的值序列化方式为json序列化 RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer(); RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair .fromSerializer(jsonSerializer); RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig() .serializeValuesWith(pair); //设置默认超过期时间是30秒 defaultCacheConfig.entryTtl(Duration.ofSeconds(360)); //初始化RedisCacheManager return new RedisCacheManager(redisCacheWriter, defaultCacheConfig); } /*spring1.x的方法 @Bean public CacheManager cacheManager(RedisTemplate redisTemplate){ RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate); redisCacheManager.setDefaultExpiration(360); return redisCacheManager; } //设置序列化与反序列化的方式 @Bean public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){ StringRedisTemplate template = new StringRedisTemplate(redisConnectionFactory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); template.setDefaultSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; }*/ }
2.配置application.properties:
server.port=9900 spring.datasource.driverClassName=org.h2.Driver //指定存入到文件中,重启不会丢失 spring.datasource.url=jdbc:h2:file:D:/user/data/h2;MODE=MYSQL; spring.datasource.username= spring.datasource.password= # database name spring.redis.database=0 # server host1 单机使用,对应服务器ip spring.redis.host=192.168.1.11 # server password 密码,如果没有设置可不配 #spring.redis.password= #connection port 单机使用,对应端口号 spring.redis.port=10179 # pool settings ...池配置 spring.redis.pool.max-idle=8 spring.redis.pool.min-idle=0 spring.redis.pool.max-active=8 spring.redis.pool.max-wait=-1 logging.level.com.cc.springbootrediscache.mapper=debug
3.在service中添加redis缓存声明
package com.cc.springbootrediscache.service; import com.cc.springbootrediscache.entity.User; import com.cc.springbootrediscache.mapper.UserMapper; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class UserService { @Resource private UserMapper userMapper; //添加和(更新)修改都调用此方法 //声明添加redis缓存,key是user_userID,可以使用unless = "#result eq null"来增加一些条件,返回结果补位null则插入缓存 //@CachePut(value = "usercache",key = "user1",unless = "#result eq null") @CachePut(value = "usercache", key = "'user_' + #user.id.toString()", unless = "#result eq null") public User save(User user){ if(null != user.getId()){ userMapper.updateUser(user); }else{ System.out.println(user.getUsername()+""+user.getId()); userMapper.addUser(user); System.out.println(user.getUsername()+""+user.getId()); } return user; } //查询业务 /* 声明使用redis缓存,如果key = "'user_'+#usr.id.toString()"在redis里有,则直接返回不用查数据库, 如果没有则查询数据库; unless = "#result eq null",如果查询数据库结果不为null,则存入缓存,待下次使用; */ //@Cacheable(value = "usercache",key = "'user_'+#id",unless = "#result eq null") @Cacheable(value = "usercache", key = "'user_' + #id", unless = "#result eq null") public User findUser(Integer id){ return userMapper.getById(id); } //删除用户 /* 删除缓存; condition = "#resut eq true "只有当数据库删除成功了才删除缓存 */ //@CacheEvict(value = "usercache",key = "'user_'+#id",condition = "#resut eq true ") @CacheEvict(value = "usercache", key = "'user_' + #id", condition = "#result eq true") public boolean delUser(Integer id){ return userMapper.deleteUserById(id) > 0; } }
4.运行CRUD并观察redis:
成功加入了数据到数据库及redis;
查询成功;
修改成功;
删除成功。