Java 从 Hibernate 中的模型中获取表名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/634342/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 17:12:44  来源:igfitidea点击:

Get the table name from the model in Hibernate

javahibernate

提问by Can Berk Güder

How do I get the table name for a model in Hibernate?

如何在 Hibernate 中获取模型的表名?

Apparently there used to be a getTableName()method in ClassMetadata, but it's been removed.

显然曾经有一个getTableName()方法ClassMetadata,但它已被删除。

There's a getClassMapping(String entityName)method in Configuration, but I don't know how I can (or if I should) use Configuration from within my DAO implementation.

中有一个getClassMapping(String entityName)方法Configuration,但我不知道如何(或是否应该)从我的 DAO 实现中使用 Configuration。

My DAO implementation is a subclass of HibernateGeneralGenericDao.

我的 DAO 实现是HibernateGeneralGenericDao的子类。

UPDATE:It turns out I can do what I'm trying to do without the table name. However, I will keep the question open (and try the answers as they come) for the sake of reference.

更新:事实证明,我可以在没有表名的情况下做我想做的事情。但是,为了参考,我将保持问题开放(并尝试答案)。

回答by Michael Pralow

回答by Alex Rockwell

If you're using the Table annotation you could do something like this:

如果您使用的是 Table 注释,您可以执行以下操作:

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

回答by Frederik Gheysels

Using the Configuration, you can call the GetClassMapping() method for a specific type, which would give you some mapping information for that type.

使用配置,您可以为特定类型调用 GetClassMapping() 方法,这将为您提供该类型的一些映射信息。

(At least, this is the case in NHibernate, but I suppose that this will be similar in Hibernate).

(至少,这是 NHibernate 的情况,但我想这在 Hibernate 中会类似)。

回答by FoxyBOA

It's a bit weird but it works:

这有点奇怪,但它有效:

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

回答by FoxyBOA

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

回答by Anthony Raymond

You can get every tables name in your project with this function :

您可以使用此功能获取项目中的每个表名称:

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

回答by Shilan

or displaying a list of all columns and all entities in the GUI, I needed to load a full list of table, entity, attributes and column names, types, setters, getters and even nice labels dynamically and that's how I did it based on @Tom Redfem solution refactored with java 8 stream:

或者在 GUI 中显示所有列和所有实体的列表,我需要动态加载表、实体、属性和列名、类型、setter、getter 甚至漂亮标签的完整列表,这就是我基于 @ 所做的使用 java 8 流重构的 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));
        ;

}

and then createNewParam method is:

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

and two String helper method to generate nice labels, which can be irrelevant to this post

和两个 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);
}

And of course in my WebAppConfig.class I get the session factory

当然,在我的 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;

}

}

Maybe we can optimize streams a little bit more, but for me it was quite fast and easy.

也许我们可以再优化一下流,但对我来说这非常快速和容易。