如何从Hibernate MetadataSources发现完全合格的表列 [英] How to discover fully qualified table column from 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从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
很酷,对吧?
You can check out this example on GitHub as well.
这篇关于如何从Hibernate MetadataSources发现完全合格的表列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!