- 浏览: 524592 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
gaolegao2008:
如果报 is_volum 列名找不到之类的,我是从新部署了一个 ...
spring quartz 定时器报错 -
gaolegao2008:
部署到linux上时,还有一种情况就是mysql数据库区分大小 ...
spring quartz 定时器报错 -
qq123zhz:
yahier 写道 对我有帮助,但我看的一个demo程序,却没 ...
spring quartz 定时器报错 -
qq123zhz:
这个要在eclipse的插件环境下运行的,你不懂eclipse ...
GEF 自动布局 -
qq123zhz:
这个很久了,不记得啥时候写的了
json转为Map
页面输入:男,数据库保存male,女,数据库保存为female。
使用interceptor,typeHandler
package cn.dcr.mybatis.util; import java.util.Properties; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.MappedStatement; 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.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import com.test.pojos.User; @Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }), @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }) }) public class MyInterceptor implements Interceptor { private static final String R_FEMALE = "女"; private static final String R_MALE = "男"; private static final String FEMALE = "female"; private static final String MALE = "male"; private Properties properties; /* * (non-Javadoc) * * @see * org.apache.ibatis.plugin.Interceptor#intercept(org.apache.ibatis.plugin * .Invocation) */ public Object intercept(Invocation invocation) throws Throwable { MappedStatement mappedStatement = (MappedStatement) invocation .getArgs()[0]; String sqlId = mappedStatement.getId(); String namespace = sqlId.substring(0, sqlId.indexOf('.')); Executor exe = (Executor) invocation.getTarget(); String methodName = invocation.getMethod().getName(); if (methodName.equals("query")) { Object parameter = invocation.getArgs()[1]; RowBounds rowBounds = (RowBounds) invocation.getArgs()[2]; } else if(methodName.equals("update")){ Object parameter = invocation.getArgs()[1]; if(parameter instanceof User) ((User)parameter).setGender(saveValueToDb(((User)parameter).getGender())); } return invocation.proceed(); } /* * (non-Javadoc) * * @see org.apache.ibatis.plugin.Interceptor#plugin(java.lang.Object) */ public Object plugin(Object target) { return Plugin.wrap(target, this); } /* * (non-Javadoc) * * @see * org.apache.ibatis.plugin.Interceptor#setProperties(java.util.Properties) */ public void setProperties(Properties properties) { this.properties = properties; } /**插入数据库 * @param value * @return */ private String saveValueToDb(String value) { if (value.equals(R_FEMALE)) { return FEMALE; } else if (value.equals(R_MALE)) { return MALE; } else { throw new IllegalArgumentException("数据库异常!" + value); } } }
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }), @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }) })
mybatis 拦截器好像只能使用注解,而且对于接口Executor,method只定义了update,query,flushStatements,commit,rollback,createCacheKey,isCached,clearLocalCache,deferLoad,getTransaction,close,isClosed这几个方法,没有delete和insert方法。
具体详见:
package org.apache.ibatis.executor; import org.apache.ibatis.cache.CacheKey; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import org.apache.ibatis.transaction.Transaction; import java.sql.SQLException; import java.util.List; public interface Executor { ResultHandler NO_RESULT_HANDLER = null; int update(MappedStatement ms, Object parameter) throws SQLException; List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException; List<BatchResult> flushStatements() throws SQLException; void commit(boolean required) throws SQLException; void rollback(boolean required) throws SQLException; CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds); boolean isCached(MappedStatement ms, CacheKey key); void clearLocalCache(); void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key); Transaction getTransaction(); void close(boolean forceRollback); boolean isClosed(); }
当我疑惑为什么mybatis没有在insert和delete的时候拦截呢?
看到了mybatis googleCode上的issue16。
Issue 16: | Update interceptor (plugin) fires for inserts |
Reporter: Eli Kizhnerman The iBatis plugin does not seem to be resolving the target methods to intercept properly. An interceptor that is defined to intercept only updates is also executed on inserts. I have the following definition: @Intercepts({@Signature( type=Executor.class, method="update", args={MappedStatement.class,Object.class})}) public class UpdateInterceptor implements Interceptor { ... } In Plugin.invoke you have the following code: Set<Method> methods = signatureMap.get(method.getDeclaringClass()); if (methods != null && methods.contains(method)) { return interceptor.intercept(new Invocation(target, method, args)); } DefaultSqlSession.insert internally calls an update method: public int insert(String statement, Object parameter) { return update(statement, parameter); } I suspect that the Method that is being passed to plugin.invoke is actually the update method and therefore the interceptor is executed.
原来在DefaultSqlSession的insert,delete方法也是调用了update方法。
public int insert(String statement, Object parameter) { return update(statement, parameter); }
public int delete(String statement, Object parameter) { return update(statement, wrapCollection(parameter)); }
mybatis太不厚道了,它的文档也没有具体的说明。
有人提出这是个bug,不过mybatis没有承认。
Clinton Begin added a comment - 10/Dec/09 03:58 PM Executor only has update and query methods. Thus inserts and deletes are also considered updates. It sounds like to do what you want, we need another interception point, at the session level. You can do so right now with a proxy class between the SqlSession interface and the default implementation. [ Show » ] Clinton Begin added a comment - 10/Dec/09 03:58 PM Executor only has update and query methods. Thus inserts and deletes are also considered updates. It sounds like to do what you want, we need another interception point, at the session level. You can do so right now with a proxy class between the SqlSession interface and the default implementation. [ Permalink | Delete | « Hide ] Eli Kizhnerman added a comment - 11/Dec/09 12:28 PM This is not working the way I expected it but that it is not a bug. I can get what I need from the MappedStatement SqlCommandType.
package cn.dcr.mybatis.util; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; /**自定义typeHandler<br/> * 1 插入数据库,男转为male * 2 查询,maile转为男 * @author Administrator * */ public class GenderTypeHandlerCallback extends BaseTypeHandler<String> { private static final String R_FEMALE = "女"; private static final String R_MALE = "男"; private static final String FEMALE = "female"; private static final String MALE = "male"; @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return cs.getString(columnIndex); } @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { String t = rs.getString(columnName); return converSex(t); } @Override public void setNonNullParameter(PreparedStatement preparedStatement, int i, String str, JdbcType jdbcType) throws SQLException { preparedStatement.setString(i, saveValueToDb(str)); } /**插入数据库 * @param value * @return */ private String saveValueToDb(String value) { if (value.equals(R_FEMALE)) { return FEMALE; } else if (value.equals(R_MALE)) { return MALE; } else { throw new IllegalArgumentException("数据库异常!" + value); } } /** 从数据库读出 * @param value * @return */ private String converSex(String value){ if (value.equals(FEMALE)) { return R_FEMALE; } else if (value.equals(MALE)) { return R_MALE; } else { throw new IllegalArgumentException("数据库异常!" + value); } } }
在自定义typeHandler的getNullableResult方法中调整自己的结果集,可以说是在sql执行后,IOC的理论叫后置通知,interceptor应该是前置通知。
@Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { String t = rs.getString(columnName); return converSex(t); }
在typeHandler的setNonNullParameter,应该是参数传入前转换参数的功能,但是实际操作中没有被调用,不知道为什么。
@Override public void setNonNullParameter(PreparedStatement preparedStatement, int i, String str, JdbcType jdbcType) throws SQLException { preparedStatement.setString(i, saveValueToDb(str)); }
以上是对mybatis 的切入点的实践。总体感觉和struts2的拦截器比,还有差距,至少我理解struts2的拦截器比理解它的要快。
发表评论
-
eclipse Resource 资料
2016-11-15 16:51 574IWorkspace/IWorkspaceRoot/IPro ... -
.docker/machine/machines/default/ca.pem: no such file or directory
2016-09-06 15:59 835Was doing adocker-machine env ... -
list.AddAll 去重复
2015-09-11 12:01 5837问题描述: 有List A和B,A、B中元素都是可保证 ... -
eclipse 插件开发 Setting the Java build path
2014-06-04 11:00 1171JDT Plug-in Developer Guide & ... -
xstream 下划线_问题
2013-12-30 10:18 4132最近在使用xtream 1.4.3,出现了如下的问题: ... -
RCP MessageConsole设置显示的最大行数
2013-09-05 11:34 894MessageConsole.setWaterMarks(5 ... -
freemarker 自定义freeMarker标签
2013-08-12 16:09 3845import java.io.IOException; i ... -
xstream javabean设置属性默认值的问题
2013-04-24 09:54 6520在xstream反序列化使用过程中发现,如果xml无该属 ... -
在使用xstream反序列化时遇到的问题
2013-04-24 09:42 1708public abstract class SBase { ... -
RCP 知识点
2013-03-14 15:10 926获得工作区的所有工程: //获得workspace的所有 ... -
RCP FileSystem 文件系统
2013-02-19 10:42 1327public static File toLocalFile ... -
json转为Map
2013-01-19 22:27 32759package digu.pendant.util; ... -
eclipse4.x 去掉quick access
2013-01-11 14:57 3985/** * 去掉quick access * ... -
xstream 的高级用法,自定义输出结构
2012-12-19 14:35 2363public static void main(Stri ... -
jdt 核心知识
2012-11-27 21:39 1179jdt官方核心知识...................... ... -
jdt 创建java工程,生成代码,运行main方法
2012-11-27 10:50 2284public static IJavaProje ... -
两个osgi的例子程序
2012-11-20 10:21 1003osgi的例子....................直接上代 ... -
jfreechart 的官方例子,很全
2012-11-20 10:19 900jfreechart的官方的demon,很全。 -
SWT 隔行换色-自动宽高调整
2012-10-16 17:32 1662** * 创建:ZhengXi 2009-8-4 */ ... -
RCP 为action添加操作进度条
2012-10-16 13:59 1247public class StartAction extend ...
相关推荐
MyBatis拦截器分页与动态修改SQL及其参数值 提取SQL Like 字段
主要给大家介绍了关于mybatis拦截器实现通用权限字段添加的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用mybatis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
通过mybatis拦截器将查询语句、更新语句、删除语句、插入语句中指定表明替换为另一个表名
下面小编就为大家带来一篇MyBatis拦截器:给参数对象属性赋值的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
Mybatis拦截器记录数据更新历史记录到MongoDB的源码,另外需要配置拦截器到mybatis配置文件中。
通过Mybatis拦截器自动定位慢SQL并记录日志
Mybatis 如何防止 sql 注入?mybatis 拦截器了解过吗,应用场景是什么答案 Mybatis 如何防止 sql 注入?mybatis 拦截器了解过吗,应用场景是什么答案
通过mybatis的拦截器,实现为所有sql(或指定sql) 统一添加查询条件,譬如通过线程变量传递某参数(日期),来实现对指定参数的数据筛选,而不需要在每个查询前,手动将该条件注入到查询中。因该资料网络较少,故特此...
mybatis拦截器的完整实现,test.sql是数据库测试脚本,主要目的是生成mybatis最终执行的sql语句,并打印出来,方便调试。 基于此,可以实现自动化分页。
MyBatis拦截器(csdn)————程序
mybatis 拦截器了解过吗,应用场景是什么.详情介绍Mybatis 如何防止 sql 注入?mybatis 拦截器了解过吗,应用场景是什么.详情介绍Mybatis 如何防止 sql 注入?mybatis 拦截器了解过吗,应用场景是什么.详情介绍...
spring+springMVC+mybatis拦截器分页
MyBatis拦截器分页代码,网上看到的,供大家一起共同分享学习。
mybatis拦截器以及JSqlParser解析sql和生成一个新的Sqlsource
mybatis mysql 分页拦截器,可以针对方法名称,或指定的参数进行拦截
详细介绍了Mybatis拦截器的使用,并且展示了分页插件的参考实现
SpringBoot整合Mybatis完整详细版含注册、登录、拦截器配置功能