2023年7月24日发(作者:)
Mybatis⾃定义拦截器,实现拼接sql和修改1⼀、应⽤场景1.分页,如lper的分页插件实现;2.拦截sql做⽇志监控;3.统⼀对某些sql进⾏统⼀条件拼接,类似于分页。⼆、MyBatis的拦截器简介 然后我们要知道拦截器拦截什么样的对象,拦截对象的什么⾏为,什么时候拦截?然后我们要知道拦截器拦截什么样的对象,拦截对象的什么⾏为,什么时候拦截? 在Mybatis框架中,已经给我们提供了拦截器接⼝,防⽌我们改动源码来添加⾏为实现拦截。说到拦截器,不得不提⼀下,拦截器是通过动态代理对Mybatis加⼊⼀些⾃⼰的⾏为。拦截对象确⽴拦截对象范围:要拦对⼈,既要保证拦对⼈,⼜要保证对正确的⼈执⾏正确的拦截动作拦截地点 在Mybatis的源码中:Executor、StatementHandler拦截时机 如果mybatis为我们提供了拦截的功能,我们应该在Mybatis执⾏过程的哪⼀步拦截更加合适呢? 拦截某个对象⼲某件事的时候,拦截的时机要对,过早的拦截会耽误别⼈做⾃⼰的⼯作,拦截太晚达不到⽬的。 Mybatis实际也是⼀个JDBC执⾏的过程,只不过被包装起来了⽽已,我们要拦截Mybatis的执⾏,最迟也要在获取PreparedStatement时拦截:PreparedStatement statement = eStatement(ng()); 在此处偷偷的将sql语句换掉,就可以改变mybatis的执⾏,加⼊⾃⼰想要的执⾏⾏为。 ⽽获取Mybatis的Statement是在StatementHandler中进⾏的。三、代码⽰例第⼀步、引⼊依赖
###classpath就是应⽤程序resources的路径-aliases-package: 第三步、配置代码⽣成器,引⼊配置在pom中添加⼀下代码
(⽣成对应⽂件后,mybatis环境算是集成好了,可以运⾏⼀个测试类试试能否从数据库读取数据。)定义⼀个类实现Mybatis的Interceptor接⼝,@Component注解必须要添加,不然可能出现拦截器⽆效的情况import entHandler;
import ql;import Statement;import .*;import tReflectorFactory;import ject;import MetaObject;import ent;import ;import ;import tion;import ties;@Component@Intercepts({ @Signature( type = , method = "prepare", args = {, })})public class MySqlInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // ⽅法⼀ StatementHandler statementHandler = (StatementHandler) get(); MetaObject metaObject = ect(statementHandler,T_OBJECT_FACTORY,T_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory()); //先拦截到RoutingStatementHandler,⾥⾯有个StatementHandler类型的delegate变量,其实现类是BaseStatementHandler,然后就到BaseStatementHandler的成员变量mappedStatement MappedStatement mappedStatement = (MappedStatement)ue("Statement"); //id为执⾏的mapper⽅法的全路径名,如User String id = (); //sql语句类型 select、delete、insert、update String sqlCommandType = CommandType().toString(); BoundSql boundSql = ndSql(); //获取到原始sql语句 String sql = (); String mSql = sql; //TODO 修改位置 //注解逻辑判断 添加注解了才拦截 Class> classType = e(().substring(0,().lastIndexOf("."))); String mName = ().substring(().lastIndexOf(".") + 1,().length()); for (Method method : laredMethods()) { if (tationPresent() && (e())) { InterceptAnnotation interceptorAnnotation = otation(); if (()) { mSql = sql + " limit 2"; } } } //通过反射修改sql语句 Field field = ss().getDeclaredField("sql"); essible(true); (boundSql, mSql); return d(); } @Override public Object plugin(Object target) { if (target instanceof StatementHandler) { return (target, this); } else { return target; } } @Override public void setProperties(Properties properties) { }}此外,定义了⼀个⽅法层⾯的注解,实现局部指定拦截@Target({,TER})@Retention(E)public @interface InterceptAnnotation { boolean flag() default true;}最后只需要在指定的⽅法出添加注解就可以实现局部拦截最后运⾏看结果就好了。(按我的逻辑下来会只查到2条数据)在@Interceptor的注解中也有以下的注解⽅式,究竟有什么不同和差异,请⼤家⾃⼰研究咯,我就在此抛砖引⽟了,请各位⼤⽜指导了。@Intercepts(value = { @Signature(type = , method = "update", args = {, }), @Signature(type = , method = "query", args = {, , , , , }), @Signature(type = , method = "query", args = {, , , })})
发布者:admin,转转请注明出处:http://www.yc00.com/news/1690193057a312388.html
评论列表(0条)