博主在使用mybatsi时由于需要业务功能都有一些基础的crud操作,每一个都写mapper很烦,使用@InsertProvider、@DeleteProvider、@SelectProvider、@UpdateProvider又不能满足所有的操作,所有参考hibernate中sql语句的组装模式写了一个基础的sql语句组装类,但是直接给sql语句赋值又会引起sql注入的问题,所以想用mybatis的Interceptor去拦截sql语句然后对sql语句中查询条件赋值,避免sql注入的问题。
以下时Interceptor代码
@Component
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { java.sql.Connection.class,
Integer.class }) })
public class Plugin implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget();
System.out.println("当前拦截到的对象:" + target);
MetaObject metaObject = SystemMetaObject.forObject(target);
String[] properties = metaObject.getGetterNames();
// Object value = metaObject.getValue("boundSql.parameterMappings");
// 对sql语句进行重新赋值
Configuration configuration = (Configuration) metaObject.getValue("delegate.configuration");
metaObject.setValue("boundSql.sql", "select * from menu t where 1=1 and t.authority=?");
// 对参数名称重新赋值
List list = new MyFirstPlugin().getParameterMappings(configuration);
metaObject.setValue("boundSql.parameterMappings", list);
// 获取参数值
Map parameterObject = (Map) metaObject.getValue("parameterHandler.parameterObject");
// 对参数值重新赋值
parameterObject.clear();
parameterObject.put("param3", 2);
metaObject.setValue("parameterHandler.parameterObject", parameterObject);
// 执行目标方法
Object proceed = invocation.proceed();
// 返回执行后的返回值
return proceed;
}
public Object plugin(Object target) {
Object wrap = Plugin.wrap(target, this);
// 返回为当前target创建的动态代理
return wrap;
}
// 将插件注册时的property属性设置进来
public void setProperties(Properties properties) {
}
private List<ParameterMapping> getParameterMappings(Configuration configuration) {
List<ParameterMapping> list = new ArrayList<ParameterMapping>();
ParameterMapping parameterMapper = new ParameterMapping.Builder(configuration, "param3", Object.class)
.mode(ParameterMode.IN).build();
list.add(parameterMapper);
return list;
}
}
以上是一个对sql语句和sql中参数进行重新赋值的示例。
org.apache.ibatis.scripting.defaults.DefaultParameterHandler中的setParameters(parameterMapping)是mybatis对预编译的sql语句进行赋值的操作,有兴趣可以看看。