问题:想把整个项目实体包含caseId字段的所有含有Bigdecaml类型的字段动态设置精度。
解决:自己写一个类实现接口org.apache.ibatis.plugin.Interceptor
几个小问题
1.Interceptor接口不能注入业务代码的service(可能是业务service比Interceptor迟加入spring容器,加载Interceptor的时候还是空的),但是可以注入ApplicationContext.
2.MetaObject对象的setValue方法可以对插入之前对象的字段做处理
3.TableFieldInfo对象有我们实体所有的字段信息
有这三个对象,业务代码可以按自己的业务写
代码:
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.okay.house.bus.service.impl.BusCaseInfoServiceImpl;
import com.okay.house.common.utils.StringUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
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;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* 根据案件统一BigDecimal数值类型小数位数
*/
@Component
@Intercepts(@Signature(type = Executor.class, method = "update", args = {MappedStatement.class,
Object.class}))
public class MybatisIntercepter implements Interceptor {
private Integer xsws;
@Autowired
private ApplicationContext applicationContext;
private Configuration configuration;
private SqlCommandType sqlCommandType;
@Override
public Object intercept(Invocation invocation) throws Throwable {
// mapper映射对象
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
configuration = mappedStatement.getConfiguration();
// 执行类型枚举 UNKNOWN, INSERT, UPDATE, DELETE, SELECT, FLUSH
sqlCommandType = mappedStatement.getSqlCommandType();
Object parameter = invocation.getArgs()[1];
BoundSql boundSql = mappedStatement.getBoundSql(parameter);
String sql = boundSql.getSql();
Object parameterObject = boundSql.getParameterObject();
process(parameterObject);
return invocation.proceed();
}
private void process(Object parameter) {
if (parameter != null) {
// 表字段对象
TableInfo tableInfo = null;
Object entity = parameter;
if (parameter instanceof Map) {
Map<?, ?> map = (Map<?, ?>) parameter;
if (map.containsKey(Constants.ENTITY)) {
Object et = map.get(Constants.ENTITY);
if (et != null) {
entity = et;
tableInfo = TableInfoHelper.getTableInfo(entity.getClass());
}
}
} else {
tableInfo = TableInfoHelper.getTableInfo(parameter.getClass());
}
if (tableInfo != null) {
//到这里就应该转换到实体参数对象了,因为填充和ID处理都是争对实体对象处理的,不用传递原参数对象下去.
MetaObject metaObject = this.configuration.newMetaObject(entity);
List<TableFieldInfo> fieldList = tableInfo.getFieldList();
// 业务处理
String property = "";
for (TableFieldInfo x : fieldList) {
if(x.getProperty().equals("caseId")){
property = x.getProperty();
}
if(StringUtils.isNotBlank(property)){
break;
}
}
if(StringUtils.isNotBlank(property)){
Object value = metaObject.getValue(property);
BusCaseInfoServiceImpl busCaseInfoMapper = applicationContext.getBean(BusCaseInfoServiceImpl.class);
xsws = busCaseInfoMapper.getXsws((String) value);
for (TableFieldInfo x : fieldList) {
Class<?> propertyType = x.getPropertyType();
if(propertyType.equals(BigDecimal.class)){
String property1 = x.getProperty();
if(!property1.equals("ftxs")){
BigDecimal decimal = (BigDecimal)metaObject.getValue(property1);
// MetaObject对象的setValue方法可以对插入之前对象的字段做处理
metaObject.setValue(x.getProperty(),decimal!=null?decimal.setScale(6,6):BigDecimal.ZERO);
}
}
}
}
}
}
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target,this);
}
@Override
public void setProperties(Properties properties) {
}
}