博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
聊聊hibernate的hbm2ddl的实现
阅读量:6496 次
发布时间:2019-06-24

本文共 7200 字,大约阅读时间需要 24 分钟。

本文主要研究下hibernate的hbm2ddl

SchemaManagementTool

hibernate-core-5.0.12.Final-sources.jar!/org/hibernate/tool/schema/spi/SchemaManagementTool.java

public interface SchemaManagementTool extends Service {    public SchemaCreator getSchemaCreator(Map options);    public SchemaDropper getSchemaDropper(Map options);    public SchemaMigrator getSchemaMigrator(Map options);    public SchemaValidator getSchemaValidator(Map options);}复制代码

这个tool定义了create、drop、migrate、validate四个功能。

SchemaCreatorImpl

hibernate-core-5.0.12.Final-sources.jar!/org/hibernate/tool/schema/internal/SchemaCreatorImpl.java

public class SchemaCreatorImpl implements SchemaCreator {    @Override    public void doCreation(Metadata metadata, boolean createNamespaces, List
targets) throws SchemaManagementException { doCreation( metadata, createNamespaces, targets.toArray( new Target[ targets.size() ] ) ); } //......}复制代码

主要逻辑在doCreation里头,里头按如下顺序创建:

  • 创建catalog/schema
  • 创建before table auxiliary objects
  • 创建sequences
  • 创建tables
    • 创建indexes
    • 创建uniques
  • 创建foreign keys
  • 创建after table auxiliary objects

它们又主要借助dialect的各种exporter来实现

Dialect

hibernate-core-5.0.12.Final-sources.jar!/org/hibernate/dialect/Dialect.java

public abstract class Dialect implements ConversionContext {    //......    // DDL support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    private StandardTableExporter tableExporter = new StandardTableExporter( this );    private StandardSequenceExporter sequenceExporter = new StandardSequenceExporter( this );    private StandardIndexExporter indexExporter = new StandardIndexExporter( this );    private StandardForeignKeyExporter foreignKeyExporter = new StandardForeignKeyExporter( this );    private StandardUniqueKeyExporter uniqueKeyExporter = new StandardUniqueKeyExporter( this );    private StandardAuxiliaryDatabaseObjectExporter auxiliaryObjectExporter = new StandardAuxiliaryDatabaseObjectExporter( this );    //......}复制代码

这里定义了table、sequence、index、foreign key、unique key、auxiliary database object的exporter

StandardTableExporter

hibernate-core-5.0.12.Final-sources.jar!/org/hibernate/tool/schema/internal/StandardTableExporter.java

public class StandardTableExporter implements Exporter
sqlStrings = new ArrayList
(); sqlStrings.add( buf.toString() ); applyComments( table, tableName, sqlStrings ); applyInitCommands( table, sqlStrings ); return sqlStrings.toArray( new String[ sqlStrings.size() ] ); }}复制代码
{ //..... @Override public String[] getSqlCreateStrings(Table table, Metadata metadata) { final QualifiedName tableName = new QualifiedNameParser.NameParts( Identifier.toIdentifier( table.getCatalog(), table.isCatalogQuoted() ), Identifier.toIdentifier( table.getSchema(), table.isSchemaQuoted() ), table.getNameIdentifier() ); final JdbcEnvironment jdbcEnvironment = metadata.getDatabase().getJdbcEnvironment(); StringBuilder buf = new StringBuilder( tableCreateString( table.hasPrimaryKey() ) ) .append( ' ' ) .append( jdbcEnvironment.getQualifiedObjectNameFormatter().format( tableName, jdbcEnvironment.getDialect() ) ) .append( " (" ); boolean isPrimaryKeyIdentity = table.hasPrimaryKey() && table.getIdentifierValue() != null && table.getIdentifierValue().isIdentityColumn( metadata.getIdentifierGeneratorFactory(), dialect ); // this is the much better form moving forward as we move to metamodel //boolean isPrimaryKeyIdentity = hasPrimaryKey // && table.getPrimaryKey().getColumnSpan() == 1 // && table.getPrimaryKey().getColumn( 0 ).isIdentity(); // Try to find out the name of the primary key in case the dialect needs it to create an identity String pkColName = null; if ( table.hasPrimaryKey() ) { Column pkColumn = (Column) table.getPrimaryKey().getColumns().iterator().next(); pkColName = pkColumn.getQuotedName( dialect ); } final Iterator columnItr = table.getColumnIterator(); boolean isFirst = true; while ( columnItr.hasNext() ) { final Column col = (Column) columnItr.next(); if ( isFirst ) { isFirst = false; } else { buf.append( ", " ); } String colName = col.getQuotedName( dialect ); buf.append( colName ).append( ' ' ); if ( isPrimaryKeyIdentity && colName.equals( pkColName ) ) { // to support dialects that have their own identity data type if ( dialect.getIdentityColumnSupport().hasDataTypeInIdentityColumn() ) { buf.append( col.getSqlType( dialect, metadata ) ); } buf.append( ' ' ) .append( dialect.getIdentityColumnSupport().getIdentityColumnString( col.getSqlTypeCode( metadata ) ) ); } else { buf.append( col.getSqlType( dialect, metadata ) ); String defaultValue = col.getDefaultValue(); if ( defaultValue != null ) { buf.append( " default " ).append( defaultValue ); } if ( col.isNullable() ) { buf.append( dialect.getNullColumnString() ); } else { buf.append( " not null" ); } } if ( col.isUnique() ) { String keyName = Constraint.generateName( "UK_", table, col ); UniqueKey uk = table.getOrCreateUniqueKey( keyName ); uk.addColumn( col ); buf.append( dialect.getUniqueDelegate() .getColumnDefinitionUniquenessFragment( col ) ); } if ( col.getCheckConstraint() != null && dialect.supportsColumnCheck() ) { buf.append( " check (" ) .append( col.getCheckConstraint() ) .append( ")" ); } String columnComment = col.getComment(); if ( columnComment != null ) { buf.append( dialect.getColumnComment( columnComment ) ); } } if ( table.hasPrimaryKey() ) { buf.append( ", " ) .append( table.getPrimaryKey().sqlConstraintString( dialect ) ); } buf.append( dialect.getUniqueDelegate().getTableCreationUniqueConstraintsFragment( table ) ); applyTableCheck( table, buf ); buf.append( ')' ); if ( table.getComment() != null ) { buf.append( dialect.getTableComment( table.getComment() ) ); } applyTableTypeString( buf ); List

上面的sql生成具体还根据传入的dialect来实现不同数据库的语句的区别。

小结

要实现一个ddl的功能,一个要有不同的dialect来屏蔽不同数据库的区别,另外一个就是需要创建索引、序列、主键、外键等相关的对象,其他的就是字段类型的映射。

转载地址:http://nvuyo.baihongyu.com/

你可能感兴趣的文章
python__高级 : 动态添加 对象属性, 类属性, 对象实例方法, 类静态方法, 类方法...
查看>>
【每天一道算法题】时间复杂度为O(n)的排序
查看>>
NLog的介绍使用
查看>>
Haproxy+Rabbitmq中的问题
查看>>
字符串变量小议
查看>>
232. Implement Queue using Stacks
查看>>
Poj(1469),二分图最大匹配
查看>>
和菜鸟一起学linux之V4L2摄像头应用流程【转】
查看>>
spin_lock、spin_lock_irq、spin_lock_irqsave区别【转】
查看>>
删除 mac 垃圾桶内清除不掉的文件
查看>>
【响应式编程的思维艺术】 (5)Angular中Rxjs的应用示例
查看>>
/bin/bash^M: bad interpreter: No such file or dire
查看>>
python xml rpc
查看>>
Java设置以及获取JavaBean私有属性进阶
查看>>
db2表结构导出导入,数据库备份
查看>>
策略模式
查看>>
第二 周作业总结
查看>>
OrderOnline——项目概述
查看>>
POJ-2739(Water)
查看>>
【转】第三节 UNIX文件系统结构
查看>>