基于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);
}
日拱一卒无有尽,功不唐捐终入海