Browse Source

Pull request #6: DEC-14578 feat: 使hibernate支持主键的自动更新

Merge in QFX/base-third from ~ELIJAH/qfx-base-third:qufenxi to qufenxi

* commit '407627bf4386296c22f80ae512612c42a4b40d7b':
  DEC-14578 feat: 使hibernate支持主键的自动更新
release/10.0
Elijah 4 years ago
parent
commit
ea2a5e6a89
  1. 9
      fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/Dialect.java
  2. 5
      fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/MySQLDialect.java
  3. 69
      fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/internal/AbstractSchemaMigrator.java
  4. 3
      fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/internal/GroupedSchemaMigratorImpl.java
  5. 3
      fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/internal/IndividuallySchemaMigratorImpl.java
  6. 63
      fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/internal/StandardPrimaryKeyExporter.java

9
fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/Dialect.java

@ -1601,11 +1601,11 @@ public abstract class Dialect implements ConversionContext {
* Build an instance of a {@link SQLExceptionConversionDelegate} for
* interpreting dialect-specific error or SQLState codes.
* <p/>
* When {@link #buildSQLExceptionConverter} returns null, the default
* When {@link #buildSQLExceptionConverter} returns null, the default
* {@link SQLExceptionConverter} is used to interpret SQLState and
* error codes. If this method is overridden to return a non-null value,
* the default {@link SQLExceptionConverter} will use the returned
* {@link SQLExceptionConversionDelegate} in addition to the following
* {@link SQLExceptionConversionDelegate} in addition to the following
* standard delegates:
* <ol>
* <li>a "static" delegate based on the JDBC 4 defined SQLException hierarchy;</li>
@ -2099,6 +2099,11 @@ public abstract class Dialect implements ConversionContext {
return " add constraint " + constraintName + " primary key ";
}
public String getDropPrimaryKeyConstraintString(String constraintName) {
return " drop constraint " + constraintName;
}
/**
* Does the database/driver have bug in deleting rows that refer to other rows being deleted in the same query?
*

5
fine-hibernate/src/main/java/com/fr/third/org/hibernate/dialect/MySQLDialect.java

@ -244,6 +244,11 @@ public class MySQLDialect extends Dialect {
return " drop foreign key ";
}
@Override
public String getDropPrimaryKeyConstraintString(String constraintName) {
return " drop primary key ";
}
@Override
public LimitHandler getLimitHandler() {
return LIMIT_HANDLER;

69
fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/internal/AbstractSchemaMigrator.java

@ -6,12 +6,6 @@
*/
package com.fr.third.org.hibernate.tool.schema.internal;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.fr.third.org.hibernate.boot.Metadata;
import com.fr.third.org.hibernate.boot.model.naming.Identifier;
import com.fr.third.org.hibernate.boot.model.relational.AuxiliaryDatabaseObject;
@ -26,17 +20,21 @@ import com.fr.third.org.hibernate.engine.config.spi.StandardConverters;
import com.fr.third.org.hibernate.engine.jdbc.internal.FormatStyle;
import com.fr.third.org.hibernate.engine.jdbc.internal.Formatter;
import com.fr.third.org.hibernate.internal.util.StringHelper;
import com.fr.third.org.hibernate.mapping.Column;
import com.fr.third.org.hibernate.mapping.Constraint;
import com.fr.third.org.hibernate.mapping.ForeignKey;
import com.fr.third.org.hibernate.mapping.Index;
import com.fr.third.org.hibernate.mapping.PrimaryKey;
import com.fr.third.org.hibernate.mapping.Table;
import com.fr.third.org.hibernate.mapping.UniqueKey;
import com.fr.third.org.hibernate.resource.transaction.spi.DdlTransactionIsolator;
import com.fr.third.org.hibernate.tool.hbm2ddl.UniqueConstraintSchemaUpdateStrategy;
import com.fr.third.org.hibernate.tool.schema.extract.spi.ColumnInformation;
import com.fr.third.org.hibernate.tool.schema.extract.spi.DatabaseInformation;
import com.fr.third.org.hibernate.tool.schema.extract.spi.ForeignKeyInformation;
import com.fr.third.org.hibernate.tool.schema.extract.spi.IndexInformation;
import com.fr.third.org.hibernate.tool.schema.extract.spi.NameSpaceTablesInformation;
import com.fr.third.org.hibernate.tool.schema.extract.spi.PrimaryKeyInformation;
import com.fr.third.org.hibernate.tool.schema.extract.spi.SequenceInformation;
import com.fr.third.org.hibernate.tool.schema.extract.spi.TableInformation;
import com.fr.third.org.hibernate.tool.schema.internal.exec.GenerationTarget;
@ -48,9 +46,15 @@ import com.fr.third.org.hibernate.tool.schema.spi.SchemaFilter;
import com.fr.third.org.hibernate.tool.schema.spi.SchemaManagementException;
import com.fr.third.org.hibernate.tool.schema.spi.SchemaMigrator;
import com.fr.third.org.hibernate.tool.schema.spi.TargetDescriptor;
import com.fr.third.org.jboss.logging.Logger;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.fr.third.org.hibernate.cfg.AvailableSettings.UNIQUE_CONSTRAINT_SCHEMA_UPDATE_STRATEGY;
/**
@ -446,6 +450,57 @@ public abstract class AbstractSchemaMigrator implements SchemaMigrator {
return tableInformation.getForeignKey( Identifier.toIdentifier( foreignKey.getName() ) );
}
protected void applyPrimaryKey(
Table table,
TableInformation tableInfo,
Dialect dialect,
Metadata metadata,
Formatter formatter,
ExecutionOptions options,
GenerationTarget... targets) {
try {
PrimaryKey primaryKey = table.getPrimaryKey();
if (primaryKey == null) {
return;
}
Exporter<PrimaryKey> exporter = new StandardPrimaryKeyExporter(dialect);
PrimaryKeyInformation existedPrimaryKeyInfo = tableInfo.getPrimaryKey();
if (existedPrimaryKeyInfo == null) {
applySqlStrings(true, exporter.getSqlCreateStrings(primaryKey, metadata), formatter, options, targets);
} else if (!columnEquals(table.getPrimaryKey().getColumns(), existedPrimaryKeyInfo.getColumns())) {
//主键列不匹配, 先删再增
PrimaryKey deletedKey = copyPrimaryKey(tableInfo.getPrimaryKey().getPrimaryKeyIdentifier().getText(), table);
applySqlStrings(true, exporter.getSqlDropStrings(deletedKey, metadata), formatter, options, targets);
applySqlStrings(true, exporter.getSqlCreateStrings(primaryKey, metadata), formatter, options, targets);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
private PrimaryKey copyPrimaryKey(String newName, Table table) {
PrimaryKey copy = new PrimaryKey(table);
copy.setName(newName);
return copy;
}
private boolean columnEquals(List<Column> columns, Iterable<ColumnInformation> iterator) {
int count = 0;
Set<String> names = new HashSet<String>();
for (Column column: columns) {
names.add(column.getName().toLowerCase());
}
for (ColumnInformation columnInformation : iterator) {
String name = columnInformation.getColumnIdentifier().getText();
if (!names.contains(name.toLowerCase())) {
return false;
}
count++;
}
return count == columns.size();
}
protected void checkExportIdentifier(Exportable exportable, Set<String> exportIdentifiers) {
final String exportIdentifier = exportable.getExportIdentifier();
if ( exportIdentifiers.contains( exportIdentifier ) ) {

3
fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/internal/GroupedSchemaMigratorImpl.java

@ -83,6 +83,9 @@ public class GroupedSchemaMigratorImpl extends AbstractSchemaMigrator {
if ( tableInformation == null || ( tableInformation != null && tableInformation.isPhysicalTable() ) ) {
applyIndexes( table, tableInformation, dialect, metadata, formatter, options, targets );
applyUniqueKeys( table, tableInformation, dialect, metadata, formatter, options, targets );
if (tableInformation != null) {
applyPrimaryKey(table, tableInformation, dialect, metadata, formatter, options, targets);
}
}
}
}

3
fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/internal/IndividuallySchemaMigratorImpl.java

@ -83,6 +83,9 @@ public class IndividuallySchemaMigratorImpl extends AbstractSchemaMigrator {
if ( tableInformation == null || ( tableInformation != null && tableInformation.isPhysicalTable() ) ) {
applyIndexes( table, tableInformation, dialect, metadata, formatter, options, targets );
applyUniqueKeys( table, tableInformation, dialect, metadata, formatter, options, targets );
if (tableInformation != null) {
applyPrimaryKey(table, tableInformation, dialect, metadata, formatter, options, targets);
}
}
}
}

63
fine-hibernate/src/main/java/com/fr/third/org/hibernate/tool/schema/internal/StandardPrimaryKeyExporter.java

@ -0,0 +1,63 @@
package com.fr.third.org.hibernate.tool.schema.internal;
import com.fr.third.org.hibernate.boot.Metadata;
import com.fr.third.org.hibernate.dialect.Dialect;
import com.fr.third.org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import com.fr.third.org.hibernate.mapping.Column;
import com.fr.third.org.hibernate.mapping.PrimaryKey;
import com.fr.third.org.hibernate.tool.schema.spi.Exporter;
import java.util.Iterator;
/**
* @author Elijah
* @version 10.5
* Created by Elijah on 2020/9/30
*/
public class StandardPrimaryKeyExporter implements Exporter<PrimaryKey> {
private Dialect dialect;
public StandardPrimaryKeyExporter(Dialect dialect) {
this.dialect = dialect;
}
@Override
public String[] getSqlCreateStrings(PrimaryKey primaryKey, Metadata metadata) {
final JdbcEnvironment jdbcEnvironment = metadata.getDatabase().getJdbcEnvironment();
final String tableName = jdbcEnvironment.getQualifiedObjectNameFormatter().format(
primaryKey.getTable().getQualifiedTableName(),
dialect
);
final String constraintName = dialect.quote( primaryKey.getName() );
return new String[]{ "alter table " + tableName + dialect.getAddPrimaryKeyConstraintString(constraintName) + " " + columnsToString( primaryKey ) };
}
protected String columnsToString(PrimaryKey primaryKey) {
final StringBuilder sb = new StringBuilder();
sb.append( " (" );
final Iterator<Column> columnIterator = primaryKey.columnIterator();
while ( columnIterator.hasNext() ) {
final Column column = columnIterator.next();
sb.append( column.getQuotedName( dialect ) );
if ( columnIterator.hasNext() ) {
sb.append( ", " );
}
}
return sb.append( ')' ).toString();
}
@Override
public String[] getSqlDropStrings(PrimaryKey primaryKey, Metadata metadata) {
final JdbcEnvironment jdbcEnvironment = metadata.getDatabase().getJdbcEnvironment();
final String tableName = jdbcEnvironment.getQualifiedObjectNameFormatter().format(
primaryKey.getTable().getQualifiedTableName(),
dialect
);
final StringBuilder buf = new StringBuilder( "alter table " );
buf.append( tableName );
buf.append(dialect.getDropPrimaryKeyConstraintString(dialect.quote( primaryKey.getName())));
return new String[] { buf.toString() };
}
}
Loading…
Cancel
Save