如何在Hibernate中获取模型的表名?
显然,ClassMetadata
中有getTableName()
方法,但它已被移除。
getClassMapping(String entityName)
中有一个Configuration
方法,但我不知道如何(或者我应该)在我的DAO实现中使用Configuration。
我的DAO实现是HibernateGeneralGenericDao的子类。
更新:事实证明,如果没有表名,我可以做我想做的事情。但是,为了便于参考,我会将问题保持开放(并尝试答案)。
答案 0 :(得分:34)
这有点奇怪,但它有效:
ClassMetadata hibernateMetadata = sessionFactory.getClassMetadata(pClassName);
if (hibernateMetadata == null)
{
return;
}
if (hibernateMetadata instanceof AbstractEntityPersister)
{
AbstractEntityPersister persister = (AbstractEntityPersister) hibernateMetadata;
String tableName = persister.getTableName();
String[] columnNames = persister.getKeyColumnNames();
}
答案 1 :(得分:22)
如果你正在使用表格注释,你可以这样做:
Table table = Entity.class.getAnnotation(Table.class);
String tableName = table.name();
答案 2 :(得分:2)
Configuration cfg = new Configuration().configure();
cfg.addResource("com/struts/Entities/User.hbm.xml");
cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
Mappings m=cfg.createMappings();
System.out.println(">> class: "+m.getClass(className));
System.out.println("User table name:: "+m.getClass("User").getTable().getName());
答案 3 :(得分:1)
使用Configuration,您可以为特定类型调用GetClassMapping()方法,该方法将为您提供该类型的一些映射信息。
(至少,NHibernate就是这种情况,但我认为这在Hibernate中是类似的。)
答案 4 :(得分:1)
或显示GUI中所有列和所有实体的列表,我需要动态加载表,实体,属性和列名称,类型,设置器,getter甚至漂亮标签的完整列表。我是如何基于使用java 8 stream重构的@Tom Redfem解决方案做到的:
public void loadHibernateMetadata() throws ClassNotFoundException {
Map<String, ClassMetadata> hibernateMetadata = sessionFactory.getAllClassMetadata();
hibernateMetadata.values()
.stream()
.filter(metadata -> metadata != null && metadata instanceof AbstractEntityPersister)
.map(AbstractEntityPersister.class::cast)
.forEach( persister -> createNewnParam(persister));
;
}
然后createNewParam方法是:
private void createNewParam(AbstractEntityPersister persister) {
try {
Class<?> $class = Class.forName(persister.getEntityName());
List<String> getterNameRoster = Lists.newArrayList($class.getMethods())
.stream()
.filter( method -> method.getName().startsWith("get") || method.getName().startsWith("is"))
.map(getterName -> getterName.getName())
.collect(toList())
;
List<String> setterNameRoster = Lists.newArrayList($class.getMethods())
.stream()
.filter( method -> method.getName().startsWith("set") )
.map(setterName -> setterName.getName())
.collect(toList())
;
Iterable<AttributeDefinition> attrs = persister.getAttributes();
attrs.forEach(a -> {
String columnName = persister.getPropertyColumnNames(a.getName())[0];
org.hibernate.type.Type hibernateType =persister.getPropertyType(a.getName());
Optional<String> optionalGetter = getterNameRoster.stream()
.filter(getterStr -> getterStr.equalsIgnoreCase( String.format("get%s", a.getName()) ) ||
getterStr.equalsIgnoreCase( String.format("is%s", a.getName())) )
.findFirst()
;
String getterName = optionalGetter.isPresent() ? optionalGetter.get() : new String("");
Optional<String> optionalSetter = setterNameRoster.stream()
.filter(setterStr -> setterStr.equalsIgnoreCase( String.format("set%s", a.getName()) ))
.findFirst()
;
String setterName = optionalSetter.isPresent() ? optionalSetter.get() : new String("");
Param param = new Param(persister.getEntityName(),
persister.getTableName().replaceAll("\"", "").toUpperCase(),
columnName.replaceAll("\"", "").toUpperCase(),
a.getName(),
getterName,
setterName,
hibernateType.getName(),
capitalizeFirstLetter(splitCamelCase(a.getName()))
);
hibernateParamList.add(param);
logger.debug(param.toString());
});
} catch (ClassNotFoundException e) {
logger.error(String.format("error occured generating the params %s" , e));
}
}
和两个String helper方法生成漂亮的标签,这可能与这篇文章无关
private String splitCamelCase(String s) {
return s.replaceAll(
String.format("%s|%s|%s",
"(?<=[A-Z])(?=[A-Z][a-z])",
"(?<=[^A-Z])(?=[A-Z])",
"(?<=[A-Za-z])(?=[^A-Za-z])"
),
" "
);
}
private String capitalizeFirstLetter(String s) {
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
}
当然,在我的WebAppConfig.class中,我得到了会话工厂
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder builder =
new LocalSessionFactoryBuilder(dataSource());
builder.addProperties(hibernateProperties());
builder.scanPackages(new String[] { "com....model" });
SessionFactory sessionFactory = builder.buildSessionFactory();
return sessionFactory;
}
也许我们可以更多地优化流,但对我而言,它非常快速和简单。
答案 5 :(得分:0)
答案 6 :(得分:0)
您可以使用此功能获取项目中的每个表名称:
public Set<String> getTablesName() {
Set<String> names = new HashSet<>();
SessionFactory sessionFactory = emf.unwrap(SessionFactory.class);
Map<String, ClassMetadata> classMetadataMap = sessionFactory.getAllClassMetadata();
for (ClassMetadata classMetadata : classMetadataMap.values()) {
AbstractEntityPersister aep = (AbstractEntityPersister) classMetadata;
String tableName = aep.getTableName();
if (StringUtils.isBlank(tableName) || StringUtils.containsWhitespace(tableName)) {
continue;
}
names.add(tableName);
}
return names;
}
答案 7 :(得分:0)
因为不赞成使用getClassMetadata方法。尝试这样的事情。
Configuration configuration = new Configuration();
configuration.configure();
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().configure().build();
Metadata = new MetadataSources(standardRegistry).getMetadataBuilder().build();
SessionFactory sessionFactory = configuration.buildSessionFactory();
String tableName=Metadata.getEntityBinding(entityName).getQualifiedTableName().toString();
答案 8 :(得分:0)
classMetadata
已弃用。
使用:
@PersistenceContext
private EntityManager entityManager;
public String extractTableName(final Class<?> modelClazz) {
final MetamodelImpl metamodel = (MetamodelImpl) entityManager.getMetamodel();
final EntityPersister entityPersister = metamodel.entityPersister(modelClazz);
if (entityPersister instanceof SingleTableEntityPersister) {
return ((SingleTableEntityPersister) entityPersister).getTableName();
} else {
throw new IllegalArgumentException(modelClazz + " does not map to a single table.");
}
}