第一步:先创建类,标志上相应注解。
@Data
public class User {
private Long id;
private String username;
/**
* type 绑定的是哪一个字典
* target 给这个类里面的那个属性赋值
*/
@FieldBind(type = BindType.USER_SEX, target = "sex")
private String sex;
}
第二步:接口实现
@Component
public class DataBind implements IDataBindQA {
@Resource
ApplicationContext applicationContext;
/**
* 设置元数据对象<br>
* 根据源对象映射绑定指定属性(自行处理缓存逻辑)
*
* @param fieldBind 数据绑定注解
* @param fieldValue 属性值
* @param metaObject 元数据对象 {@link MetaObject}
* @return
*/
@Override
public void setMetaObject(DictAnno fieldBind, Object fieldValue, MetaObject metaObject) {
//调用字典的service层
ISysDictItemService dictService = applicationContext.getBean(ISysDictItemService.class);
List<SysDictItem> sysDictItems = dictService.selectDictDataByType(fieldBind.type());
//找到相应的数据
Map<String, String> dictMap = sysDictItems.stream().collect(Collectors.toMap(dict -> dict.getDictValue(), dict -> dict.getDictLabel()));
// 赋值
metaObject.setValue(fieldBind.target(), dictMap.get(String.valueOf(fieldValue)));
}
}
注解:
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface DictZP {
String sharding() default "";
String type();
String target();
}
使用:
public class User {
private Long id;
private String username;
/**
* type 绑定的是哪一个字典
* target 给这个类里面的那个属性赋值
*/
@DictZP(type = BindType.USER_SEX, target = "sex")
private String sex;
}
代码如下:
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.sdecloud.mybatismate.a.annotation.DictAnno;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.apache.ibatis.reflection.ReflectorFactory;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import java.lang.reflect.Field;
import java.sql.Statement;
import java.util.*;
@Slf4j
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
@Component
public class MyExecutor implements Interceptor {
@Autowired
private IDataBindZP iDataBindZP;//源码中是IDataBind,我则是定义为IDataBindZP
private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
private static final ReflectorFactory REFLECTOR_FACTORY = new DefaultReflectorFactory();
@Override
@SuppressWarnings("unchecked")
public Object intercept(Invocation invocation) throws Throwable {
//returnValue :这个returnValue就是已经查询出来的数据
Object returnValue = invocation.proceed();
// 使用反射对结果进行处理
if (returnValue instanceof ArrayList<?>) {
List<?> list = (ArrayList<?>) returnValue;
if (CollUtil.isNotEmpty(list)) {
Class<?> clazz = list.get(0).getClass();
//获取所有的属性
Field[] declaredFields = clazz.getDeclaredFields();
list.forEach(obj -> {
MetaObject metaObject = MetaObject.forObject(obj, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, REFLECTOR_FACTORY);
Arrays.stream(declaredFields).forEach(field -> {
//判断属性之上是否有自己定义的注解
DictZP annotation = field.getAnnotation(DictZP.class);
if (ObjectUtil.isNotEmpty(annotation)) {
//如果有,则进行转换
Object filedValue = metaObject.getValue(field.getName());
iDataBindZP.setMetaObject(annotation, filedValue, metaObject);
}
});
});
}
}
return returnValue;
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
}
public interface IDataBindZP {
void setMetaObject(DictZP var1, Object var2, MetaObject var3);
}