1.连接redis--2014
默认有三种方式连接redis.
第一种:jedis---传统的项目--ssm
第二种:lettuce:---->刚出现没有多久就被springboot整合进来。
第三种:springboot连接redis
1.1 jedis操作redis服务器
(1)引入jedis依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.3.1</version>
</dependency>
(2)编写相关的代码
void testJedis(){
Jedis jedis=new Jedis("192.168.1.87",6379);
//该类包含很多对redis操作的方法--而这些方法和原来我们使用的命令一样。
Set<String> keys = jedis.keys("*");
System.out.println(keys);
//对string数据类型操作
String set = jedis.set(;"k3", "zmz");
System.out.println("set"+set);
String v3 = jedis.get("k3");
System.out.println("v3:"+v3);
jedis.setex("s1",99,"jsl");
jedis.close();
}
每次使用jedis对象时 都需要自己创建,当使用完后,需要关闭该对象。===>jedis中也存在连接池.
1.2 jedis连接池的使用
//连接池的配置信息
JedisPoolConfig config=new JedisPoolConfig();
config.setMaxTotal(100);//最多的连接个数
config.setMaxIdle(10); //最多空闲的连接个数
config.setMinIdle(2); //最小的空闲个数
config.setTestOnBorrow(true);//在获取连接对象时是否验证该连接对象的连通性
//创建连接池对象
JedisPool jedisPool=new JedisPool(config,"192.168.1.87",6379);
long start = System.currentTimeMillis();
for(int i=0;i<1000;i++){
Jedis jedis = jedisPool.getResource();
String ping = jedis.ping();
jedis.close();
}
long end = System.currentTimeMillis();
System.out.println("耗时:"+(end-start));
long start = System.currentTimeMillis();
//Jedis(String host, int port)
for(int i=0;i<1000;i++){
Jedis jedis=new Jedis("192.168.1.87",6379);
String ping = jedis.ping();
jedis.close();
}
long end = System.currentTimeMillis();
System.out.println("耗时:"+(end-start));
1.3 springboot整合redis
springboot在整合redis时提高两个模板类,StringRedisTemplate和RedisTemplate.以后对redis的操作都在该模板类中。StringRedisTemplate是RedisTemplate的子类。
<!--redis相关的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
修改配置文件
#redis的配置信息
spring.redis.host=192.168.1.87
spring.redis.port=6379
#最多获取数
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
//因为springboot整合redis时会把StringRedisTemplate创建并交于spring容器管理
@Autowired
private StringRedisTemplate redisTemplate;
@Test
void contextLoads() {
//关于key的操作
Set<String> keys = redisTemplate.keys("*");//获取所有的key
System.out.println("keys:"+keys);
Boolean hasKey = redisTemplate.hasKey("k1");//判断是否存在指定的key
System.out.println("判断是否存在指定的key:"+hasKey);
Boolean k1 = redisTemplate.delete("k1");//删除指定的key
System.out.println("是否删除指定key成功:"+k1);
//操作Stirng------StringRedisTemplate会把对每一种数据的操作单独封装成一个类。
ValueOperations<String, String> forValue = redisTemplate.opsForValue();//ValueOperations专门操作字符串
forValue.set("k2","张明喆");
String k2 = forValue.get("k2");
System.out.println("k2:"+k2);
//只有在 key 不存在时设置 key 的值。
Boolean aBoolean = forValue.setIfAbsent("k2", "zmz2");
System.out.println("是否存入成功:"+aBoolean);
//incr decr
Long k4 = forValue.increment("k4",20);
System.out.println("k4:"+k4);
//decr 将 key 中储存的数字值减一
forValue.decrement("k4");
//批量添加
Map<String,String> map=new HashMap<>();
map.put("m1","m1");
map.put("m2","m2");
forValue.multiSet(map);
//hash操作
HashOperations<String, Object, Object> forHash = redisTemplate.opsForHash();
forHash.put("k5", "name", "zmz");
forHash.put("k5", "age", "16");
forHash.put("k5", "sex", "男");
Map<String, String> map1 = new HashMap<>();
map.put("name", "jsl");
map.put("age", "29");
map.put("sex", "男");
forHash.putAll("k6", map1);
Map<Object, Object> k5 = forHash.entries("k5");
System.out.println(k5);
Set<Object> k6 = forHash.keys("k6");
System.out.println(k6);
System.out.println(forHash.values("k6"));
//list操作
ListOperations<String, String> list = redisTemplate.opsForList();
//放入单个 key value
list.leftPush("l1","111");
//放入 批量value
list.leftPushAll("l2","zmz","jsl","hql","fxd");
//获取列表指定范围内的元素
List<String> l2 = list.range("l2", 0, -1);
System.out.println(l2);
//移出并获取列表的第一个元素
list.leftPop("l2");
//set 无序不允许重复.
SetOperations<String, String> forSet = redisTemplate.opsForSet();
//向集合添加一个或多个成员
forSet.add("s1","张明喆","贾善领","黄启龙","张明喆","贾善领");
forSet.add("s2","张明喆1","贾善领2","黄启龙3","张明喆","贾善领");
//返回集合中的所有成员
Set<String> s1 = forSet.members("s1");
System.out.println(s1);
//随机获取一个或多个元素
String s11 = forSet.randomMember("s1");
System.out.println(s11);
//返回给定所有集合的交集
Set<String> intersect = forSet.intersect("s1", "s2");
System.out.println(intersect);
//sort set操作
ZSetOperations<String, String> forZSet = redisTemplate.opsForZSet();
//向有序集合添加一个或多个成员,或者更新已存在成员的分数
forZSet.add("z1","math",80);
forZSet.add("z1","chinese",99);
forZSet.add("z1","english",78);
forZSet.add("z1","physics",76);
forZSet.add("z1","biology",60);
//通过索引区间返回有序集合成指定区间内的成员
Set<String> z1 = forZSet.range("z1", 0, -1);
System.out.println(z1);
//返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
Set<String> z11 = forZSet.reverseRange("z1", 0, -1);
System.out.println(z11);
}
1.4RedisTemplate
它是StringRedisTemplate的父类,它类可以存储任意数据类型,但是任意类型必须序列化,默认采用的是jdk的序列化方式。jdk序列化方式阅读能力差,而且占用空间大. 我们在使用是一般需要人为指定序列化方式。
public class SpringbootRedisApplicationTests2 {
@Autowired
private RedisTemplate redisTemplate;
@Test
void test1(){
ValueOperations valueOperations = redisTemplate.opsForValue();
valueOperations.set("user",new User("张明喆",29,"上海"));
Object o = valueOperations.get("user");
System.out.println(o);
HashOperations hashOperations = redisTemplate.opsForHash();
hashOperations.put("k3","name","zmz");
Map<String, Object> map = new HashMap<>();
map.put("1", new User("zz",22,"ll"));
hashOperations.putAll("k5", map);
}
}
如果每次使用都人为指定序列化方式,统一设置redisTemplate的序列化
package com.sws;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @program: springboot-redis
* @description:
* @author:
* @create: 2023-04-24 16:24
**/
@Configuration
public class RedisConfig {
//比如验证码
@Bean //该方法的返回对象交于spring容器管理
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setConnectionFactory(factory);
//key序列化方式
template.setKeySerializer(redisSerializer);
//value序列化
template.setValueSerializer(jackson2JsonRedisSerializer);
//value hashmap序列化
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.setHashKeySerializer(redisSerializer);
return template;
}
}
1.5 springboot连接集群
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
# 设置redis重定向的次数---根据主节点的个数
spring.redis.cluster.max-redirects=3
spring.redis.cluster.nodes=192.168.1.87:7001,192.168.1.87:7002,192.168.1.87:7003,192.168.1.87:7004,192.168.1.87:7005,192.168.1.87:7006
2.redis的应用场景
2.1. redis可以作为缓存
(1) 缓存的原理
(2)缓存的作用:
减少访问数据库的频率。--提高系统的性能。
(3)什么样的数据适合放入缓存
查询频率高的
修改频率低的
数据安全性要求低的。
(4)如何使用缓存
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ykq</groupId>
<artifactId>qy163-springboot-redis02</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>qy163-springboot-redis02</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
(3)配置文件
server.port=9999
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql:///aaa
spring.datasource.username=root
spring.datasource.password=17637422471
#打印日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#最多获取数
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
# ??redis??????---????????
spring.redis.cluster.max-redirects=3
#redis的配置信息
spring.redis.host=192.168.1.87
spring.redis.port=6379
servie层
package com.sws.service.impl;
import com.sws.mapper.Student1Mapper;
import com.sws.pojo.Student1;
import com.sws.service.Student1Service;
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 javax.annotation.Resource;
/**
* @program: springboot--redis
* @description:
* @author:
* @create: 2023-04-24 18:07
**/
@Service
public class Student1ServiceImpl implements Student1Service {
@Resource
private Student1Mapper student1Mapper;
@Autowired
private RedisTemplate<String,Object> redisTemplate;
@Override
public Student1 selectById(Integer id) {
ValueOperations<String, Object> ops =redisTemplate.opsForValue();
Object o = ops.get("student:" + id);
if (o!=null){
return (Student1) o;
}
Student1 student1 = student1Mapper.selectById(id);
if (student1!=null){
ops.set("student:"+id,student1);
}
return student1;
}
}
public interface Student1Service {
Student1 selectById(Integer id);
}
controller层
@RestController
@RequestMapping("student")
public class Student1Controller {
@Resource
private Student1Service student1Service;
@GetMapping("selectById/{id}")
public Student1 selectById(@PathVariable Integer id ){
return student1Service.selectById(id);
}
}
config层配置类
@Configuration
public class RedisConfig {
//比如验证码
@Bean //该方法的返回对象交于spring容器管理
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setConnectionFactory(factory);
//key序列化方式
template.setKeySerializer(redisSerializer);
//value序列化
template.setValueSerializer(jackson2JsonRedisSerializer);
//value hashmap序列化
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.setHashKeySerializer(redisSerializer);
return template;
}
}
mapper接口
@Mapper public interface Student1Mapper extends BaseMapper<Student1> { }