Mybatis插件开发

My Batis 允许在己映射语句执行过程中的某一点进行拦截调用。默认情况下, MyBatis 允许 使用插件来拦截的接口和方法包括以下几个。
• Executor ( update 、 query 、 flushStatements 、 commit 、 rollback 、 get Transaction、 close、 isClosed)
• ParameterHandler ( getParameterObj ect、 setParameters)
• ResultSetHandler ( handleResul tSets 、 handleCursorResultSets 、 handleOutputParameters)
• StatementHandler (prepare、 parameterize、 batch、 update、 query)


拦截器接口


MyBatis插件可以用来实现拦截器接口,在实现类中对拦截对象和方法进行处理
Interceptor 接口代码

	public interface Interceptor {
		Object intercept(Invocation invocation) throws Throwable; 
		Object plugin(Object target) ; 
		void setProperties(Properties properties);
	}

mybatis-config.xml

<plugins>
	<plugin interceptor="tk.mybatis.simple.plugin.XXXInterceptor>
		<property name="prop1" value="value1"/>
		<property name="prop2" value="value2"/>
	<plugin/>
</plugins>

在配置拦截器时, plugin 的 interceptor 属性为拦截器实现类的全限定名称,如果需 要参数,可以在 plugin 标签内通过 property 标签进行配置,配置后的参数在拦截器初始化 时会通过 setProperties 方法传递给拦截器。在拦截器中可以很方便地通过 Properties 取得配置的参数值。

plugin方法。这个方法的参数 target 就是拦截器要拦截的对象,该方法会 在创建被拦截的接口实现类时被调用。该方法的实现很简单 ,只需要调用 MyBatis 提供的 Plugin (org . apache. ibatis. plug in. Plugin )类的 wrap 静态方法就可以通过 Java 的 动态代理拦截目标对象。这个接口方法通常的实现代码如下。

@Override public Object plugin(Object target) {
	 return Plugin .wrap(target , this) ; 
}

intercept 方法是 MyBatis 运行时要执行的拦截方法。通过该方法的参数 invocation 可以得到很多有用的信息,该参数的常用方法如下。

@Override 
public Object intercept(Invocation invocation) throws Throwable { 
	Object target =invocation.getTarget (); 
	Method method= invocation.getMethod() ; 
	Object[] args = invocation.getArgs() ; 
	Object result =invocation .proceed (); 
return result; 
}
getTarget();方法可以获取当前被拦截的对象
getMethod();可以获取当前被拦截 的方法
getArgs();方法可以返回被拦截方法中的参数
proceed(); 可以执行被拦截对象真正的方法

拦截器签名


@Intercepts(org . apache . ibatis . plugin . Intercepts )和签名注解@Signature Corg . apache . ibatis . plugin . Signature ),这两个注解用来配置拦截器要拦截的接口 的方法。@ Intercepts 注解中的属性是一个@Signature (签名)数组,可以在同一个拦截器中 同时拦截不同的接口和方法

@Intercepts({ 
	@Signature (
	 type = ResultSetHandler.class, 
	 method = ” handleResultSets”,
	 args = {Statement . class})
}) 
public class ResultSetinterceptor implements Interceptor
@Signature 注解包含以下三个属性。
 type: 设置拦截的接口,可选值是前面提到的4 个接口 。
 method: 设置拦截接口中的方法名, 可选值是前面提到的4 个接口对应的方法,需要和接口匹配。
 args: 设置拦截方法的参数类型数组, 通过方法名和参数类型可以确定唯一一个方法。

通过不同的注解来配置可以拦截的方法,在方法完成后调用配置该注解的类.由于 MyBatis 代码具体实现的原因,可以被拦截的 4 个接口中的方法并不是都可以被拦截的,下面将针对这 4 种接口,将可以被拦截的方法以及方法被调用的位置和对应的拦截器签名 依次列举出来,大家可以根据方法调用的位置和方法提供的参数来选择想要拦截的方法

