SSM笔记-插件开发

1、作用:通过拦截mybatis的四大对象,并且对其数据进行处理,达到对指定数据进行修改的效果

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

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

3、插件编写:
①编写Interceptor的实现类
②使用@Intercepts注解完成插件签名
③将写好的插件注册到全局配置文件中

4、mybatis.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>

	<properties resource="dbConfig.properties"></properties>

	<!--plugins:注册插件  -->
	<plugins>
		<plugin interceptor="com.demo.ssmtest.TestingPlugin"></plugin>
	</plugins>

	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	
	<mappers>
		<mapper resource="InfoMapper.xml" />
	</mappers>
</configuration>

5、InfoMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.demo.ssmtest.InfoMapper">
	<select id="getById"  resultType="com.demo.ssmtest.Info">
		select * from info where id = #{id}
	</select>
</mapper>

6、dbConfig.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/mybatis
jdbc.username=root
jdbc.password=

7、Info.java

package com.demo.ssmtest;


public class Info {

	Integer id;
	String name;
	String password;
	String description;
	
	public Info() {
		super();
	}
	
	public Info(Integer id, String name, String password, String description) {
		super();
		this.id = id;
		this.name = name;
		this.password = password;
		this.description = description;
	}

	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	@Override
	public String toString() {
		return "Info [id=" + id + ", name=" + name + ", password=" + password + ", description=" + description + "]";
	}
}

8、InfoMapper.java

package com.demo.ssmtest;

public interface InfoMapper {

	public Info getById(int id);
	
}

9、TestingPlugin.java

package com.demo.ssmtest;

import java.util.Properties;

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;

@Intercepts(
		{
			@Signature(type=StatementHandler.class,method="parameterize",args=java.sql.Statement.class)
		})
public class TestingPlugin implements Interceptor{

	/**
	 * intercept:拦截:
	 * 		拦截目标对象的目标方法的执行;
	 */
	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		System.out.println("TestingPlugin...intercept:"+invocation.getMethod());
		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("当前拦截到参数是:"+value);
		//修改元数据的参数值
		metaObject.setValue("parameterHandler.parameterObject", 11);
		//执行目标方法
		Object proceed = invocation.proceed();
		//返回执行后的返回值
		return proceed;
	}

	/**
	 * plugin:
	 * 		包装目标对象的:包装:为目标对象创建一个代理对象
	 */
	@Override
	public Object plugin(Object target) {
		//我们可以借助Plugin的wrap方法来使用当前Interceptor包装我们目标对象
		System.out.println("TestingPlugin...plugin:mybatis将要包装的对象"+target);
		Object wrap = Plugin.wrap(target, this);
		//返回为当前target创建的动态代理
		return wrap;
	}

	/**
	 * setProperties:
	 * 		将插件注册时 的property属性设置进来
	 */
	@Override
	public void setProperties(Properties properties) {
		System.out.println("插件配置的信息:"+properties);
	}

}

10、TestMain.java

package com.demo.ssmtest;

import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class TestMain {

	public static void main(String[] args) throws Exception {
		test();
	}

	/**
	 * 插件原理
	 * 在四大对象创建的时候
	 * 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的实现类
	 * 2、使用@Intercepts注解完成插件签名
	 * 3、将写好的插件注册到全局配置文件中
	 * 
	 */
	public static void test() throws Exception {

		String resource = "mybatis.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		
		SqlSession openSession = sqlSessionFactory.openSession();
		try {
			InfoMapper queryMapper = openSession.getMapper(InfoMapper.class);
			Info info = queryMapper.getById(1);
			System.out.println(info);
		} finally {
			openSession.close();
		}

	}
	
}

11、项目目录
项目目录

12、demo
https://download.csdn.net/download/qq_22778717/10719610

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值