java – 如何从Hibernate MetadataSources中发现完全限定的表列

我有一个实体,我有一个Class< MyEntity>参考:
@Entity
class MyEntity {
    @Id int id;
    @Column String col1;
    @Column(name = "abc") String col2;
}

我目前正在使用Hibernate将我的实体导出到内存数据库中,如下所示:

MetadataSources Metadata = new MetadataSources(...);
Metadata.addAnnotatedClass(MyEntity.class);
SchemaExport export = new SchemaExport();
export.create(EnumSet.of(TargetType.DATABASE),Metadata.buildMetadata());

Details about the Hibernate-specific API here.

有没有可靠的方法通过Hibernate API从MyEntity.col2(带注释的Java字段引用)到数据库中的完全限定列名(反之亦然)获取映射?在没有明确限定的情况下,我想避免重新实现Java标识符(包括getter和setter)如何映射到sql标识符的所有细节.

解决方法

这是一个非常好的问题,所以我决定将 an article用于更详细地回答它.

org.hibernate.boot.Metadata是我们感兴趣的,因为它包含PersistentClass实体绑定.

首先,您需要创建一个Integrator来访问元数据:

public class MetadataExtractorIntegrator 
    implements org.hibernate.integrator.spi.Integrator {

    public static final MetadataExtractorIntegrator INSTANCE = 
        new MetadataExtractorIntegrator();

    private Database database;

    private Metadata Metadata;

    public Database getDatabase() {
        return database;
    }

    public Metadata getMetadata() {
        return Metadata;
    }

    @Override
    public void integrate(
            Metadata Metadata,SessionFactoryImplementor sessionFactory,SessionFactoryServiceRegistry serviceRegistry) {

        this.database = Metadata.getDatabase();
        this.Metadata = Metadata;

    }

    @Override
    public void disintegrate(
        SessionFactoryImplementor sessionFactory,SessionFactoryServiceRegistry serviceRegistry) {

    }
}

如果您使用JPA,您可以按如下方式注册

Map<String,Object> configuration = new HashMap<>();

Integrator integrator = integrator();
if (integrator != null) {
    configuration.put("hibernate.integrator_provider",(IntegratorProvider) () -> Collections.singletonList(
            MetadataExtractorIntegrator.INSTANCE
        )
    );
}

EntityManagerFactory entityManagerFactory = new EntityManagerFactoryBuilderImpl(
    new PersistenceUnitInfoDescriptor(persistenceUnitInfo),configuration
)
.build();

现在,在运行以下测试用例时:

Metadata Metadata = MetadataExtractorIntegrator.INSTANCE.getMetadata();

for ( PersistentClass persistentClass : Metadata.getEntityBindings()) {

    Table table = persistentClass.getTable();

    LOGGER.info( "Entity: {} is mapped to table: {}",persistentClass.getClassName(),table.getName()
    );

    for(Iterator propertyIterator = persistentClass.getPropertyIterator(); 
            propertyIterator.hasNext(); ) {
        Property property = (Property) propertyIterator.next();

        for(Iterator columnIterator = property.getColumnIterator(); 
                columnIterator.hasNext(); ) {
            Column column = (Column) columnIterator.next();

            LOGGER.info( "Property: {} is mapped on table column: {} of type: {}",property.getName(),column.getName(),column.getsqlType()
            );
        }
    }
}

反对以下实体:

我们得到以下输出

Entity: com.vladmihalcea.book.hpjp.util.providers.entity.BlogEntityProvider$Tag is mapped to table: tag
Property: name is mapped on table column: name of type: varchar(255)
Property: version is mapped on table column: version of type: integer

Entity: com.vladmihalcea.book.hpjp.util.providers.entity.BlogEntityProvider$PostComment is mapped to table: post_comment
Property: post is mapped on table column: post_id of type: bigint
Property: review is mapped on table column: review of type: varchar(255)
Property: version is mapped on table column: version of type: integer

Entity: com.vladmihalcea.book.hpjp.util.providers.entity.BlogEntityProvider$Post is mapped to table: post
Property: title is mapped on table column: title of type: varchar(255)
Property: version is mapped on table column: version of type: integer

Entity: com.vladmihalcea.book.hpjp.util.providers.entity.BlogEntityProvider$PostDetails is mapped to table: post_details
Property: createdBy is mapped on table column: created_by of type: varchar(255)
Property: createdOn is mapped on table column: created_on of type: datetime(6)
Property: version is mapped on table column: version of type: integer

很酷,对吗?

您也可以查看此示例on GitHub.

相关文章

ArrayList简介:ArrayList 的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增...
一、进程与线程 进程:是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。 线程...
本文为博客园作者所写:&#160;一寸HUI,个人博客地址:https://www.cnblogs.com/zsql/ 简单的一个类...
#############java面向对象详解#############1、面向对象基本概念2、类与对象3、类和对象的定义格式4、...
一、什么是异常? 异常就是有异于常态,和正常情况不一样,有错误出错。在java中,阻止当前方法或作用域...
Collection接口 Collection接口 Collection接口 Collection是最基本的集合接口,一个Collection代表一组...