利用空余时间学习Redis的简单使用,记录一下,往后需要使用方便查看。
window版Redis安装
借鉴了https://www.cnblogs.com/skmobi/p/11696620.html这个老哥的
1,Redis下载,下载完后在d盘新建一个Redis文件夹并解压下载的包
链接:https://pan.baidu.com/s/1b7QlQGvz8Dtjz6-eFpxfRQ
提取码:d4yl
2,启动临时服务:打开一个cmd,切换到刚刚新建Redis文件夹里,然后输入命令:redis-server.exe redis.windows.conf (备注:通过这个命令,会创建Redis临时服务,不会在window Service列表出现Redis服务名称和状态,此窗口关闭,服务会自动关闭。)
重新在打开一个cmd,输入命令:redis-cli.exe -h 127.0.0.1 -p 6379,测试set name '随意' ,get name 可以出数据表示Redis使用正常
整合springboot,配置借鉴了https://www.cnblogs.com/lzhdonald/p/11560002.html这个老哥的,记不住这些东西
1, pom配置,我这里加了版本号启动会冲突,所以去掉了
<!--redis--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <!--<version>2.9.0</version>--> </dependency> <!-- config redis data and client jar--> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <!--<version>2.1.0.RELEASE</version>--> </dependency> <!--commons-pool2--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <!--<version>2.6.0</version>--> </dependency>
2,application.yml配置Redis
spring:
#redis配置 redis: ## Redis数据库索引(默认为0) database: 0 ## Redis服务器地址,本机ip地址 host: 192.168.51.23 ## Redis服务器连接端口 port: 6379 ## Redis服务器连接密码(默认为空) password: jedis: pool: ## 连接池最大连接数(使用负值表示没有限制) #spring.redis.pool.max-active=8 max-active: 8 ## 连接池最大阻塞等待时间(使用负值表示没有限制) #spring.redis.pool.max-wait=-1 max-wait: -1 ## 连接池中的最大空闲连接 #spring.redis.pool.max-idle=8 max-idle: 8 ## 连接池中的最小空闲连接 #spring.redis.pool.min-idle=0 min-idle: 0 ## 连接超时时间(毫秒) timeout: 1200
3,实体类记得需要序列化,不然要报错
4,配置redistemplate序列化
package com.demo.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.*; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.time.Duration; /** * @author lzh * create 2019-09-24-15:07 */ @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { /** * 选择redis作为默认缓存工具 * @param redisConnectionFactory * @return */ /*@Bean //springboot 1.xx public CacheManager cacheManager(RedisTemplate redisTemplate) { RedisCacheManager rcm = new RedisCacheManager(redisTemplate); return rcm; }*/ @Bean public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时 return RedisCacheManager .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory)) .cacheDefaults(redisCacheConfiguration).build(); } /** * retemplate相关配置 * @param factory * @return */ @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); // 配置连接工厂 template.setConnectionFactory(factory); //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式) Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jacksonSeial.setObjectMapper(om); // 值采用json序列化 template.setValueSerializer(jacksonSeial); //使用StringRedisSerializer来序列化和反序列化redis的key值 template.setKeySerializer(new StringRedisSerializer()); // 设置hash key 和value序列化模式 template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(jacksonSeial); template.afterPropertiesSet(); return template; } /** * 对hash类型的数据操作 * * @param redisTemplate * @return */ @Bean public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForHash(); } /** * 对redis字符串类型数据操作 * * @param redisTemplate * @return */ @Bean public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForValue(); } /** * 对链表类型的数据操作 * * @param redisTemplate * @return */ @Bean public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForList(); } /** * 对无序集合类型的数据操作 * * @param redisTemplate * @return */ @Bean public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForSet(); } /** * 对有序集合类型的数据操作 * * @param redisTemplate * @return */ @Bean public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForZSet(); } }
5,这里在serviceimpl里面进行操作,这里只对查询做了测试,更新和删除列出的是逻辑没有进行测试
package com.demo.service.Impl; import com.demo.dao.EmployeeMapper; import com.demo.entity.Employee; import com.demo.service.IEmployeeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.concurrent.TimeUnit; @Service @Transactional public class EmployeeServiceImpl implements IEmployeeService { @Autowired private EmployeeMapper employeeMapper; @Autowired private RedisTemplate redisTemplate;//引入Redis /** * 查询用户:先从缓存中获取用户,没有则查询数据库,再将数据写入缓存 * redisTemplate.opsForValue();//操作字符串 redisTemplate.opsForHash();//操作hash redisTemplate.opsForList();//操作list redisTemplate.opsForSet();//操作set redisTemplate.opsForZSet();//操作有序set
TimeUnit.DAYS //天
TimeUnit.HOURS //小时
TimeUnit.MINUTES //分钟
TimeUnit.SECONDS //秒
TimeUnit.MILLISECONDS //毫秒
* @param email * @return */ @Override public Employee queryEmail(String email) { Employee employee = new Employee(); ValueOperations<String,Employee> valueOperations = redisTemplate.opsForValue();//Redis数据结构 Boolean hasKey = redisTemplate.hasKey(email);//将email作为key值去Redis中查询是否有数据 if(hasKey){ employee = valueOperations.get(email);//通过key值获取数据 System.out.println("从Redis获取到的数据:"+employee); }else { employee = employeeMapper.queryEmail(email);//数据库查询数据 System.out.println("从数据库获取到的数据:"+employee); //将数据写Redis,设置变量值的过期时间 valueOperations.set(email,employee,1, TimeUnit.HOURS); } return employee; } @Override public void insert(Employee employee) { employeeMapper.insert(employee); } /** * 更新用户:先更新数据库里的数据,成功之后,再删除原来的缓存,最后重新添加缓存 */ public int updateByPrimaryKey(Employee employee) { ValueOperations<String, Employee> operations = redisTemplate.opsForValue(); int num = employeeMapper.updateByPrimaryKey(employee); if (num != 0) { boolean haskey = redisTemplate.hasKey(employee.getEmail()); if (haskey) { redisTemplate.delete(employee.getEmail()); System.out.println("删除缓存中的key-----------> " + employee.getEmail()); } // 再将更新后的数据加入缓存 Employee employees = employeeMapper.queryEmail(employee.getEmail()); if (employees != null) { operations.set(employees.getEmail(), employees, 3, TimeUnit.HOURS); } } return num; } /** * 删除用户:先删除数据库表中的数据,然后在删除缓存 */ public int deleteUserById(int id) { int num = employeeMapper.deleteByPrimaryKey(id);if (num != 0) { boolean hasKey = redisTemplate.hasKey(id); if (hasKey) { redisTemplate.delete(id); System.out.println("删除了缓存中的key:" + id); } } return num; } }
6,第一次通过接口查询执行结果,可以看到执行了SQL语句
第二次通过接查询执行结果