如何从Hibernate MetadataSources发现完全合格的表列 [英] How to discover fully qualified table column from Hibernate MetadataSources

查看:114
本文介绍了如何从Hibernate MetadataSources发现完全合格的表列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个实体,对此我有一个Class<MyEntity>引用:

I have an entity, for which I have a Class<MyEntity> reference:

@Entity
class MyEntity {
    @Id int id;
    @Column String col1;
    @Column(name = "abc") String col2;
}

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

I'm currently using Hibernate to export my entities into an in-memory database as such:

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

此处有关特定于Hibernate的API的详细信息.

是否有通过Hibernate API从MyEntity.col2(带注释的Java字段引用)到数据库中标准列名(反之亦然)的映射的可靠方法?我想避免重新实现在没有显式限定的情况下如何将Java标识符(包括getter和setter)映射到SQL标识符的所有微妙细节.

Is there any reliable way to get a mapping from MyEntity.col2 (the annotated Java field reference) to the fully qualified column name in the database (and vice versa) through Hibernate API? I'd like to avoid re-implementing all the delicate details of how Java identifiers (including getters and setters) are mapped to SQL identifiers in the absence of explicit qualification.

推荐答案

这是一个很好的问题,所以我决定专门

This is a very good question, so I decided to dedicate an article to answer it in more detail.

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

The org.hibernate.boot.Metadata is what we are interested in since it contains the PersistentClass entity bindings.

首先,您需要创建一个Integrator,它将使您可以访问Metadata:

First, you need to create an Integrator which will give you access to Metadata:

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,则可以按以下方式注册:

If you use JPA, you can register it as follows:

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

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

Now, when running the following test case:

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

很酷,对吧?

您也可以在GitHub上查看此示例

You can check out this example on GitHub as well.

这篇关于如何从Hibernate MetadataSources发现完全合格的表列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