我有一个实体,我有一个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.