在我们开发过程中,总会遇到主表字典字段关联字典表,也就是说数据库表中存的是字典的ID,前端界面展示的时候需要转换成字典ID对应的字典值,有的时候一个表还存有多个字典关联的字段,所以我们在查询的时候需要做一系列的关联查询,这样不仅效率低而且SQL比较麻烦。
根据这个需求为出发点,写了一个通用的处理类,另外只需要在字典的实体字段上加一个注解即可以。
自定义注解
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Diction {
String value() default "";
}
转换类大致思路
1、实体类/OutVO中的字典属性加注解
@Diction
private String polluterType;
2、调用工具类的conventDicValue(List<T> list, Class<T> clazz)方法,把集合以及集合存储元素的类型传入方法内,方法内部根据反射机制遍历实体加注解的属性,根据字典 ID去Reds里查找其对应的值,当然如果redis初次运行没有此key,则把所有字典载入redis中,然后遍历集合逐条替换,最后把处理后的list返回。
@Component
public class DictionUtils implements IDictionUtils{
@Autowired
RedisUtil redisUtil;
@Autowired
IDictionaryInfoService iDictionaryInfoService;//从mysql中加载所有字典到redis中
public <T> List<T> conventDicValue(List<T> list, Class<T> clazz){
List<String> filedNameList = new ArrayList<String>();//加有字典注解的字段
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields){
if (field.isAnnotationPresent(Diction.class)){
filedNameList.add(field.getName());
}
}
if (filedNameList.size() == 0)
return list;
for (T t : list){
try {
for (String filedName : filedNameList){
Field field = t.getClass().getDeclaredField(filedName);
field.setAccessible(true);
if (field.get(t) == null){
field.set(t, "");
continue;
}
if (!redisUtil.hasKey("dictionaryInfo"))
iDictionaryInfoService.redisHashMap();//如果redis中没有此key,则从mysql中加载
if (redisUtil.hget("dictionaryInfo", field.get(t).toString()) != null)
field.set(t, redisUtil.hget("dictionaryInfo", field.get(t).toString()));
else
field.set(t, "");
}
} catch (Exception e) {
e.printStackTrace();
}
}
return list;
}
}