springboot+redis+mybatis体会布隆过滤器

2024-08-31 06:28

本文主要是介绍springboot+redis+mybatis体会布隆过滤器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.建立数据库表和对应实体类

CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`uname` varchar(50) DEFAULT NULL,`usex` varchar(20) DEFAULT NULL,`uage` int(11) DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1319 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
public class User {private String id;private String uname;private String usex;private String uage;public String getUname() {return uname;}public void setUname(String uname) {this.uname = uname;}public String getUsex() {return usex;}public void setUsex(String usex) {this.usex = usex;}public String getUage() {return uage;}public void setUage(String uage) {this.uage = uage;}public String getId() {return id;}public void setId(String id) {this.id = id;}
}

2.编写Controller,新增用户和获取用户

@Controller
public class BloomController {@Autowiredprivate BloomService bloomService;@RequestMapping(value = "/addUser")@ResponseBodypublic void addUser(){for(int i=0;i<100;i++){User user = new User();user.setUsex(i + "");user.setUname("user:" + i);user.setUage("26");bloomService.addUser(user);}}@RequestMapping(value = "/getUser")@ResponseBodypublic User getUser(HttpServletRequest request){String userId = request.getParameter("userId");User user = bloomService.getUser(userId);return  user;}}

3.编写servie,实现具体的业务逻辑

public interface BloomService {void addUser(User user);User getUser(String userId);List<String> getUserIds();
}
@Service
public class BloomServiceImpl implements BloomService {public static final String redisKey = "USER:";@Resourceprivate BloomDao bloomDao;@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate BloomCheckUtil bloomCheckUtil;@Overridepublic void addUser(User user) {int i = bloomDao.addUser(user);if(i>0){//mysql插入成功,将数据存入redisUser currentUser = bloomDao.getUser(user.getId());redisTemplate.opsForValue().set(redisKey+user.getId(), JSONObject.toJSONString(currentUser));}}@Overridepublic User getUser(String userId) {User user = null;//1.先从布隆过滤器中获取数据,若没有则直接返回if(!bloomCheckUtil.check(userId)){System.out.println("该用户id:" + userId +"不在合法用户内!!!!");return user;}//2.从redis中查找String rediskey = redisKey + userId;String jsonObj = Optional.ofNullable(redisTemplate.opsForValue().get(rediskey)).map(Object::toString).orElse(null);if(jsonObj == null){//3.redis中没有,查询数据库user = bloomDao.getUser(userId);if(user != null){//4.redis无mysql有,把查询出的数据写入到redis缓存redisTemplate.opsForValue().set(rediskey,JSONObject.toJSONString(user));}return user;}user =JSONObject.parseObject(jsonObj, User.class) ;return user;}@Overridepublic List<String> getUserIds() {return bloomDao.getUserIds();}
}

4.编写dao和mapper,实现数据库操作

public interface BloomDao {int addUser(@Param("user") User user);User getUser(@Param("id")String id);List<String> getUserIds();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.cn.study.redis.dao.BloomDao"><insert id="addUser"  parameterType="com.cn.study.redis.pojo.User" useGeneratedKeys="true" keyProperty="id">insert into user(uname,usex,uage) values (#{user.uname},#{user.usex},#{user.uage})</insert><select id="getUser" resultType="com.cn.study.redis.pojo.User">select u.id ,u.uname ,u.usex ,u.uage  from user u where u.id = #{id}</select><select id="getUserIds" resultType="String">select id from user</select>
</mapper>

5.编写布隆过滤器和工具类

@Component
public class BloomFilter {public static final String key = "LEGITIMATE_USER";@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate BloomService bloomService;@PostConstructpublic void init(){//初始化布隆过滤器//1.从数据库查出user表中的所有id,计算hash值List<String> userIdList = bloomService.getUserIds();for(int i=0;i<userIdList.size();i++){//对每个userId计算hash值并取绝对值int hashValue = Math.abs(("USER:" + userIdList.get(i)).hashCode());//使用hash值对2的32次方取余,得到下标long index = (long)(hashValue % Math.pow(2,32));System.out.println("id为:" + userIdList.get(i)+"的用户产生的hash值为:" + hashValue +",下标为:" + index);//将redis中对应下标的bitmap的值更新成1redisTemplate.opsForValue().setBit(key,index,true);}}
}
@Component
public class BloomCheckUtil {private static final String key = "LEGITIMATE_USER";@Autowiredprivate RedisTemplate redisTemplate;public boolean check(String userId){boolean flag = false;int hashValue = Math.abs(("USER:" + userId).hashCode());long index = (long)(hashValue % Math.pow(2,32));flag = redisTemplate.opsForValue().getBit(key,index);return flag;}}

7.验证

由于第一次启动项目的时候,BloomFilter 类中的init方法会在一开始执行,此时我还并没有调用addUser方法添加用户,数据库中没有任何用户信息,所以第一次启动项目的时候,布隆过滤器中不会有任何的数据。
我们启动项目后,手动调用下addUser方法,新增100条用户数据。
然后重启项目,将用户信息加载到布隆过滤器中。
我们调用getUser方法尝试获取用户信息,当我们传了一个数据库不存在的用户id时,当请求到布隆过滤器,布隆过滤器发现没有此数据,则直接返回,不会再往下查redis和mysql
在这里插入图片描述

这篇关于springboot+redis+mybatis体会布隆过滤器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1123137

相关文章

Java实现Excel与HTML互转

《Java实现Excel与HTML互转》Excel是一种电子表格格式,而HTM则是一种用于创建网页的标记语言,虽然两者在用途上存在差异,但有时我们需要将数据从一种格式转换为另一种格式,下面我们就来看看... Excel是一种电子表格格式,广泛用于数据处理和分析,而HTM则是一种用于创建网页的标记语言。虽然两

java图像识别工具类(ImageRecognitionUtils)使用实例详解

《java图像识别工具类(ImageRecognitionUtils)使用实例详解》:本文主要介绍如何在Java中使用OpenCV进行图像识别,包括图像加载、预处理、分类、人脸检测和特征提取等步骤... 目录前言1. 图像识别的背景与作用2. 设计目标3. 项目依赖4. 设计与实现 ImageRecogni

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

Java访问修饰符public、private、protected及默认访问权限详解

《Java访问修饰符public、private、protected及默认访问权限详解》:本文主要介绍Java访问修饰符public、private、protected及默认访问权限的相关资料,每... 目录前言1. public 访问修饰符特点:示例:适用场景:2. private 访问修饰符特点:示例:

详解Java如何向http/https接口发出请求

《详解Java如何向http/https接口发出请求》这篇文章主要为大家详细介绍了Java如何实现向http/https接口发出请求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用Java发送web请求所用到的包都在java.net下,在具体使用时可以用如下代码,你可以把它封装成一

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.