基于mybatis-plus提供的示例环境,自定义注解和mybatis插件实现对数据库印射对象属性值进行操作

1. 自定义注解FieldTrim

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Author ZhengQinfeng
 * @Date 2020/11/28 21:50
 * @dec
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)  //作用于属性上
public @interface FieldTrim {

    /**
     * 默认将属性值trim去空格之后,大写保存
     *
     * @return
     */
    boolean upper() default true;
}

2. 自定义Mybatis插件

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.springframework.stereotype.Component;
import qinfeng.zheng.mybatis.plus.demo.anno.FieldTrim;

import java.lang.reflect.Field;

/**
 * @Author ZhengQinfeng
 * @Date 2020/11/28 21:52
 * @dec  自定义一个插件,在update数据库操作时,对印射对象属性值进行处理
 */
@Slf4j
@Component
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class StringTrimInterceptor implements Interceptor {


    @Override
    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();
        }

        // 只对插入或更新操作生效
        if (SqlCommandType.INSERT == sqlCommandType || SqlCommandType.UPDATE == sqlCommandType) {
            Field[] fields = parameter.getClass().getDeclaredFields();
            for (Field field : fields) {
                FieldTrim fieldTrim = field.getAnnotation(FieldTrim.class);
                if (fieldTrim != null && field.getType().equals(String.class)) {
                    field.setAccessible(true);
                    Object o = field.get(parameter);
                    field.setAccessible(false);
                    String newVal = o == null ? "" : String.valueOf(o).trim();
                    newVal = fieldTrim.upper() ? newVal.toUpperCase() : newVal.toLowerCase();
                    field.setAccessible(true);
                    field.set(parameter, newVal);
                    field.setAccessible(false);
                }
            }
        }

        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        // 创建代理对象,不覆写不影响功能使用
        return Plugin.wrap(target, this);
    }
}

3. 印射类User

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import qinfeng.zheng.mybatis.plus.demo.anno.FieldTrim;

@Accessors(chain = true)
@Data
@TableName(value = "user")
public class User {
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private String id;

    @FieldTrim
    private String name;

    private Integer age;

    @FieldTrim(upper = false)
    private String email;
}

4. 测试

   @Test
    public void testAdd() throws Exception {
        User user = new User();
        user.setName("admin   ");
        user.setAge(63);
        user.setEmail("   22@qq.com");
        userMapper.insert(user);
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);

    }

5. 测试结果

6. MyBatis-Plus3.4.0提供的内置拦截器接口

实现InnerInterceptor接口方法,也可以完成上述功能

import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import qinfeng.zheng.mybatis.plus.demo.anno.FieldTrim;

import java.lang.reflect.Field;

/**
 * @Author ZhengQinfeng
 * @Date 2020/11/28 23:18
 * @dec 写一个测试拦截器
 */
public class TestInnerInterceptor implements InnerInterceptor {

    @Override
    public void beforeUpdate(Executor executor, MappedStatement ms, Object parameter) {
        SqlCommandType sqlCommandType = ms.getSqlCommandType();
        if (SqlCommandType.INSERT == sqlCommandType || SqlCommandType.UPDATE == sqlCommandType) {
            Field[] fields = parameter.getClass().getDeclaredFields();
            for (Field field : fields) {
                FieldTrim fieldTrim = field.getAnnotation(FieldTrim.class);
                if (fieldTrim != null && field.getType().equals(String.class)) {
                    try {
                        field.setAccessible(true);
                        Object o = field.get(parameter);
                        field.setAccessible(false);
                        String newVal = o == null ? "" : String.valueOf(o).trim();
                        newVal = fieldTrim.upper() ? newVal.toUpperCase() : newVal.toLowerCase();
                        field.setAccessible(true);
                        field.set(parameter, newVal);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                    field.setAccessible(false);
                }
            }
        }
    }
}

配置拦截器生效

 /**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));  // 分页拦截器
        interceptor.addInnerInterceptor(new TestInnerInterceptor());  // 自定义拦截器
        return interceptor;
    }

    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return configuration -> configuration.setUseDeprecatedExecutor(false);
    }
posted on 2020-11-28 22:19  显示账号  阅读(494)  评论(0编辑  收藏  举报