反射实现数据到对象的映射
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();
}
}