18 April 2018

反射实现数据到对象的映射

1.背景:项目在用hibernate,自己感觉一些功能很繁琐,反射实现数据到对象的映射

2.想法:获取注解的属性信息,得到需要映射的泛型,把泛型类对象转换为rowmapper对象,用jdbc模板查询

3.实现

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
@Lazy(false)
public @interface Config {
    String tableName() default "";

    String sql() default "";
}
private volatile List<T> configList = Collections.emptyList();

//得到调用类上面,自定义注解的对象,包含对象里面的信息
private Config getConfigLocation() {
     Class<?> clazz = this.getClass();
     Config configLocation = AnnotationUtils.getAnnotation(clazz, Config.class);
     while (configLocation == null) {
         clazz = clazz.getSuperclass();
         if (clazz == Object.class) {
             return null;
         }
         configLocation = AnnotationUtils.getAnnotation(clazz, Config.class);
     }
     return configLocation;
}
public void reloadConfigs() {
     Config configLocation = this.getConfigLocation();
     if (configLocation == null) {
         log.error("Config Annotation error");
         return;
     }
     String sql = configLocation.sql();
     String query;
     String tableName = configLocation.tableName();
     if (StringUtils.isNoneBlank(sql)) {
         query = sql;
     } else {
         query = "SELECT * FROM " + tableName;
     }
     RowMapper<T> rowMapper = this.getRowMapper();
     List<T> currentConfigList = jdbcTemplate.query(query, rowMapper);
     configList = Collections.unmodifiableList(currentConfigList);

     this.afterReload();
}
protected RowMapper<T> getRowMapper() {
     Class<T> clazz = this.getGenericType();
     return BeanPropertyRowMapper.newInstance(clazz);
}
//获得超类的泛型参数的实际类型
private Class<T> getGenericType() {
     ParameterizedType t = (ParameterizedType) this.getClass().getGenericSuperclass();
     Type[] types = t.getActualTypeArguments();
     Type type = types[0];
     if (type instanceof Class) {
         return (Class<T>) type;
     }
     return null;
}
protected void afterReload() {
    // do the after things in childClass
}
protected abstract void scheduleReload();

4.调用

@Config(tableName = "boss_anti_sharing_rule")
public class AntiSharingRuleServiceImpl extends RefreshConfigService<AntiSharingRule> {

    @Scheduled(cron = "0 0 * * * ?")
    @Override
    protected void scheduleReload() {
        this.reloadConfigs();
    }
}


blog comments powered by Disqus