我用过两次,
1.一次是数据库以前数据可以为null,现在不想为null,然后不想改代码,所以在插入或修改数据的时候,查一次,把为null的数据变一下,字符串变“”,数字变0或-1
下面的就是设置监听
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 4.0.0以后版本可以不设置该参数 -->
<property name="dialect" value="mysql"/>
<!-- 该参数默认为false -->
<!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
<!-- 和startPage中的pageNum效果一样-->
<property name="offsetAsPageNum" value="true"/>
<!-- 该参数默认为false -->
<!-- 设置为true时,使用RowBounds分页会进行count查询 -->
<property name="rowBoundsWithCount" value="true"/>
<!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
<!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型)-->
<property name="pageSizeZero" value="true"/>
<!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
<!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
<!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
<property name="reasonable" value="false"/>
<!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
<!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
<!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值 -->
<!-- 不理解该含义的前提下,不要随便复制该配置 -->
<property name="params" value="pageNum=start;pageSize=limit;"/>
</plugin>
<plugin interceptor="com.banksteel.erp.pfpurchase.util.EntityInterceptor"></plugin>
</plugins>
方法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 <T> void null2default(T obj)
{
if (null == obj)
{
return;
}
Method[] methods=obj.getClass().getMethods();
Map<String,Method> 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.如果不是用上面的分页,就用另一种监听
<!-- 创建SqlSessionFactory,同时指定数据源 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--<property name="mapperLocations" value="classpath*:com/banksteel/openerp/system/provider/DAOImpl/*Mapper.xml"
/> -->
<property name="mapperLocations" value="classpath*:mybatis/mapper/*Mapper.xml" />
<!-- MyBatis拦截器,拦截SQL语句处理companyId -->
<property name="plugins">
<array>
<bean
class="com.banksteel.openerp.commons.interceptor.RebuildSqlInterceptor" />
</array>
</property>
</bean>
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<ParameterMapping> 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) {
}
}



所有评论(0)