SpringBoot+Redis整合
一.操作Json
1.1 pom文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.17</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.2.2</version>
</dependency>
<!--redis依赖-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
</dependencies>
2.创建实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;
private String name;
private String pwd;
}
3.通用类
JedisPoolUtil
4.测试类
@Test
public void test01(){
Jedis jedis= JedisPoolUtils.getJedis();
User user=new User(1,"张三","666");
String jsonString = JSONObject.toJSONString(user);
//存数据擦操作
//设置数据到redis服务器
jedis.set("user:1",jsonString);
System.out.println(jedis.get("user:1"));
//从redis服务器取数据操作
//将字符串的格式转回Object类型;
//parseObject(json字符串,User.class);
User user2= JSONObject.parseObject(jedis.get("user:1"), User.class);
System.out.println(user2);
jedis.close();
jedis.close();
}
5.集合测试类
@Test
public void test02(){
Jedis jedis= JedisPoolUtils.getJedis();
List<User> userList = Arrays.asList(new User(2,"万凯","888"),new User(3,"tom","989"));
String jsonString = JSONArray.toJSONString(userList);
//存数据到redis服务器
jedis.set("userList",jsonString);
System.out.println(jedis.get("userList"));
//将字符串转回来;
String str=jedis.get("userList");
//从redis服务器取数据操作;
List<User>list= JSONArray.parseArray(str, User.class);
//lambda方式;
list.forEach(System.out::println);
//之前的操作方式
for (User user : userList2) {
System.out.println(user.getId()+"\t"+user.getName()+"\t"+user.getPwd());
}
jedis.close();
}
二.整合RedisTemplate
SpringData
JDBCTemplate
jedis客户端,存在如下不足:
- connection管理缺乏自动化,connection-pool的设计缺少必要的容器支持。
- 数据操作需要关注“序列化”/“反序列化”,因为jedis的客户端API接受的数据类型为string和byte,对结构化数据(json,xml,pojo等)操作需要额外的支持。
- 事务操作纯粹为硬编码。
- pub/sub功能,缺乏必要的设计模式支持,对于开发者而言需要关注的太多。
spring-data-redis针对jedis提供了如下功能:
-
1.连接池自动管理,提供了一个高度封装的“**RedisTemplate”**类
-
2.针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口
ValueOperations:String简单K-V操作 SetOperations:set类型数据操作 ZSetOperations:zset类型数据操作 HashOperations:针对map类型的数据操作 ListOperations:针对list类型的数据操作
-
3.提供了对key的“bound”(绑定)便捷化操作API,可以通过bound封装指定的key,然后进行一系列的操作而无须“显式”的再次指定Key,即
BoundKeyOperations BoundValueOperations BoundSetOperations BoundListOperations BoundSetOperations BoundHashOperations
-
4.将事务操作封装,有容器控制。
-
5.针对数据的“序列化/反序列化”,提供了多种可选择策略.
RedisTemplate中API使用
2.1增加jar包依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.17</version>
</parent>
<!-- data-redis依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
2.2 测试代码
编写启动类
@SpringBootApplication
public class RedisApp {
public static void main(String[] args) {
SpringApplication.run(RedisApp.class);
}
}
编写配置类
package com.yh.config;
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.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory){
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
//使用jackson进行序列化
Jackson2JsonRedisSerializer jsonRedisSerializer =
new Jackson2JsonRedisSerializer(Object.class);
//规定序列化规则
ObjectMapper objectMapper = new ObjectMapper();
/**
* 第一个参数指的是序列化的域,ALL指的是字段、get和set方法、构造方法
* 第二个参数指的是序列化哪些访问修饰符,默认是public,ANY指任何访问修饰符
*/
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//指定序列化输入的类型,类必须是非final修饰的类
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jsonRedisSerializer.setObjectMapper(objectMapper);
//序列化key value
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(jsonRedisSerializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(jsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
测试类
@RunWith(SpringRunner.class)
@SpringBootTest(classes = RedisApp.class)
public class Demo03 {
@Autowired
RedisTemplate<String,Object> redisTemplate;
/**
* 对redisTemplate的依赖
*/
@Test
public void test03(){
ValueOperations opsForValue = redisTemplate.opsForValue();
opsForValue.set("name","chenguang");
System.out.println(opsForValue.get("name"));
}
@Test
public void test04(){
User user=new User(5,"tomhs","tttt");
ValueOperations opsForValue = redisTemplate.opsForValue();
opsForValue.set("user"+user.getId(),user);
User u = (User) opsForValue.get("user" + user.getId());
System.out.println(u);
}
@Test
public void test05(){
List<User> userList = Arrays.asList(new User(2,"smith","99999"),new User(3,"king","kkkk"));
ValueOperations opsForValue = redisTemplate.opsForValue();
}
}
单对象格式:
列表格式:
三.布隆过滤器测试
布隆过滤器本质上是一种数据结构,是一种巧妙的概率型数据结构,用来高效的插入和查询.作用是用来告诉使用者某样东西一定不存在或者可能存在。使用多个哈希函数,将一个数据映射到位图结构中。
查询某个变量的时候,只要这些对应的点是否是都是1:
- 如果这些点有一个0,则被查询的变量一定不存在.
- 如果都是1,则被查询的变量可能存在
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
JAVA代码测试
private static int size = 1000000;//预计要插入多少数据
private static double fpp = 0.01;//期望的误判率
private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, fpp);
public static void main(String[] args) {
//插入数据
for (int i = 0; i < 1000000; i++) {
bloomFilter.put(i);
}
int count = 0;
for (int i = 1000000; i < 2000000; i++) {
if (bloomFilter.mightContain(i)) {
count++;
System.out.println(i + "误判了");
}
}
System.out.println("总共的误判数:" + count);
}
使用場景
布隆过滤器适用场景
1.网页爬虫中对URL的去重,避免爬取相同的URL地址
2.垃圾邮件过滤,从数十亿个垃圾邮件列表中判断邮箱是否是垃圾邮箱
3.秒杀系统,查看用户是否重复购买
4.数据库防止穿库。 Google Bigtable,HBase 和 Cassandra 以及 Postgresql 使用BloomFilter来减少不存在的行或列的磁盘查找。避免代价高昂的磁盘查找会大大提高数据库查询操作的性能。
业务场景中判断用户是否阅读过某视频或文章,比如抖音或头条,当然会导致一定的误判,但不会让用户看到重复的内容。
5.缓存宕机、缓存击穿场景,一般判断用户是否在缓存中,如果在则直接返回结果,不在则查询db,如果来一波冷数据,会导致缓存大量击穿,造成雪崩效应,这时候可以用布隆过滤器当缓存的索引,只有在布隆过滤器中,才去查询缓存,如果没查询到,则穿透到db。如果不在布隆器中,则直接返回。
标签:SpringBoot,Redis,jedis,user,整合,序列化,public,redisTemplate,User
From: https://blog.51cto.com/teayear/8348478