2009-03-11 4 views
26

Как получить имя таблицы для модели в Hibernate?Получить имя таблицы из модели в Hibernate

По-видимому, когда-то был getTableName() метод в ClassMetadata, но он был удален.

Существует getClassMapping(String entityName) метод в Configuration, но я не знаю, как я могу (или если я должен) использовать Конфигурация из моей реализации DAO.

Моя реализация DAO является подклассом HibernateGeneralGenericDao.

UPDATE: Оказывается, я могу делать то, что я пытаюсь сделать, без имени таблицы. Тем не менее, я буду держать вопрос открытым (и попробуйте ответы, когда они приходят) для справки.

ответ

0

Возможно использование SessionFactory.getClassMetadata?

+0

Да, я пробовал это, но ClassMetadata, похоже, не содержит никакой информации о таблице –

17

Если вы используете таблицу аннотацию вы могли бы сделать что-то вроде этого:

Table table = Entity.class.getAnnotation(Table.class); 
String tableName = table.name(); 
+0

Я не (и, честно говоря, я только что узнал об аннотации), но это хорошая идея. Благодарю. –

+9

Справедливо, что это работает, только если вы задаете аннотацию таблицы для каждого объекта.Hibernate работает отлично, если вы этого не делаете (он получает имя от имени сущности) – Justin

1

Использование конфигурации, вы можете вызвать метод GetClassMapping() для конкретного типа, который даст вам некоторую информацию отображения для этого типа.

(По крайней мере, это так в NHibernate, но я полагаю, что это будет похоже на Hibernate).

+0

Да, но как использовать конфигурацию? Могу ли я просто создать новый экземпляр? –

+0

Некоторые параметры - создать новый экземпляр, например, во время инициализации; держите его неподвижным или одиночным; или использовать рефлексию, чтобы захватить ее из SessionFactory. Как только у вас есть конфигурация: configuration.getClassMapping ("foo"). GetTable(). GetName(); –

32

Это немного странно, но это работает:

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

В конце пятой строки есть дополнительная скобка. Кто-то с достаточной репутацией должен это исправить. Кроме того, посмотрите и подумайте о https://meta.stackoverflow.com/questions/251580/what-is-the-reason-behind- the-character-minimum-for-welcome-edits и https: // meta. stackoverflow.com/questions/277184/why-is-it-necessary-for-me-to-write-6-character-if-just-one-is-missing-and-what –

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()); 
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; 
} 
1

или отображение списка всех столбцов и все объекты в графическом интерфейсе, мне нужно было загрузить полный список таблиц, сущностей, атрибутов и имен столбцов, типов, сеттеров, геттеров и даже хороших ярлыков динамически, и именно так я сделал это на основе рефакторинга @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 я получаю сессионную фабрику

public SessionFactory sessionFactory() { 
    LocalSessionFactoryBuilder builder = 
      new LocalSessionFactoryBuilder(dataSource()); 
    builder.addProperties(hibernateProperties()); 
    builder.scanPackages(new String[] { "com....model" }); 
    SessionFactory sessionFactory = builder.buildSessionFactory(); 

    return sessionFactory; 

}

Возможно, мы можем оптимизировать потоки немного больше, но для меня это было довольно быстро и просто.

Смежные вопросы