阅读量:0
- 首先自定义一个mybatis的拦截器,实现Interceptor接口。
- 重写intercept方法。
- 在intercept方法里面通过invocation获取到QueryWrapper。
- 通过QueryWrapper的getParamNameValuePairs方法获取查询条件参数。
- 注意在Executor阶段,出现getParamNameValuePairs为空的情况,需要显示调用一次getCustomSqlSegment后,参数才会被填充到
paramNameValuePairs
中。 - 然后使用guava库,实现布隆过滤器。
- 自定义一个配置类,在配置类里面set方法注入Mapper,通过Mapper一次查询所有key添加到布隆过滤器。
- 之后的每次查询都会先使用布隆过滤器判断是否存在,否则直接返回。
- 这里我返回的是ArrayList<?>,?是一个实体类对应一张mysql表。
- 返回的是ArrayList<?>集合还需要创建一个?实例。
- 如果key存在,在判断是否命中缓存,使用的redis做缓存
- redis缓存的数据,必须序列化成字符串或者字节数组
package com.example.Interceptor; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.example.config.MyConfiguration; import com.example.domain.Emp; import com.example.util.CacheKeyGenerator; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.*; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import java.io.*; import java.util.ArrayList; import java.util.Map; import java.util.Properties; @Intercepts({@Signature( type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class} )}) public class CacheInterceptor implements Interceptor { @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { } public static byte[] serialize(Object obj) throws IOException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(obj); return byteArrayOutputStream.toByteArray(); } private static JedisPool pool; static { System.out.println("static...."); // 配置连接池 JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(30); // 最大连接数 poolConfig.setMaxIdle(10); // 最大空闲连接数 poolConfig.setMinIdle(5); // 最小空闲连接数 poolConfig.setTestOnBorrow(true); // 借用连接时进行连接测试 poolConfig.setTestOnReturn(true); // 归还连接时进行连接测试 poolConfig.setTestWhileIdle(true); // 空闲时进行连接测试 poolConfig.setMinEvictableIdleTimeMillis(60000); // 逐出连接的最小空闲时间 poolConfig.setTimeBetweenEvictionRunsMillis(30000); // 逐出扫描的时间间隔 // 创建连接池 pool = new JedisPool(poolConfig, "localhost", 6379); } @Override public Object intercept(Invocation invocation) throws Throwable { System.out.println("intercept...."); Map<?, ?> arg = ( Map<?, ?>) invocation.getArgs()[1]; System.out.println(arg); Map<String, Object> paramNameValuePairs=null; Long id=null; for (Object entry : arg.values()) { if(entry!=null) { QueryWrapper<?> queryWrapper_emp = (QueryWrapper<?>) entry; System.out.println(queryWrapper_emp.getCustomSqlSegment()); paramNameValuePairs = queryWrapper_emp.getParamNameValuePairs(); System.out.println(paramNameValuePairs); id = (Long) paramNameValuePairs.get("MPGENVAL1"); System.out.println(id); if(!MyConfiguration.bloomFilter.mightContain(Math.toIntExact(id))){ System.out.println("不存在"); ArrayList<Emp> objects = new ArrayList<>(); objects.add(new Emp()); return objects; } System.out.println("paramNameValuePairs=" + paramNameValuePairs); } break; } String generateKey = CacheKeyGenerator.generateKey(paramNameValuePairs); Jedis jedis=null; try { jedis= pool.getResource(); byte[] generateKeybytes = jedis.get(generateKey.getBytes()); if(generateKeybytes!=null){ Object deserialize = deserialize(generateKeybytes); System.out.println("命中"); return deserialize; }else{ System.out.println("未命中"); Object proceed = invocation.proceed(); jedis.set(generateKey.getBytes(),serialize(proceed)); return proceed; } }catch (Exception e){ e.printStackTrace(); }finally { jedis.close(); } return null; } // 反序列化对象 public static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException { ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); return objectInputStream.readObject(); } }
package com.example.config; import com.example.domain.Emp; import com.example.mapper.EmpMapper; import com.google.common.hash.BloomFilter; import com.google.common.hash.Funnels; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import java.util.Iterator; import java.util.List; @Configuration public class MyConfiguration { public static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), 10000, 0.01); @Autowired public void setEmpMapper(EmpMapper empMapper){ List<Emp> emps = empMapper.selectList(null); Iterator<Emp> iterator = emps.iterator(); while (iterator.hasNext()){ Emp next = iterator.next(); bloomFilter.put(Math.toIntExact(next.getId())); } System.out.println(bloomFilter.mightContain(3214044)); System.out.println(bloomFilter.mightContain(7213478)); } }