2009-03-11 35 views
26

Làm cách nào để lấy tên bảng cho một mô hình trong Hibernate?Lấy tên bảng từ mô hình trong Hibernate

Dường như đã từng là phương pháp getTableName() trong ClassMetadata nhưng đã bị xóa.

Có phương pháp getClassMapping(String entityName) trong Configuration, nhưng tôi không biết cách tôi có thể (hoặc nếu tôi nên) sử dụng Cấu hình từ bên trong triển khai DAO của tôi.

Triển khai DAO của tôi là một phân lớp của HibernateGeneralGenericDao.

CẬP NHẬT: Hóa ra tôi có thể làm những gì tôi đang cố gắng làm mà không có tên bảng. Tuy nhiên, tôi sẽ giữ câu hỏi mở (và thử các câu trả lời khi họ đến) để tham khảo.

Trả lời

0

có thể sử dụng SessionFactory.getClassMetadata?

+0

Có, tôi đã thử điều đó, nhưng ClassMetadata dường như không chứa bất kỳ thông tin nào liên quan đến bảng –

17

Nếu bạn đang sử dụng chú thích Bảng bạn có thể làm một cái gì đó như thế này:

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

Tôi không (và thành thật mà nói, tôi vừa học về chú thích), nhưng đây là một ý tưởng hay. Cảm ơn. –

+9

Chắc chắn điều này chỉ hoạt động nếu bạn đặt chú thích bảng trên mọi thực thể.Hibernate hoạt động hoàn hảo tốt nếu bạn không (nó có nguồn gốc tên từ tên thực thể) – Justin

1

Sử dụng Configuration, bạn có thể gọi phương thức GetClassMapping() cho một loại cụ thể, mà sẽ cung cấp cho bạn một số thông tin bản đồ cho loại đó.

(Ít nhất, đây là trường hợp trong NHibernate, nhưng tôi cho rằng điều này sẽ tương tự trong Hibernate).

+0

Có, nhưng làm cách nào để sử dụng Cấu hình? Tôi có thể tạo một phiên bản mới không? –

+0

Một số tùy chọn để tạo một cá thể mới như trong quá trình khởi tạo; giữ nó xung quanh như một tĩnh hoặc singleton; hoặc sử dụng sự phản chiếu để lấy nó từ SessionFactory. Khi bạn có cấu hình: configuration.getClassMapping ("foo"). GetTable(). GetName(); –

32

Đó là một chút lạ, nhưng nó hoạt động:

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

Có một dấu ngoặc đơn phụ gần cuối dòng thứ năm. Một người có đủ danh tiếng nên sửa nó. Ngoài ra, hãy xem và suy nghĩ về https://meta.stackoverflow.com/questions/251580/what-is-the-reason-behind-the-6-character-minimum-for-suggested-edits và 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

Bạn có thể nhận được tất cả tên bảng trong dự án của bạn với chức năng này:

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

hoặc hiển thị một danh sách của tất cả các cột và tất cả các thực thể trong GUI, tôi cần tải một danh sách đầy đủ của bảng, thực thể, thuộc tính và tên cột, kiểu, setters, getters và thậm chí cả các nhãn đẹp và đó là cách tôi đã làm nó dựa trên giải pháp @Tom Redfem refactor ed với java 8 dòng:

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

} 

và sau đó phương pháp createNewParam là:

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

và hai phương pháp Chuỗi helper để tạo nhãn đẹp, có thể không liên quan đến bài viết này

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

Và tất nhiên trong WebAppConfig.class của tôi, tôi nhận được phiên nhà máy

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

    return sessionFactory; 

}

Có lẽ chúng tôi có thể tối ưu hóa luồng nhiều hơn một chút, nhưng đối với tôi, nó khá nhanh và dễ dàng.

Các vấn đề liên quan