【学习笔记】mybatis自定义插件案例代码
文章目錄
- 插件介紹
- 案例
- 實(shí)體類:
- 定義插件:
- 測(cè)試:
插件介紹
插件是MyBatis提供的一個(gè)非常強(qiáng)大的機(jī)制,我們可以通過(guò)插件來(lái)修改MyBatis的一些核心行為。插件通過(guò)動(dòng)態(tài)代理機(jī)制,可以介入四大對(duì)象的任何一個(gè)方法的執(zhí)行
四大對(duì)象:
?Executor(update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
?ParameterHandler(getParameterObject, setParameters)
?ResultSetHandler(handleResultSets, handleOutputParameters)
?StatementHandler(prepare, parameterize, batch, update, query)
案例
新建mybatis配置文件,在配置中注冊(cè)插件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><!--plugins:注冊(cè)插件 --><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="mybatis" /><property name="password" value="123456" /></dataSource></environment></environments><!-- 將我們寫好的sql映射文件(EmployeeMapper.xml)一定要注冊(cè)到全局配置文件(mybatis-config.xml)中 --><mappers><mapper resource="EmployeeMapper.xml" /></mappers> </configuration>實(shí)體類:
@Data public class Employee {private Integer id;private String lastName;private String email;private String gender;}定義插件:
@Intercepts({@Signature(type=StatementHandler.class,method="parameterize",args=java.sql.Statement.class)//這里的args是發(fā)給發(fā)參數(shù)的意思,防止方法重載}) public class MyFirstPlugin implements Interceptor{/*** intercept:攔截:* 攔截目標(biāo)對(duì)象的目標(biāo)方法的執(zhí)行;*/@Overridepublic Object intercept(Invocation invocation) throws Throwable {// TODO Auto-generated method stubSystem.out.println("MyFirstPlugin...intercept:"+invocation.getMethod());//動(dòng)態(tài)的改變一下sql運(yùn)行的參數(shù):以前1號(hào)員工,實(shí)際從數(shù)據(jù)庫(kù)查詢3號(hào)員工Object target = invocation.getTarget();System.out.println("當(dāng)前攔截到的對(duì)象:"+target);//拿到:StatementHandler==>ParameterHandler===>parameterObject//拿到target的元數(shù)據(jù)MetaObject metaObject = SystemMetaObject.forObject(target);Object value = metaObject.getValue("parameterHandler.parameterObject");System.out.println("sql語(yǔ)句用的參數(shù)是:"+value);//修改完sql語(yǔ)句要用的參數(shù)metaObject.setValue("parameterHandler.parameterObject", 11);//執(zhí)行目標(biāo)方法Object proceed = invocation.proceed();//返回執(zhí)行后的返回值return proceed;}/*** plugin:* 包裝目標(biāo)對(duì)象的:包裝:為目標(biāo)對(duì)象創(chuàng)建一個(gè)代理對(duì)象*/@Overridepublic Object plugin(Object target) {// TODO Auto-generated method stub//我們可以借助Plugin的wrap方法來(lái)使用當(dāng)前Interceptor包裝我們目標(biāo)對(duì)象System.out.println("MyFirstPlugin...plugin:mybatis將要包裝的對(duì)象"+target);Object wrap = Plugin.wrap(target, this);//返回為當(dāng)前target創(chuàng)建的動(dòng)態(tài)代理return wrap;}/*** setProperties:* 將插件注冊(cè)時(shí) 的property屬性設(shè)置進(jìn)來(lái)*/@Overridepublic void setProperties(Properties properties) {// TODO Auto-generated method stubSystem.out.println("插件配置的信息:"+properties);}}其中 StatementHandler 接口類的源碼:
public interface StatementHandler {Statement prepare(Connection var1, Integer var2) throws SQLException;void parameterize(Statement var1) throws SQLException; ....}其中 可以看到parameterize方法的參數(shù)是Statement
而實(shí)現(xiàn)類 SimpleStatementHandler的parameterize方法是一個(gè)空方法:
public void parameterize(Statement statement) throws SQLException {}MyFirstPlugin 與 MySecondPlugin基本一模一樣就不粘貼了。
public interface EmployeeMapper {public Employee getEmpById(Integer id);}測(cè)試:
/*** 1、獲取sqlSessionFactory對(duì)象:* 解析文件的每一個(gè)信息保存在Configuration中,返回包含Configuration的DefaultSqlSession;* 注意:【MappedStatement】:代表一個(gè)增刪改查的詳細(xì)信息* * 2、獲取sqlSession對(duì)象* 返回一個(gè)DefaultSQlSession對(duì)象,包含Executor和Configuration;* 這一步會(huì)創(chuàng)建Executor對(duì)象;* * 3、獲取接口的代理對(duì)象(MapperProxy)* getMapper,使用MapperProxyFactory創(chuàng)建一個(gè)MapperProxy的代理對(duì)象* 代理對(duì)象里面包含了,DefaultSqlSession(Executor)* 4、執(zhí)行增刪改查方法* * 1、根據(jù)配置文件(全局,sql映射)初始化出Configuration對(duì)象* 2、創(chuàng)建一個(gè)DefaultSqlSession對(duì)象,* 他里面包含Configuration以及* Executor(根據(jù)全局配置文件中的defaultExecutorType創(chuàng)建出對(duì)應(yīng)的Executor)* 3、DefaultSqlSession.getMapper():拿到Mapper接口對(duì)應(yīng)的MapperProxy;* 4、MapperProxy里面有(DefaultSqlSession);* 5、執(zhí)行增刪改查方法:* 1)、調(diào)用DefaultSqlSession的增刪改查(Executor);* 2)、會(huì)創(chuàng)建一個(gè)StatementHandler對(duì)象。* (同時(shí)也會(huì)創(chuàng)建出ParameterHandler和ResultSetHandler)* 3)、調(diào)用StatementHandler預(yù)編譯參數(shù)以及設(shè)置參數(shù)值;* 使用ParameterHandler來(lái)給sql設(shè)置參數(shù)* 4)、調(diào)用StatementHandler的增刪改查方法;* 5)、ResultSetHandler封裝結(jié)果* 注意:* 四大對(duì)象每個(gè)創(chuàng)建的時(shí)候都有一個(gè)interceptorChain.pluginAll(parameterHandler);* * @throws IOException*/@Testpublic void test01() throws IOException {// 1、獲取sqlSessionFactory對(duì)象SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();// 2、獲取sqlSession對(duì)象SqlSession openSession = sqlSessionFactory.openSession();try {// 3、獲取接口的實(shí)現(xiàn)類對(duì)象//會(huì)為接口自動(dòng)的創(chuàng)建一個(gè)代理對(duì)象,代理對(duì)象去執(zhí)行增刪改查方法EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);Employee employee = mapper.getEmpById(1);System.out.println(mapper);System.out.println(employee);} finally {openSession.close();}}結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的【学习笔记】mybatis自定义插件案例代码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: springcloudstream+ra
- 下一篇: 一些题目以及答案