zoukankan      html  css  js  c++  java
  • Mybatis核心对象及插件使用

    1,核心对象


    Configuration: mybatis的核心配置类,里面维护了mybatis的各种属性。

    Sqlsession: 一个会话,里面定义了各种操作数据库的方法,和应用层交互。

    Executor: Mybatis执行器,负责生成Sql和查询缓存。

    StatementHanler: 负责对JDBC Statement的操作,例如设置参数。

    ParameterHandler: 负责将用户参数转换为JDBC Statement需要的参数。

    ResultSetHandler: 负责数据库返回的对象转化为Java需要的。

    MapperProxy: mapper接口的代理对象。

    MapperStatement: 对一个(select|update|delete|insert)节点的封装,里面包含了sql语句,出参,入参等一些参数。

    2,插件原理与自定义插件


    如果我们想对原代码进行功能上的增强,那么我想到代理模式,mybatis中只有四个对象允许被代理拦截,Executor,StatementHanler,ParameterHandler,ResultSetHandler

    2.1,以PageHelpher为例,分析开发插件的流程


    2.1.1,实现Interceptor接口,在上面加上@Intercepts注解,指定拦截的类和方法(方法名称和参数类型构成了一个方法的签名),实现接口的三个方法。
                intercept():覆盖被拦截对象的原有的方法
                plugin():给被拦截对象生成一个代理对象。


    2.1.2,在mybatis-config.xml中注册插件

    2.2.3,登记插件

        mybatis启动时,扫描<plugin>标签,注册到了Configuration对象中的InterceptorChain中,property里面的参数会调用setProperties方法处理。

    3.1,代理和拦截的实现


    3.1.1,四大对象什么时候被代理的?

        Executor在openSession的时候,另外三个在SimpleExecutor调用doQuery的时候创建的。然后使用interceptorChain.pluginAll返回层层代理的对象。
        statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
        parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
        resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
        executor = (Executor) interceptorChain.pluginAll(executor);

    3.1.2,多个插件的情况下,代理能不能被代理,代理顺序和调用顺序的关系?

        代理可以被代理,代理顺序是从内到外,调用顺序是从外到内。

    3.1.3,谁来创建代理对象?

        Plugin类,Plugin.wrap方法返回代理对象

    3.1.4,被代理后,调用的是什么方法?怎么调用到原来被代理对象的方法?
        
        举例Executor被自己写的一个拦截器(MyInterceptor)拦截
        第一步:target = interceptor.plugin(target); MyInterceptor会调用Plugin.wrap返回一个代理对象。
        第二步:当执行Executor的具体的方法的时候,其实执行的是Plugin中的invoke方法,里面用Invocation对被代理对象进行了封装。 return interceptor.intercept(new Invocation(target, method, args));
        第三步:调用MyInterceptor中的intercept方法,接着进行我们的处理,最后我们可以调用Invocation中的process方法,执行原来对象的方法。
        public Object proceed() throws InvocationTargetException, IllegalAccessException {
            return method.invoke(target, args);
        }

    3.2,应用场景分析

        水平分表:对query方法进行拦截,在接口上添加注解,获取注解上的参数进行分表,修改原Sql,例如id取模,按月分表
        数据加解密:query解密,update加密。
        菜单权限控制:对query方法拦截,获取方法上面的注解,根据权限配置以及用户登录信息,在Sql上加上权限过滤条件。





  • 相关阅读:
    python脚本 – 删除指定天数前的文件
    java 获取屏幕的分辩率
    解决Multi input/output stream coders are not yet supported(org.apache.commons.compress)
    解决tomcat at org.apache.tomcat.util.buf.CharChunk.append(CharChunk.java:355)
    org.quartz.jobStore.misfireThreshold = 60000
    python list 自定义排序
    利用pycron在windows上实现cron定时任务
    [Selenium+Java] Scroll UP or Down a page in Selenium Webdriver
    Python获取硬件信息(硬盘序列号,CPU序列号)
    ChromeDriver自动更新、FirefoxDriver自动更新、InternetExplorerDriver自动更新(Java+Python)
  • 原文地址:https://www.cnblogs.com/gaojf/p/12894798.html
Copyright © 2011-2022 走看看