欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

mybaties二级缓存全网最强解决方案

程序员文章站 2022-04-13 17:43:26
...

mybaties二级缓存全网最强解决方案

拦截器方式解决

直接上代码

@Intercepts({
        @Signature(method = "query", type = Executor.class, args = {MappedStatement.class, Object.class,
                RowBounds.class, ResultHandler.class}),
        @Signature(method = "prepare", type = StatementHandler.class, args = {Connection.class})})
public class MyPlugin implements Interceptor {

    private String databaseType;//数据库类型,不同的数据库有不同的分页方法

    private RedisTemplate<String, Object> redisTemplate = SpringContextHolder.getBean("redisTemplate");

    //方法拦截
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        //通过StatementHandler获取执行的sql
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
        MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");
        String selectId = mappedStatement.getId();
        BoundSql boundSql = statementHandler.getBoundSql();
        String sql = boundSql.getSql();
        if (checkSql(sql)) {
            try {
                Set<TableStat.Name> nameSet = sqlParser(sql);
                nameSet.stream().forEach(t -> {
                    Set<String> keys = redisTemplate.keys("*:*" + t + "*");
                    if (!CollectionUtils.isEmpty(keys)) {
                        redisTemplate.delete(keys);
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return invocation.proceed();
    }
/**
     * sql解析器
     *
     * @param sql
     * @return
     */
    public static Set<TableStat.Name> sqlParser(String sql) {

        // 新建 MySQL Parser
        SQLStatementParser parser = new MySqlStatementParser(sql);

        // 使用Parser解析生成AST,这里SQLStatement就是AST
        SQLStatement statement = parser.parseStatement();

        // 使用visitor来访问AST
        MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
        statement.accept(visitor);

        // 从visitor中拿出你所关注的信息
        // System.out.println(visitor.getColumns());
        Set<TableStat.Name> table = visitor.getTables().keySet();
        //System.out.println(visitor.getTables().keySet());

        return table;
    }


    public boolean checkSql(String sql) {
        return sql.toUpperCase().contains("DELETE") || sql.toUpperCase().contains("INSERT") || sql.toUpperCase().contains("UPDATE");
    }