我用过两次,
1.一次是数据库以前数据可以为null,现在不想为null,然后不想改代码,所以在插入或修改数据的时候,查一次,把为null的数据变一下,字符串变“”,数字变0或-1
下面的就是设置监听
方法EntityInterceptor.java
package com.banksteel.erp.pfpurchase.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
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;
/**
*
* @description: 防止插入出现null
* @projectName:finance-inventorybook-service
* @author:
* @createTime:2017年11月30日 上午9:37:30
*/
@Intercepts(value =
{ @Signature(type = Executor.class, method = "update", args =
{ MappedStatement.class, Object.class }) })
public class EntityInterceptor implements Interceptor
{
@Override
public Object intercept(Invocation invocation) throws Throwable
{
final Object[] args = invocation.getArgs();
MappedStatement ms = (MappedStatement) args[0];
Object obj = args[1];
// 插入时初始化为null的字段
if (SqlCommandType.INSERT == ms.getSqlCommandType())
{
if (obj instanceof List>)
{
List> list = (List>) obj;
for (Object item : list)
{
null2default(item);
}
} else
{
null2default(obj);
}
}
return invocation.proceed();
}
@Override
public Object plugin(Object target)
{
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties)
{
}
/**
*
* @description: 将实体类的属性由null设置为默认值,这里没有变数字的,只变了字符串
* @param obj
* @author:
* @createTime:2017年11月2日 下午5:19:56
*/
public static void null2default(T obj)
{
if (null == obj)
{
return;
}
Method[] methods=obj.getClass().getMethods();
Map setMethodMap = new HashMap<>();
for (Method method : methods){
if(method.getName().startsWith("set")){
setMethodMap.put(method.getName(),method);
}
}
for (Method method : methods){
if((method.getName().length() < 3) || (!method.getName().startsWith("get"))){
//只调用get函数
continue;
}
//排除带有参数列表的方法
Class>[] pts =method.getParameterTypes();
if(null != pts && 0 < pts.length){
continue;
}
//排除值不为null的get方法
try {
if(null != method.invoke(obj)){
continue;
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//找出get方法对应的set方法
char[] cs = method.getName().toCharArray();
cs[0] = 's';
Method setMethod = setMethodMap.get(String.valueOf(cs));
if(null == setMethod){
continue;
}
//设置默认值
Class> retClazz = method.getReturnType();
try {
if(Objects.equals(retClazz,String.class)){
setMethod.invoke(obj, "");
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
setMethodMap.clear();
}
// public static void main(String args[]){
// ResourceAuditInfo ra = new ResourceAuditInfo();
// null2default(ra);
// System.out.println(JSONObject.toJSONString(ra));
// }
}
2.如果不是用上面的分页,就用另一种监听
class="com.banksteel.openerp.commons.interceptor.RebuildSqlInterceptor" />
Rexxx.java,这里可以查找到要修改的sql或查询的条件,再这里都可以修改
package com.banksteel.openerp.commons.interceptor;
import java.sql.Connection;
import java.util.List;
import java.util.Properties;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.banksteel.openerp.commons.filter.SaasParameter;
import com.banksteel.openerp.commons.utils.RebuildSqlUtils;
import cn.mysteel.util.StringUtils;
/**
* 重建SQL语句拦截器
*
* @author KangJian
*
*/
// MyBatis中Statement语句是通过RoutingStatementHandler对象的 prepare方法生成的,注解声明拦截此方法
@Intercepts({ @Signature(method = "prepare", type = StatementHandler.class, args = { Connection.class }) })
public class RebuildSqlInterceptor implements Interceptor {
static Logger logger = LoggerFactory.getLogger(RebuildSqlInterceptor.class);
public Object intercept(Invocation invocation) throws Throwable {
// long start = System.currentTimeMillis();
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
// 创建反射工具类,用于获取和设置SQL语句
MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
// 获取拦截的SQL语句
MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");
BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");
// 获取本地线程变量
Long memberId = 0L;
try {
if (StringUtils.isNotEmpty(SaasParameter.getMemberId())) {
memberId = Long.parseLong(SaasParameter.getMemberId());
}
} catch (Exception e) {
logger.error("【noSaas拦截构建】会员ID转换异常,id=" + memberId, e);
}
if (!mappedStatement.getId().endsWith("noSaas")) {
// 当statement的id不以noSaas结尾,且memberId>0,则执行对INSERT与SELECT语句的重构
if ("SELECT".equals(mappedStatement.getSqlCommandType().toString()) && memberId > 0) {
List parameterMappings = boundSql.getParameterMappings();
metaStatementHandler.setValue("delegate.boundSql.sql", RebuildSqlUtils.rebuildQuery(boundSql.getSql(),
SaasParameter.getMemberId(), parameterMappings));
} else if ("INSERT".equals(mappedStatement.getSqlCommandType().toString()) && memberId > 0) {
metaStatementHandler.setValue("delegate.boundSql.sql",
RebuildSqlUtils.rebuildInsert(boundSql.getSql(), SaasParameter.getMemberId()));
}
} else {
// 当statement的id以noSaas结尾,为语句添加memberId额外参数
if ("SELECT".equals(mappedStatement.getSqlCommandType().toString())
|| "INSERT".equals(mappedStatement.getSqlCommandType().toString())) {
boundSql.setAdditionalParameter("memberId", memberId);
metaStatementHandler.setValue("delegate.boundSql", boundSql);
}
}
Object result = invocation.proceed();
// System.out.println("拦截耗时:" + (System.currentTimeMillis() - start));
return result;
}
public Object plugin(Object target) {
// 当目标类是StatementHandler类型时,才包装目标类,否者直接返回目标本身,减少目标被代理的次数
if (target instanceof StatementHandler) {
return Plugin.wrap(target, this);
} else {
return target;
}
}
public void setProperties(Properties properties) {
}
}