Executor 接口

    · int update(MappedStatement var1, Object var2) throws SQLException;
    该方法会在所有的 INSERT、 UPDATE、 DELETE 执行时被调用,因此如果想要拦截这3类操作,可以拦截该方法。接口方法对
	应的签名如下
	@Signature(type = Executor.class, method = "update", args = {MappedStatement.class,Object.class})
	
    · <E> List<E> query(MappedStatement var1, Object var2, RowBounds var3, ResultHandler var4) throws SQLException;
	该方法会在所有 SELECT 查询方法执行时被调用。过这个接口参数可以获取很多有用的信息,因此这是最常被拦截的一个方法。使用该
	方法需要注意的是,虽然接口中还有一个参数 更多的同名接口 ,但由于 MyBatis 的设计原因,这个参数多的接口不能被拦截。接口方法对
	应的签名如下
	@Signature(type = Executor.class, method = "query", args = {MappedStatement.class,Object.class,RowBounds.class, ResultHandler.class})
	
    · <E> Cursor<E> queryCursor(MappedStatement var1, Object var2, RowBounds var3) throws SQLException;
	该方法只有在查询的返回值类型为Cursor 时被调用 。接口方法对应的签名如下
	@Signature(type = Executor.class, method = "queryCursor", args = {MappedStatement.class,Object.class,RowBounds.class})
	
    · List<BatchResult> flushStatements() throws SQLException;
	该方法只在通过SqlSession方法调用flushStatements方法或执行的接口方法中带 有@Flush注解时才被调用 ,接口方法对应的签名如下。
	@Signature(type = Executor.class, method = "flushStatements", args = {})

    · void commit(boolean var1) throws SQLException;
	该方法只在通过SqlSession方法调用commit方法时才被调用,接口方法对应的签名如下。
	@Signature(type = Executor.class, method = "commit", args = {boolean.class})

    · void rollback(boolean var1) throws SQLException;
	该方法只在通过SqlSession方法调用rollback方法时才被调用,接口方法对应的签名如下。
	@Signature(type = Executor.class, method = "rollback", args = {boolean.class})

    · Transaction getTransaction();
	该方法只在通过 SqlSession方法获取数据库连接时才被调用,接口方法对应的签名如下。
	@Signature(type = Executor.class, method = "getTransaction", args = {})

    · void close(boolean var1);
	该方法只在延迟加载获取新 Executor后才会被执行,接口方法对应的签名如下。
	@Signature(type = Executor.class, method = "close", args = {boolean.class})

    · boolean isClosed();
    该方法只在延迟加载执行查询方法前被执行,接口方法对应的签名如下。
	@Signature(type = Executor.class, method = "isClosed", args = {})

ParameterHandler 接口

	· Object getParameterObject();
	该方法只在执行存储过程处理出参的时候被调用。接口方法对应的签名如下。
	@Signature(type = ParameterHandler.class, method = "getParameterObject", args = {})

    · void setParameters(PreparedStatement var1) throws SQLException;
    该方法在所有数据库方法设置 SQL 参数时被调用。接口方法对应的签名如下。
	@Signature(type = ParameterHandler.class, method = "setParameters", args = {PreparedStatement.class})

ResultSetHandler接口

 	· <E> List<E> handleResultSets(Statement var1) throws SQLException;
	该方法会在除存储过程及返回值类型为 Cursor<T> ( org.apache.ibatis.cursor.Cursor<T>)以外的查询方法中被调用。接口方法对应的签名如下。
	@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})

    · <E> Cursor<E> handleCursorResultSets(Statement var1) throws SQLException;
	只会在返回值类型为 Cursor<T>的查询方法中被调用 , 接口方法对应的签名如下。
	@Signature(type = ResultSetHandler.class, method = "handleCursorResultSets", args = {Statement.class})

    · void handleOutputParameters(CallableStatement var1) throws SQLException;
    该方法只在使用存储过程处理出参时被调用 ,接口方法对应的签名如下。
    @Signature(type = ResultSetHandler.class, method = "handleOutputParameters", args = {Statement.class})
    
	ResultSetHandler 接口的第一个方法对于拦截处理 MyBatis 的查询结果非常有用,并 且由于这个接口被调用的位置在处理二级缓存之前,因此通过这种方式处理的结果可以执行二 级缓存。

StatementHandler接口

    · Statement prepare(Connection var1, Integer var2) throws SQLException;
	该方法会在数据库执行前被调用 , 优先于当前接口中的其他方法而被执行。 接口方法对应 的签名如下。
    @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})

    · void parameterize(Statement var1) throws SQLException;
	该方法在 prepare 方法之后执行,用于处理参数信息, 接口方法对应的签名如下。
    @Signature(type = StatementHandler.class, method = "parameterize", args = {Statement.class})

    · void batch(Statement var1) throws SQLException;
	在全局设置配置 defaultExecutorType=”BATCH”时,执行数据操作才会调用该方法, 接口方法对应的签名如下。
    @Signature(type = StatementHandler.class, method = "batch", args = {Statement.class})

    · <E> List<E> query(Statement var1, ResultHandler var2) throws SQLException;
	执行 SELECT 方法时调用,接口方法对应的签名如下。
    @Signature(type = StatementHandler.class, method = "query", args = {Statement.class,ResultHandler.class})

    · <E> Cursor<E> queryCursor(Statement var1) throws SQLException;
    只会在返回值类型为 Cursor<T>的查询中被调用 , 接口 方法对应的签名如下。
    @Signature(type = StatementHandler.class, method = "queryCursor", args = {Connection.class, Integer.class})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值