我正在处理一些我用hibernate实现的web服务。问题是我需要访问实体表的名称(比如@Table中的那些(" Table_A"))。 代码生成,所以我不能改变实体类本身给我我需要的东西。
这就是我到目前为止所做的事情:
public static
<T extends Entity<K>, K extends Serializable>
String getTableName(Class<T> objClass) {
Table table = objClass.getAnnotation(Table.class);
return (table != null)? table.name() : null;
}
然而,经过一些研究后,我发现反射并不是最好的表现方式,而且由于这种方法会被大量调用,我正在寻找另一种方法。
我试图遵循这里给出的建议: Performance of calling Method/Field.getAnnotation(Class) several times vs. Pre-caching this data in a Map。
这就是我提出的:
public final class EntityUtils {
private static HashMap<String, String> entityCache;
private EntityUtils() {
entityCache = new HashMap<String, String>();
}
public static
<T extends Entity<K>, K extends Serializable>
String getTableName_New(Class<T> objClass) {
String tableName = entityCache.get(objClass.getCanonicalName());
if (tableName == null) {
Table table = objClass.getAnnotation(Table.class);
if (table != null) {
tableName = table.name();
entityCache.put(objClass.getCanonicalName(), tableName);
}
}
return tableName;
}
}
但是,我对此并不确定。将反射数据缓存在静态地图中是一个好主意吗?有没有其他方法可以实现这个目标?
答案 0 :(得分:2)
理想情况下,我会使用带有弱键的Guava缓存,这样您就不会保留对类对象的任何引用,以防您使用某些高级ClassLoader魔法。
LoadingCache<Class<?>, String> tableNames = CacheBuilder.newBuilder()
.weakKeys()
.build(
new CacheLoader<Class<?>, String>() {
public String load(Class<?> key) {
Table table = objClass.getAnnotation(Table.class);
return table == null ? key.getSimpleName() : table.name();
}
});
用法:
String tablename = tableNames.get(yourClass);
请参阅:Caches Explained
另一方面:注释也由JDK缓存,所以你以前的方法可能很好