spring boot整合redis

spring boot整合redis,第1张

spring boot整合redis spring boot整合redis

文章目录
  • spring boot整合redis
    • 安装
    • 启动redis服务
    • 连接redis服务
    • 基于注解整合redis
      • 常用的几个注解
      • 注意点:
    • 基于api的Redis缓存实现
    • Redis序列化处理

安装

redis下载地址

启动redis服务

可以双击redis-server.exe文件,也可以进入改目录,使用命令启动服务

连接redis服务

进入redis安装目录,使用以下命令连接:

redis-cli.exe -h 127.0.0.1 -p 6379

基于注解整合redis

1.添加redis的依赖

        
            org.springframework.boot
            spring-boot-starter-data-redis
            2.4.5
        

2.使用yml文件配置redis

#springboot整合redis配置
#密码默认为空
spring:
  redis:
    host: 127.0.0.1
    port: 6379

3.启动类上添加@EnableCaching注解(目的是开启缓存

4.这里以查询方法举例

使用注解@Cacheable(cacheNames=“user”,unless="#result==null"),该方法作用于要使用缓存的方法上。
1.cacheNames:定义缓存空间的名称
2.unles:当result=null时,不进行缓存(就是查询到的数据为null时不进行缓存)

5.对相关的pojo类实现Serializable接口,让类序列化(不然查询的数据无法被缓存且会报错)

常用的几个注解

1.@Cacheable:作用于数据查询的方法

2.@CachePut:作用于更新方法

3.@CacheEvict: 作用于数据删除

4.@CacheConfig(cacheNames=“user”):统筹管理@Cacheable、@CachePut、@CacheEvict注解标注的方法中的公共属性(包括cacheNames,keyGenerator、cacheManager、cacheResolver)

使用@CacheConfig好处是:使用@CacheConfig(cacheNames=“user”)注解可以统一设置缓存空间的名称,这样@Cacheable注解就不需要再设置缓存空间的名称了。如果@Cacheable等注解也设置了,则采取就近原则。

注意点:

1.pojo类必须序列化
2.必须声明缓存空间名称(即:使用@CacheConfig(cacheNames=“user”)注解及其@Cacheable等注解声明)

基于api的Redis缓存实现

1.继承CrudRepository接口,第一个参数为pojo类,第二个为主键的引用类型

@Repository
public interface UserRepository extends CrudRepository {
	List findById(int id);
	Optional findByAge(int age);
	Optional findBySex(String sex);
	Optional findByName(String name);
//	更新数据
//	int updateUser(String name,int id);

//	删除数据
	int deleteUser(int id);
}

2.编写用于对缓存控制的类ApiUserServices,使用@Autowired注入RedisTemplate实例。

**
 * 基于redis的api的缓存 *** 作
 * 通过该api:1.查询缓存  2.可以更新缓存  3.删除缓存 4.定制缓存过期时间
 * 这里使用Optional接收数据好处:不用像List集合那样比较麻烦的需要判读为空的情况
 *
 */

@Service
public class ApiUserServices {
	@Autowired
	private UserRepository userRepository;
	Logger logger= LoggerFactory.getLogger(ApiUserServices.class);
	@Autowired
	private RedisTemplate redisTemplate;

//	查询数据
	public User findById(int userID){
//		从缓存中查询数据 如果缓存中有对应数据就返回,否者从redis数据库中查询
		Object object=redisTemplate.opsForValue().get("user_"+userID);
		if (object!=null){
			logger.info("缓存中有id="+userID+"的数据");
			return  (User) object;
		}else{
			logger.info("缓存中没有id="+userID+"的数据");
			List user=userRepository.findById(userID);
			if(user!=null){
//				将数据缓存并设置缓存的有效期  有效期设置为1天,最后一个参数可以控制时间单位
				redisTemplate.opsForValue().set("user_"+userID,user.get(0),1, TimeUnit.DAYS);
				logger.info("查询数据缓存succes");
				return  user.get(0);
			}else{
				return null;
			}

		}

	}

//	更新数据和缓存  user:更新后的数据
	public int updateUser(User user){
//		int count=userRepository.updateUser(user.getName(),user.getId());
		int count=0;
		User user1=userRepository.save(user);
		if(user1!=null){
			count=1;
		}
		redisTemplate.opsForValue().set("user_"+user.getId(),user);
		logger.info("更新缓存成功");
		return count;
	}

//	删除数据和缓存
	public int DeleteUser(int userID){
		int count=userRepository.deleteUser(userID);
		boolean isdelete=redisTemplate.delete("user_"+userID);
		if(isdelete){
			logger.info("删除缓存成功");
		}
		return count;

	}
}

3.编写控制器测试
注意:这里使用Restful风格时,要使用@PathVariable获取浏览器的路径参数。否者报错

@RestController
public class UserController {
	@Autowired
	private UserServiceImpl userService;
	@Autowired
	private ApiUserServices apiUserServices;
	private Logger logger= LoggerFactory.getLogger(UserController.class);

//	查询数据
	@GetMapping("/get/{id}")
	public User findUserById(@PathVariable("id") Integer id){
		User user=null;
		System.out.println("id="+id);
		User userList=apiUserServices.findById(id);
		if(userList!=null){
			logger.info("数据查询成功!");
		}else{
			logger.info("查询数据为null");
		}
		return userList;
	}

//	更新数据和缓存
	@GetMapping("/update/{id}/{name}")
	public String updateUser(@PathVariable("id") int id,@PathVariable("name") String name){
		List userList=null;
		int count=0;
		userList=userService.findById(id);
		if(userList!=null){
			userList.get(0).setName(name);
			count=apiUserServices.updateUser(userList.get(0));
		}else{
			logger.info("更新时,查询的数据为null");
		}
		if(count>0){
			return "成功更新数据和缓存";
		}else{
			return "更新数据和缓存fail";
		}
	}

//	删除数据和缓存
	@GetMapping("/delete/{id}")
	public String deleteUser(@PathVariable("id") int id){
		int count=apiUserServices.DeleteUser(id);
		if(count>0){
			return "删除数据和缓存成功";
		}else{
			return "删除数据和缓存fail";
		}

	}

}

Redis序列化处理

Redis序列化的原理

当我们导入starter时,会默认生成一个RedisCahceManager(不进行配置的话@MissingConfiguration)
然后RedisCacheManager帮我们创建RedisCahce来 *** 作(通过使用RedisTemplate
然后RedisTemplate默认采用的是JDK序列化机制

因为redis默认序列化的数据是二进制的,导致在redis客户端不便于查看,因此需要我们自己手动将redis以json或string格式序列化。

package com.example.springboot_redis.Config;

import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import lombok.extern.slf4j.Slf4j;
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.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;



@Slf4j
@Configuration
@EnableCaching
//启用缓存,这个注解很重要;
//继承CachingConfigurerSupport,为了自定义生成KEY的策略。可以不继承。
public class RedisConfig extends CachingConfigurerSupport {

	@Bean(name="redisTemplate")
	public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
		RedisTemplate template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);

		FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
		// value值的序列化采用fastJsonRedisSerializer
		template.setValueSerializer(serializer);
		template.setHashValueSerializer(serializer);
		// key的序列化采用StringRedisSerializer
		template.setKeySerializer(new StringRedisSerializer());
		template.setHashKeySerializer(new StringRedisSerializer());

		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

	@Bean
	public CacheManager cacheManager(RedisConnectionFactory factory) {
		// 生成一个默认配置,通过config对象即可对缓存进行自定义配置
		RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
		// 设置缓存的默认过期时间,也是使用Duration设置
		config = config.entryTtl(Duration.ofMinutes(1))
				.disableCachingNullValues();     // 不缓存空值

		// 设置一个初始化的缓存空间set集合
		Set cacheNames =  new HashSet<>();
		cacheNames.add("my-redis-cache1");
		cacheNames.add("my-redis-cache2");

		// 对每个缓存空间应用不同的配置
		Map configMap = new HashMap<>();
		configMap.put("my-redis-cache1", config);
		configMap.put("my-redis-cache2", config.entryTtl(Duration.ofSeconds(120)));

		// 使用自定义的缓存配置初始化一个cacheManager
		RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
				.initialCacheNames(cacheNames)  // 注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置
				.withInitialCacheConfigurations(configMap)
				.build();
		return cacheManager;
	}
}


					
										


					

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5685046.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)