• JavaEE——Mybatis(16)--MyBatis插件开发


    插件原理
    * 在四大对象创建的时候
    * 1、每个创建出来的对象不是直接返回的,而是
       interceptorChain.pluginAll(parameterHandler);
    * 2、获取到所有的Interceptor(拦截器)(插件需要实现的接口);
       调用interceptor.plugin(target);返回target包装后的对象
    * 3、插件机制,我们可以使用插件为目标对象创建一个代理对象;AOP(面向切面)
       我们的插件可以为四大对象创建出代理对象;
       代理对象就可以拦截到四大对象的每一个执行;

    public Object pluginAll(Object target) {
    	for (Interceptor interceptor : interceptors) {
    	    target = interceptor.plugin(target);
    	}
        return target;
    }
    

      

    插件编写:
    * 1、编写Interceptor的实现类  要实现Interceptor接口   implements Interceptor

    MyFirstPlugin类

    package com.atguigu.mybatis.dao;
    
    import java.util.Properties;
    
    import org.apache.ibatis.executor.parameter.ParameterHandler;
    import org.apache.ibatis.executor.statement.StatementHandler;
    import org.apache.ibatis.plugin.Interceptor;
    import org.apache.ibatis.plugin.Intercepts;
    import org.apache.ibatis.plugin.Invocation;
    import org.apache.ibatis.plugin.Plugin;
    import org.apache.ibatis.plugin.Signature;
    import org.apache.ibatis.reflection.MetaObject;
    import org.apache.ibatis.reflection.SystemMetaObject;
    
    /**
     * 完成插件签名:
     *		告诉MyBatis当前插件用来拦截哪个对象的哪个方法
     */
    @Intercepts(
    		{
    			@Signature(type=StatementHandler.class,method="parameterize",args=java.sql.Statement.class)
    		})
    public class MyFirstPlugin implements Interceptor{
    
    	/**
    	 * intercept:拦截:
    	 * 		拦截目标对象的目标方法的执行;
    	 */
    	@Override
    	public Object intercept(Invocation invocation) throws Throwable {
    		// TODO Auto-generated method stub
    		System.out.println("MyFirstPlugin...intercept:"+invocation.getMethod());
    		//动态的改变一下sql运行的参数:以前1号员工,实际从数据库查询3号员工
    		Object target = invocation.getTarget();
    		System.out.println("当前拦截到的对象:"+target);
    		//拿到:StatementHandler==>ParameterHandler===>parameterObject
    		//拿到target的元数据
    		MetaObject metaObject = SystemMetaObject.forObject(target);
    		Object value = metaObject.getValue("parameterHandler.parameterObject");
    		System.out.println("sql语句用的参数是:"+value);
    		//修改完sql语句要用的参数
    		metaObject.setValue("parameterHandler.parameterObject", 11);
    		//执行目标方法
    		Object proceed = invocation.proceed();
    		//返回执行后的返回值
    		return proceed;
    	}
    
    	/**
    	 * plugin:
    	 * 		包装目标对象的:包装:为目标对象创建一个代理对象
    	 */
    	@Override
    	public Object plugin(Object target) {
    		// TODO Auto-generated method stub
    		//我们可以借助Plugin的wrap方法来使用当前Interceptor包装我们目标对象
    		System.out.println("MyFirstPlugin...plugin:mybatis将要包装的对象"+target);
    		Object wrap = Plugin.wrap(target, this);
    		//返回为当前target创建的动态代理
    		return wrap;
    	}
    
    	/**
    	 * setProperties:
    	 * 		将插件注册时 的property属性设置进来
    	 */
    	@Override
    	public void setProperties(Properties properties) {
    		// TODO Auto-generated method stub
    		System.out.println("插件配置的信息:"+properties);
    	}
    
    }

    * 2、使用@Intercepts注解完成插件签名
    * 3、将写好的插件注册到全局配置文件中

    在mybatis_config.xml中注册插件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
     PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
     "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
    
    	<!--plugins:注册插件  -->
    	<plugins>
    		<plugin interceptor="com.atguigu.mybatis.dao.MyFirstPlugin">
    			<property name="username" value="root"/>
    			<property name="password" value="123456"/>
    		</plugin>
    		<plugin interceptor="com.atguigu.mybatis.dao.MySecondPlugin"></plugin>
    	</plugins>
    	<environments default="development">
    		<environment id="development">
    			<transactionManager type="JDBC" />
    			<dataSource type="POOLED">
    				<property name="driver" value="com.mysql.jdbc.Driver" />
    				<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
    				<property name="username" value="root" />
    				<property name="password" value="123456" />
    			</dataSource>
    		</environment>
    	</environments>
    	<!-- 将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中 -->
    	<mappers>
    		<mapper resource="EmployeeMapper.xml" />
    	</mappers>
    </configuration>
    

      

    开发插件

    如:动态改变sql运行的参数

    @Override
    	public Object intercept(Invocation invocation) throws Throwable {
    		// TODO Auto-generated method stub
    		System.out.println("MyFirstPlugin...intercept:"+invocation.getMethod());
    		//动态的改变一下sql运行的参数:以前1号员工,实际从数据库查询3号员工
    		Object target = invocation.getTarget();
    		System.out.println("当前拦截到的对象:"+target);
    		//拿到:StatementHandler==>ParameterHandler===>parameterObject
    		//拿到target的元数据
    		MetaObject metaObject = SystemMetaObject.forObject(target);
    		Object value = metaObject.getValue("parameterHandler.parameterObject");
    		System.out.println("sql语句用的参数是:"+value);
    		//修改完sql语句要用的参数
    		metaObject.setValue("parameterHandler.parameterObject", 11);
    		//执行目标方法
    		Object proceed = invocation.proceed();
    		//返回执行后的返回值
    		return proceed;
    	}
    

      

  • 相关阅读:
    回调函数案例(二)
    回调函数案例(一)
    liteos学习文档liteos.github.io
    HeapAlloc、GlobalAlloc和new等内存分配有什么区别么?
    C语言中字符数组和字符串指针分析
    socket 连接,使得地址马上可以重用
    shutdown 和closesocket
    IP地址转换成Long型数字的算法
    WSAStartup( )
    关于完成端口IOCP异步接收连接函数AcceptEx注意事项
  • 原文地址:https://www.cnblogs.com/SkyeAngel/p/8490506.html
Copyright © 2020-2023  润新知