mybatis拦截器开发(手写分页插件)

作用:深度定制mybatis的开发

场景:

1.需要干预Mybatis的SQL

2.需要统一的处理 多个Mappering文件

eg.分页(干预SQL,统一处理),乐观锁(版本对比)

3.一个业务,log业务日志

拦截器的基本开发:

1.编码

1)类implements Interceptor

2)类 标注 拦截目标:

 @Intercepts(
         @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
 )

拦截的是Executor(方法 + 参数),StatementHandler(方法 + 参数)

2.配置 mybtis-config.xml种配置

<plugins>
     <plugin interceptor="com.mybatis.interceptor.MyMybatisInterceptor"></plugin>
 </plugins>

MetaObject --> Mybatis底层封装的反射工具类,便于Mybatis中通过反射操作一个对象

手写分页插件:PageHelperInterceptor:

@Intercepts(
        @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
)
public class PageHelperInterceptor implements Interceptor {
    private String queryMethodPrefix;
    private String queryMethodSuffix;

    private static final Logger log = LoggerFactory.getLogger(PageHelperInterceptor.class);

    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        MetaObject metaObject = SystemMetaObject.forObject(invocation);
        String  sql = (String) metaObject.getValue("target.delegate.boundSql.sql");
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("target.delegate.mappedStatement");
        String id = mappedStatement.getId();
        if (id.indexOf(queryMethodPrefix) != -1 && id.endsWith(queryMethodSuffix)) {

//            Page page = new Page(1);

            Page page = (Page) metaObject.getValue("target.delegate.parameterHandler.parameterObject");

            String countSql = "select count(*) " + sql.substring(sql.indexOf("from"));
            //JDBC操作
            Connection connection = (Connection) invocation.getArgs()[0];
            PreparedStatement preparedStatement = connection.prepareStatement(countSql);
            //假如 select count(*) from user where name = #{name}
//            preparedStatement.setString(1,?);

            //用parameterHandler获取sql语句中的参数
            ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("target.delegate.parameterHandler");
            parameterHandler.setParameters(preparedStatement);
			
            ResultSet resultSet = preparedStatement.executeQuery();
            if (resultSet.next()){
                page.setTotalSize(resultSet.getInt(1));
                if (log.isInfoEnabled())
                    log.info("{}",resultSet.getInt(1));
            }

            sql = sql + " limit " + (page.getPageIndex() - 1) + "," + page.getPageCount();
            metaObject.setValue("target.delegate.boundSql.sql",sql);
        }
        if (log.isInfoEnabled()) {
            log.info("PageHelpInterceptor....{}",sql);
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target,this);
    }

    @Override
    public void setProperties(Properties properties) { 
        this.queryMethodPrefix = properties.getProperty("queryMethodPrefix");
        this.queryMethodSuffix = properties.getProperty("queryMethodSuffix"); 
    }
}

 对于Sql语句的操作我们可以使用JSqlparser,简化对sql语句的操作

 CCJSqlParserManager parserManager = new CCJSqlParserManager();
 Select select = (Select) parserManager.parse(new StringReader("select * from user where name = 'yht'"));
 PlainSelect selectBody = (PlainSelect) select.getSelectBody();
 //获取表名
 FromItem fromItem = selectBody.getFromItem();

JSqlparser依赖:

        <dependency>
            <groupId>com.github.jsqlparser</groupId>
            <artifactId>jsqlparser</artifactId>
            <version>4.3</version>
        </dependency>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值