2009-03-11 15 views
26

Hibernateでモデルのテーブル名を取得するにはどうすればよいですか?Hibernateでモデルからテーブル名を取得

ClassMetadataにはgetTableName()の方法がありましたが、削除されています。

ConfigurationにはgetClassMapping(String entityName)メソッドがありますが、私のDAO実装内からどのように(または私が)設定を使用できるかわかりません。

私のDAOの実装はHibernateGeneralGenericDaoのサブクラスです。

更新日:私はテーブル名なしでやろうとしていることができます。しかし、私は参考のため質問を開いたままにしておきます。

答えて

0

おそらくSessionFactory.getClassMetadataを使用しますか?あなたはあなたにいくつかのマッピング情報を与える特定のタイプのためのGetClassMapping()メソッドを呼び出すことができ、コンフィギュレーションを使用して

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

はい、私はそれを試みましたが、ClassMetadataはテーブルに関する情報を含んでいないようです –

17

あなたはこのような何かを行うことができますそのタイプの

(少なくとも、これはNHibernateの場合ですが、これはHibernateでも同様です)。

+0

私はそうではありません(正直なところ、私は注釈について学んだだけですが)。ありがとう。 –

+9

これは、すべてのエンティティでテーブル注釈を設定した場合にのみ有効です。あなたがしなければHibernateは完全にうまく動作します(それは実体名から名前を派生します) – Justin

1

:あなたは表の注釈を使用している場合

+0

はい、どうやってConfigurationを使いますか?新しいインスタンスを作成することはできますか? –

+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

5行目の末尾に余分なカッコがあります。十分な評判を持つ人はそれを修正すべきです。また、https://meta.stackoverflow.com/questions/251580/what-is-the-reason-behind-the-6-character-minimum-for-suggested-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

またはすべての列のリストを表示し、 GUIのすべてのエンティティ、テーブル、エンティティ、属性、カラム名、タイプ、セッター、ゲッター、さらには素敵なラベルを動的にロードする必要がありました。これは、@Tom RedfemソリューションリファクタJavaの8ストリームとED:

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

と2つの文字列ヘルパーメソッドこのポスト

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; 

ストリームを少しでも最適化できますが、私にとっては非常に高速で簡単です。

関連する問題