初始化布隆过滤器
/**
* 启动时候将产品加入到 布隆过滤器中
*/
@PostConstruct
public void init() {
bloomFilter = redissonClient.getBloomFilter(BLOOM_STR, new JsonJacksonCodec());
this.refreshBloom();
}
@Override
public void refreshBloom() {
bloomFilter.delete();
//初始化布隆过滤器:预计元素为 1000000L (这个值根据实际的数量进行调整),误差率为3%
bloomFilter.tryInit(1000000L, 0.03);
List<Integer> productIdList = this.list(new LambdaQueryWrapper<Product>().select(Product::getId))
.stream().map(Product::getId).collect(Collectors.toList());
productIdList.forEach(bloomFilter::add);
}
controller层
@Resource
ProductService productService;
/**
* 根据 id 查询详情
*
* @param id id
* @return json string
*/
@GetMapping("/{id}")
public String getProduct(@PathVariable Integer id) {
Product product = productService.getProductById(id);
if (BeanUtil.isEmpty(product)) {
return "暂无该产品!";
}
return JSONUtil.toJsonStr(product);
}
/**
* 添加产品
*
* @param product 产品
* @return boolean
*/
@PostMapping("/add")
public Boolean addProduct(@RequestBody Product product) {
try {
return productService.addProduct(product);
} catch (Exception e) {
log.error("异常:",e);
throw new RuntimeException(e);
}
}
/**
* 根据id删除产品
*
* @param product 产品
* @return boolean
*/
@DeleteMapping("/{id}")
public Boolean delProduct(@PathVariable Integer id) {
return productService.removeById(id);
}
service层
查询
private static final String BLOOM_STR = "product_list_bloom";
private static final String REDIS_CACHE = "product_list";
@Resource
RedissonClient redissonClient;
RBloomFilter<Integer> bloomFilter;
@Override
public Product getProductById(Integer id) {
// 走布隆过滤器筛选一下,防止被缓存穿透
boolean contains = bloomFilter.contains(id);
// 如果布隆过滤器判断当前产品id 存在,则去查询数据库
if (contains) {
// 先去缓存中查
log.info("正在redis缓存中查询:{}",id);
RMap<Integer, String> productCache = redissonClient.getMap(REDIS_CACHE);
String cacheProduct = productCache.get(id);
if (StrUtil.isNotEmpty(cacheProduct)) {
// 如果缓存中不是空 则返回
return JSONUtil.toBean(cacheProduct, Product.class);
}
Product product = this.getById(id);
// 如果查到了数据,那么存一份到 redis 中去
if (BeanUtil.isNotEmpty(product)) {
productCache.put(id, JSONUtil.toJsonStr(product));
return product;
}
} else {
log.info("布隆过滤器中不存在产品id:{}的数据", id);
}
return null;
}
添加:
/**
* 添加产品
*
* @param product 产品
* @return boolean
*/
@PostMapping("/add")
public Boolean addProduct(@RequestBody Product product) {
try {
return productService.addProduct(product);
} catch (Exception e) {
log.error("异常:",e);
throw new RuntimeException(e);
}
}
import com.baomidou.mybatisplus.extension.service.IService;
import top.bulk.bloom.entity.Product;
/**
* 产品demo(Product)表服务接口
*
* @author wanglu
* @since 2022-12-08 18:00:14
*/
public interface ProductService extends IService<Product> {
/**
* 查询产品详情
*
* @param id id
* @return product
*/
Product getProductById(Integer id);
/**
* 添加产品操作
*
* @param product 产品信息
* @return 返回
*/
Boolean addProduct(Product product);
/**
* 清空 布隆过滤器中的数据,然后重新添加
* 删除后,重新添加
*/
void refreshBloom();
}
实体层:
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 产品demo(Product)表实体类
*
* @author wanglu
* @since 2022-12-08 18:00:11
*/
@Data
public class Product implements Serializable {
/**
* 主键
**/
private Integer id;
/**
* 名称
**/
private String productName;
/**
* 价钱
**/
private Double productPrice;
/**
* 数量
**/
private Integer productNum;
/**
* 添加时间
**/
@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss") // 表示返回时间类型
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") // 表示接收时间类型
private LocalDateTime addTime;
/**
* 创建人
**/
private String addBy;
/**
* 更新时间
**/
@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss") // 表示返回时间类型
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") // 表示接收时间类型
private Date updateTime;
/**
* 更新人
**/
private String updateBy;
}
mapper层
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import top.bulk.bloom.entity.Product;
/**
* 产品demo(Product)表数据库访问层
*
* @author wanglu
* @since 2022-12-08 18:00:10
*/
public interface ProductMapper extends BaseMapper<Product> {
}