SpringBoot中使用Redis作为缓存

环境: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.测试

  1. 测试findAll方法,结果为:

执行controller层的findAllData方法。。。。。
查询数据库获得用户信息列表。。。。
执行controller层的findAllData方法。。。。。
执行controller层的findAllData方法。。。。。

测试查询所有数据成功!

  1. 测试findById方法,结果为:

执行controller层的findById方法。。。。。
从数据库中查询编号为:1
执行controller层的findById方法。。。。。
执行controller层的findById方法。。。。。

测试查询单个数据成功!

  1. 测试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;
	}
  1. 重新测试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]

测试更新成功!

  1. 测试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]

测试添加成功!

  1. 测试deleteUserById方法,其结果为:

刪除数据库中编号为:6 的信息
执行controller层的findAllData方法。。。。。
执行controller层的findById方法。。。。。
从数据库中查询编号为:6
【查詢的id為6的数据为:】null

测试删除成功!

  1. 测试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.个人觉得还是实现自己的缓存管理器,这样控制的更加精确!

以上纯属个人见解,如有错误请联系本人!

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值