赞
踩
- import org.apache.commons.lang3.StringUtils;
- import org.apache.commons.lang3.reflect.FieldUtils;
- 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.mapping.SqlSource;
- import org.apache.ibatis.plugin.*;
- import org.apache.ibatis.session.defaults.DefaultSqlSession;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.stereotype.Component;
- import tk.mybatis.mapper.annotation.LogicDelete;
- import tk.mybatis.mapper.annotation.Version;
-
- import java.io.File;
- import java.lang.reflect.Field;
- import java.util.*;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
-
- @Component
- @Intercepts({@Signature(
- type = Executor.class,
- method = "update",
- args = {MappedStatement.class, Object.class}
- )})
- public class MybatisInterception implements Interceptor {
-
- public MybatisInterception() {
- }
-
- public Object intercept(Invocation invocation) throws Throwable {
- MappedStatement mappedStatement = (MappedStatement)invocation.getArgs()[0];
- SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
-
- Object parameter = invocation.getArgs()[1];
- if (parameter == null) {
- return invocation.proceed();
- } else {
- Field[] declaredFields = this.getAllFields(parameter);
- Date now = new Date();
- String userId = ContextUtil.getUserId();
- Integer dteptId = ContextUtil.getDteptId();
- Field[] var9 = declaredFields;
-
- if (SqlCommandType.DELETE.equals(sqlCommandType)) {
-
- BoundSql boundSql = mappedStatement.getBoundSql(parameter);
-
- //转换DELETE语句为逻辑删除语句
- String logicDeleteSql = convertToLogicDelete(boundSql.getSql());
-
- FieldUtils.writeField(boundSql, "sql", logicDeleteSql, true);
-
- MappedStatement newMappedStatement = new MappedStatement.Builder(mappedStatement.getConfiguration(),
- mappedStatement.getId(), new BoundSqlSqlSource(boundSql), mappedStatement.getSqlCommandType())
- .build();
-
- invocation.getArgs()[0] = newMappedStatement;
-
- return invocation.proceed();
- }
-
- if(parameter instanceof DefaultSqlSession.StrictMap) {
- DefaultSqlSession.StrictMap strictMap = (DefaultSqlSession.StrictMap) parameter;
- Object collection = strictMap.get("collection");
- if(collection instanceof Collection) {
- for (Object obj : ((Collection<Object>) collection)) {
- Field[] fields = this.getAllFields(obj);
- for (Field field : fields) {
- extracted(sqlCommandType, obj, now, userId, dteptId, field);
- }
- }
- }
- } else {
- for (Field field : var9) {
- extracted(sqlCommandType, parameter, now, userId, dteptId, field);
- }
- }
- return invocation.proceed();
- }
- }
-
- private void extracted(SqlCommandType sqlCommandType, Object parameter, Date now, String userId, Integer dteptId, Field field) throws IllegalAccessException {
- if (field.getAnnotation(NotAutoFill.class) == null) {
- Class clazz;
- if (SqlCommandType.INSERT.equals(sqlCommandType)) {
- if (field.getAnnotation(CreateTime.class) != null || Objects.equals(field.getName(), "createTime")) {
- field.setAccessible(true);
- field.set(parameter, now);
- }
-
- if (field.getAnnotation(Version.class) != null || Objects.equals(field.getName(), "version")) {
- field.setAccessible(true);
- field.set(parameter, 1);
- }
-
- if (field.getAnnotation(LogicDelete.class) != null || Objects.equals(field.getName(), "isDeleted")) {
- field.setAccessible(true);
- field.set(parameter, 0);
- }
-
- if (Objects.equals(field.getName(), "status")) {
- field.setAccessible(true);
- if (field.getType() == Integer.class) {
- field.set(parameter, 0);
- }
- }
-
- if (Objects.equals(field.getName(), "createBy")) {
- field.setAccessible(true);
- if (StringUtils.isNotEmpty(userId)) {
- clazz = field.getType();
- if (clazz == Integer.class) {
- field.set(parameter, Integer.parseInt(userId));
- } else {
- field.set(parameter, userId);
- }
- }
- }
-
- if (Objects.equals(field.getName(), "createDeptId")) {
- field.setAccessible(true);
- field.set(parameter, dteptId);
- }
- }
-
- if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) {
- if (field.getAnnotation(UpdateTime.class) != null || Objects.equals(field.getName(), "updateTime")) {
- field.setAccessible(true);
- field.set(parameter, now);
- }
-
- if (Objects.equals(field.getName(), "updateBy")) {
- field.setAccessible(true);
- clazz = field.getType();
- if (StringUtils.isNotEmpty(userId)) {
- if (clazz == Integer.class) {
- field.set(parameter, Integer.parseInt(userId));
- } else {
- field.set(parameter, userId);
- }
- }
- }
- }
- }
- }
-
- public static Class<?> findEntityClassByTableName(String tableName, String basePackage) {
- ClassPathScanningCandidateComponentProvider scanner =
- new ClassPathScanningCandidateComponentProvider(false);
- scanner.addIncludeFilter(new AnnotationTypeFilter(Table.class));
- Set<BeanDefinition> beanDefinitions = scanner.findCandidateComponents(basePackage);
- for (BeanDefinition beanDefinition : beanDefinitions) {
- try {
- Class<?> clazz = Class.forName(beanDefinition.getBeanClassName());
- Table table = clazz.getAnnotation(Table.class);
- if (table != null && table.name().equals(tableName)) {
- return clazz;
- }
- } catch (ClassNotFoundException e) {
- continue;
- }
- }
- return null;
- }
-
- private String convertToLogicDelete(String sql) throws NoSuchFieldException {
- Pattern pattern = Pattern.compile("DELETE\\s+FROM\\s+(\w+)\\s+WHERE\\s+(.*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
- Matcher matcher = pattern.matcher(sql);
-
- if (matcher.matches()) {
- String tableName = matcher.group(1); //获取表名
-
- Class<?> classByTableName = findEntityClassByTableName(tableName, "com.demo.entity");
- if(classByTableName == null) {
- return sql;
- }
-
- Field isDeletedField = getDeletedField(classByTableName);
-
- if(isDeletedField == null || isDeletedField.getAnnotation(LogicDelete.class) == null) {
- return sql;
- }
-
- String whereClause = matcher.group(2).trim(); //获取WHERE子句并去除两端空白字符
-
- // 构建逻辑删除的UPDATE语句
- StringBuilder logicDeleteSql = new StringBuilder();
- logicDeleteSql.append("UPDATE ").append(tableName).append(" SET ").append("is_deleted").append(" = ").append(1);
-
- //如果WHERE子句不为空或不全为空白字符,则加上WHERE子句
- if (!whereClause.isEmpty()) {
- logicDeleteSql.append(" WHERE ").append(whereClause);
- }
- return logicDeleteSql.toString();
- } else {
- // 如果SQL语句格式不匹配,则返回原始SQL或抛出异常,这里为了简单起见,直接返回原始 SQL
- return sql;
- }
- }
-
- public Object plugin(Object o) {
- return Plugin.wrap(o, this);
- }
-
- public void setProperties(Properties properties) {
- }
-
- private Field getDeletedField(Class clazz) {
- String isDeleted = "isDeleted";
- Field isDeletedField = null;
- for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
- Field[] declaredFields = c.getDeclaredFields();
- for (Field field : declaredFields) {
- if(field.getName().equals(isDeleted)) {
- isDeletedField = field;
- break;
- }
- }
- }
- return isDeletedField;
- }
-
- private Field[] getAllFields(Object object) {
- Class<?> clazz = object.getClass();
- ArrayList fieldList;
- for(fieldList = new ArrayList(); clazz != null; clazz = clazz.getSuperclass()) {
- fieldList.addAll(new ArrayList(Arrays.asList(clazz.getDeclaredFields())));
- }
- Field[] fields = new Field[fieldList.size()];
- fieldList.toArray(fields);
- return fields;
- }
-
- public class BoundSqlSqlSource implements SqlSource {
-
- private BoundSql boundSql;
-
- public BoundSqlSqlSource(BoundSql boundSql) {
- this.boundSql = boundSql;
- }
-
- @Override
- public BoundSql getBoundSql(Object parameterObject) {
- return boundSql;
- }
- }
- }
切身经历但不一定是真相:项目已经有拦截器和mybatis-config.xml比如在公共依赖中,再新建mybatis-config.xml会存在覆盖xml配置的情况,虽然拦截器都生效了。如果命名为mybatis-config-xxx.xml等拦截器就没有生效。通过采用配置类的形式,暂时未发现不良影响。
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
- <configuration>
- <!-- 插件配置... -->
- <plugins>
- <plugin interceptor="xxx.xxx.MybatisInterceptor">
- <!-- 插件可以配置属性,如果需要的话 -->
- <!-- <property name="someProperty" value="someValue"/> -->
- </plugin>
- </plugins>
-
- <!-- 其他配置... -->
- </configura
- @Configuration
- @AutoConfigureAfter({PageHelperAutoConfiguration.class})
- public class MybatisFeatureConfig {
- @Autowired
- private List<SqlSessionFactory> sqlSessionFactoryList;
-
- public MybatisFeatureConfig() {
- }
-
- @PostConstruct
- public void addMyInterceptor() {
- MybatisInterception e = new MybatisInterception();
- Iterator var2 = this.sqlSessionFactoryList.iterator();
-
- while(var2.hasNext()) {
- SqlSessionFactory sqlSessionFactory = (SqlSessionFactory)var2.next();
- sqlSessionFactory.getConfiguration().addInterceptor(e);
- }
-
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。