Получить имя таблицы из модели в Hibernate
Как получить имя таблицы для модели в Hibernate?
По-видимому, в ClassMetadata
использовался getTableName()
, но он был удален.
Здесь getClassMapping(String entityName)
метод в Configuration
, но я не знаю, как я могу (или если я должен) использовать конфигурацию из моей реализации DAO.
Моя реализация DAO является подклассом HibernateGeneralGenericDao.
ОБНОВЛЕНИЕ: Оказывается, я могу сделать то, что я пытаюсь сделать, без имени таблицы. Тем не менее, я буду держать вопрос открытым (и попробуйте ответы, когда они приходят) для справки.
Ответы
Ответ 1
Немного странно, но он работает:
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();
}
Ответ 2
Если вы используете аннотацию таблицы, вы можете сделать что-то вроде этого:
Table table = Entity.class.getAnnotation(Table.class);
String tableName = table.name();
Ответ 3
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());
Ответ 4
Используя конфигурацию, вы можете вызвать метод GetClassMapping() для определенного типа, который предоставит вам некоторую информацию о сопоставлении для этого типа.
(По крайней мере, так обстоит дело в NHibernate, но я полагаю, что это будет похоже на Hibernate).
Ответ 5
или отображение списка всех столбцов и всех объектов в графическом интерфейсе, мне нужно было загружать полный список таблиц, сущностей, атрибутов и имен столбцов, типов, сеттеров, геттеров и даже хороших ярлыков динамически и что я сделал это основанный на решении @Tom Redfem, рефакторинг с потоком java 8:
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));
}
}
и два метода вспомогательных строк для создания ярлыков, которые могут быть неактуальны для этого сообщения
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 я получаю сеанс factory
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder builder =
new LocalSessionFactoryBuilder(dataSource());
builder.addProperties(hibernateProperties());
builder.scanPackages(new String[] { "com....model" });
SessionFactory sessionFactory = builder.buildSessionFactory();
return sessionFactory;
}
Возможно, мы можем немного оптимизировать потоки, но для меня это было довольно быстро и легко.
Ответ 6
возможно использовать SessionFactory.getClassMetadata?
Ответ 7
Вы можете получить каждое имя таблицы в своем проекте с помощью этой функции:
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;
}