环境:JDK1.8、MAVEN 3.6.1 、eclipse
1.添加redis依赖
当前的
pom
文件内容:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.4.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 配置redis数据库 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
<!-- junit配置 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
当前的
application.properties
内容
server.port=9090
server.context-path=/springboot-cache-redis
spring.redis.host=localhost
spring.redis.password=
spring.redis.port=6379
2.创建redis的配置类
当前的
RedisConfig
配置类如下:
/**
* @description redis的配置类
* @author hy
* @date 2019-08-13
*/
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private String redisPort;
/**
* @description 创建RedisTemplate 的操作类
*/
@Bean
public RedisTemplate<String, User> getRedisTemplate() {
RedisTemplate<String, User> redisTemplate = new RedisTemplate<String, User>();
redisTemplate.setConnectionFactory(getConnectionFactory());
return redisTemplate;
}
/**
* @description 创建redis连接工厂
*/
public RedisConnectionFactory getConnectionFactory() {
System.out.println("host:" + redisHost);
System.out.println("port:" + redisPort);
RedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(
new JedisShardInfo(redisHost, redisPort));
return jedisConnectionFactory;
}
/**
* @description 设置缓存管理器
*/
@Bean(name = "cacheManager")
public RedisCacheManager getRedisCacheManager() {
RedisCacheManager redisCacheManager = new RedisCacheManager(getRedisTemplate());
return redisCacheManager;
}
}
3.创建实体类
/**
* @author hy
* @date 2019-08-13
*/
@SuppressWarnings("serial")
public class User implements Serializable {
private Integer id;
private String name;
private Date birth;
private Boolean onWork;
....省略getter、setter和toString方法
}
4.创建dao层
UserDao
的内容如下:
/**
* @description user的dao层
* @author hy
* @date 2019-08-13
*/
public interface UserDao {
List<User> findAll();
User findUserById(Integer id);
void addUser(User user);
void updateUser(User user);
void deleteUserById(Integer id);
void clearCache();
}
5.创建dao的实现层
当前的
UserDaoImpl
的内容:
/**
* @description userDao的实现类
* @author hy
* @date 2019-08-13
*/
@Repository
public class UserDaoImpl implements UserDao {
static Map<Integer, User> userData = new HashMap<Integer, User>();
/**
* @description 模拟数据库
*/
static {
userData.put(1, new User(1, "张三", new Date(), false));
userData.put(2, new User(2, "李四", new Date(), true));
userData.put(3, new User(3, "lili", new Date(), false));
userData.put(4, new User(4, "lucy", new Date(), true));
userData.put(5, new User(5, "jeck", new Date(), false));
}
/**
* @description 查询所有的user数据信息
*/
@Cacheable(key = "#root.methodName", value = "userCache")
//@Cacheable 表示如果要查的value库中有缓存中有findAll的key,就直接在缓存中查询,不存在直接到数据库中查询
@Override
public List<User> findAll() {
System.out.println("查询数据库获得用户信息列表。。。。");
Collection<User> values = userData.values();
List<User> userList = new ArrayList<User>();
for (User user : values) {
userList.add(user);
}
return userList;
}
/**
* @description 根据id查询用户信息
*/
@Cacheable(key = "#id.toString()", value = "userCache")
//@Cacheable 表示可缓存,如果缓存中存在,就从缓存中查询,不存在,就走数据库
//其中缓存库位userCache,key表示使用缓存的key(为当前的传递的id.toString())
@Override
public User findUserById(Integer id) {
System.out.println("从数据库中查询编号为:"+id);
return userData.get(id);;
}
/**
* @description 添加user数据信息
*/
@CachePut(key = "#user.id.toString()", value = "userCache")
//@CachePut 表示向缓存中直接添加数据,添加的库为当前的value,添加的key为当前的key(user的id.toString())
@Override
public void addUser(User user) {
userData.put(user.getId(), user);
}
/**
* @description 更新User数据
*/
@CachePut(key = "#user.id.toString()", value = "userCache")
//@CachePut 表示向缓存中直接添加数据,添加的库为当前的value,添加的key为当前的key(user的id.toString())
@Override
public void updateUser(User user) {
userData.put(user.getId(), user);
}
/**
* @description 根据id删除user数据
*/
@CacheEvict(key = "#id.toString()", value = "userCache")
//@CacheEvict用来删除数据,指定key表示删除缓存库中的key的字段的内容,value表示删除的缓存的库
@Override
public void deleteUserById(Integer id) {
userData.remove(id);
}
/**
* @description 用来清空缓存
*/
@CacheEvict(allEntries = true, value = "userCache")
//@CacheEvict用来删除数据,指定allEntries = true表示删除所有的缓存,value表示删除的缓存的库
@Override
public void clearCache() {
System.out.println("====清空缓存===");
}
}
6.创建controller层
当前的
UserController
层中的内容
/**
* @description 使用redisTemplate控制user对象的存储
* @author hy
* @date 2019-08-13
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
UserDao userDao;
/**
* @description 用于添加User数据
* @param user 添加的数据
* @return 添加的提示信息
*/
@RequestMapping("/add")
@ResponseBody
public String addData(User user) {
System.out.println("执行controller层的addData方法。。。。。");
if (user != null) {
userDao.addUser(user);
return "【添加数据】:" + user.getName() + " 成功!";
}
return "【添加数据】:" + user + " 失败!";
}
/**
* @description 删除数据user
* @param name 需要删除的user的id编号
* @return 提示信息
*/
@RequestMapping("/delete/{id}")
@ResponseBody
public String deleteData(@PathVariable("id") Integer id) {
System.out.println("执行controller层的deleteData方法。。。。。");
if (id != null) {
userDao.deleteUserById(id);
return "【刪除编号为 " + id + " 成功!】";
}
return "【刪除数据 " + id + " 失败!】";
}
/**
* @description 根据当前数据的hash更新user数据
* @param user 用户
* @return 修改成功和失败的数据
*/
@RequestMapping("/update")
@ResponseBody
public String updateData(User user) {
System.out.println("执行controller层的updateData方法。。。。。");
userDao.addUser(user);
return "【更新成功!】";
}
/**
* @description 查询所有user的数据,列表
* @return
*/
@RequestMapping("/findAll")
@ResponseBody
public String findAllData() {
System.out.println("执行controller层的findAllData方法。。。。。");
List<User> userList = userDao.findAll();
return userList.toString();
}
/**
* @description 根据id查询user数据
* @param id 当前的hash
* @return 该下标的数据信息
*/
@RequestMapping("/findById/{id}")
@ResponseBody
public String findById(@PathVariable("id") Integer id) {
System.out.println("执行controller层的findById方法。。。。。");
User user = userDao.findUserById(id);
return "【查詢的id為" + id + "的数据为:】" + user;
}
/**
* @description 清空所有的数据
* @return 提示信息
*/
@RequestMapping("/clear")
@ResponseBody
public String clear() {
System.out.println("执行controller层的clear方法。。。。。");
userDao.clearCache();
return "【当前的緩存清除成功】";
}
}
7.创建入口类
当前的
Application
类中的内容如下
/**
1. @description 使用SpringBoot中使用redis作为缓存
2. @author hy
3. @date 2019-08-13
*/
@RestController
@EnableCaching // 开启缓存
@SpringBootApplication
public class Application {
@Autowired
RedisCacheManager redisCacheManager;
/**
* @description 测试redisCacheManager 是否配置正确
*/
@RequestMapping("/redisCacheManager")
public String redisCacheManager() {
return redisCacheManager.toString();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
8.测试
测试findAll
方法,结果为:
执行controller层的findAllData方法。。。。。
查询数据库获得用户信息列表。。。。
执行controller层的findAllData方法。。。。。
执行controller层的findAllData方法。。。。。
测试查询所有数据成功!
测试findById
方法,结果为:
执行controller层的findById方法。。。。。
从数据库中查询编号为:1
执行controller层的findById方法。。。。。
执行controller层的findById方法。。。。。
测试查询单个数据成功!
测试updateUser
方法,结果为:
执行controller层的updateData方法。。。。。
执行controller层的findById方法。。。。。
【查詢的id為1的数据为:】null
测试更新失败
!
当前的updateUser返回值为void
,所以没有添加数据并更新
所以:当前的缓存是缓存的就是当前方法的返回值
,作为存储的value的,开始修改缓存的方法
当前修改后的
updateUser
方法和addUser
方法
/**
* @description 添加user数据信息
*/
@CachePut(key = "#user.id.toString()", value = "userCache")
// @CachePut 表示向缓存中直接添加数据,添加的库为当前的value,添加的key为当前的key(user的id.toString())
// 发现只能将返回值作为缓存的数据
@Override
public User addUser(User user) {
System.out.println("向数据库中添加编号为:" + user.getId() + " 的信息");
userData.put(user.getId(), user);
return user;
}
/**
* @description 更新User数据
*/
@CachePut(key = "#user.id.toString()", value = "userCache")
// @CachePut 表示向缓存中直接添加数据,添加的库为当前的value,添加的key为当前的key(user的id.toString())
//发现只能将返回值作为缓存的数据
@Override
public User updateUser(User user) {
System.out.println("更新数据库中编号为:" + user.getId() + " 的信息");
userData.put(user.getId(), user);
return user;
}
- 重新测试
updateUser
方法,其结果为:
执行controller层的updateData方法。。。。。
执行controller层的findById方法。。。。。
执行controller层的findById方法。。。。。
【查詢的id為1的数据为:】User [id=1, name=updateName, birth=Thu Mar 08 00:00:00 CST 2018, onWork=false]
测试更新成功!
- 测试
addUser
方法,其结果为:
执行controller层的addData方法。。。。。
向数据库中添加编号为:6 的信息
执行controller层的findById方法。。。。。
执行controller层的findById方法。。。。。
【查詢的id為6的数据为:】User [id=6, name=admin, birth=Sun May 05 00:00:00 CST 2019, onWork=true]
测试添加成功!
- 测试
deleteUserById
方法,其结果为:
刪除数据库中编号为:6 的信息
执行controller层的findAllData方法。。。。。
执行controller层的findById方法。。。。。
从数据库中查询编号为:6
【查詢的id為6的数据为:】null
测试删除成功!
- 测试
clear
方法清空缓存,其结果
【当前的緩存清除成功】
发现数据库中没有了缓存
9.总结
1.当前的缓存还是存在缺陷
,当更新数据的时候当前的findAll方法中的缓存,随着当前数据的增加和删除
,修改没有
随之发生变化
2.只有自定义的缓存控制才能实现该方法,进行控制缓存
3.使用缓存需要先开启缓存:@EnableCaching
// 开启缓存
4.需要创建缓存管理器RedisCacheManager
5.使用注解的方式控制缓存,需要将缓存控制放在dao
层
@Cacheable(key = "#root.methodName", value = "userCache")
表示缓存中存在从缓存中获取,否者从数据库获取@CachePut
表示向缓存中直接添加数据,并且向数据库更新数据@CacheEvict
用来删除缓存中的数据和删除数据库的数据
allEntries = true
,表示删除所有的缓存数据(一般用来清空缓存)
指定key
的时候,表示删除缓存中指定的数据
,删除数据库的数据
6.其中的key
,一般表示缓存的key,value表示缓存的库
7.个人觉得还是实现自己的缓存管理器
,这样控制的更加精确!
以上纯属个人见解,如有错误请联系本人!