sql >> Database teknologi >  >> RDS >> Oracle

Sæt automatisk nøglegenerering i dvale med MySQL og Oracle

Også selvom du brugte GenerationType.AUTO uden nogen SEQUENCE-specifik parameter, ville du ikke være i stand til at gemme tildelte identifikatorer.

Der er nogle løsninger, hvis du er villig til at indgå nogle kompromiser:

  1. En måde ville være at skifte til de tildelte identifikatorer. Du kan bruge UUID identifikatorer, som fungerer for både MySQL og Oracle, og du kan også tildele værdierne manuelt.

  2. En anden måde er at bruge en brugerdefineret tabelgenerator.

Først definerer du en identificerbar grænseflade:

    public interface Identifiable<T extends Serializable> {
        T getId();
    }

Så udvider du tabelgeneratoren:

    public class AssignedTableGenerator extends TableGenerator {

        @Override
        public Serializable generate(SessionImplementor session, Object obj) {
            if(obj instanceof Identifiable) {
                Identifiable identifiable = (Identifiable) obj;
                Serializable id = identifiable.getId();
                if(id != null) {
                    return id;
                }
            }
            return super.generate(session, obj);
        }
    }

Denne generator er i stand til at blande tildelte identifikatorer med syntetisk genererede:

    doInTransaction(session -> {
        for (int i = 0; i < 5; i++) {
            session.persist(new AssignTableSequenceIdentifier());
        }
        AssignTableSequenceIdentifier tableSequenceIdentifier = new AssignTableSequenceIdentifier();
        tableSequenceIdentifier.id = -1L;
        session.merge(tableSequenceIdentifier);
        session.flush();
    });

generere følgende udsagn:

    select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
    insert into sequence_table (sequence_name, next_val)  values (default,1)
    update sequence_table set next_val=2  where next_val=1 and sequence_name=default
    select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
    update sequence_table set next_val=3  where next_val=2 and sequence_name=default
    select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
    update sequence_table set next_val=4  where next_val=3 and sequence_name=default
    select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
    update sequence_table set next_val=5  where next_val=4 and sequence_name=default
    select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for update
    update sequence_table set next_val=6  where next_val=5 and sequence_name=default
    select identityvs0_.id as id1_0_0_ from assigneTableIdentifier identityvs0_ where identityvs0_.id=-1
    insert into assigneTableIdentifier (id) values (1, 2)
    insert into assigneTableIdentifier (id) values (2, 4)
    insert into assigneTableIdentifier (id) values (5, -1)

For Oracle kan du kombinere SEQUENCE og de tildelte generatorer. Kort sagt, i betragtning af følgende generator:

public class AssignedSequenceStyleGenerator 
    extends SequenceStyleGenerator {
 
    @Override
    public Serializable generate(SessionImplementor session, 
        Object obj) {
        if(obj instanceof Identifiable) {
            Identifiable identifiable = (Identifiable) obj;
            Serializable id = identifiable.getId();
            if(id != null) {
                return id;
            }
        }
        return super.generate(session, obj);
    }
}

Du kan tilknytte det til dine enheder som følger:

@Id
@GenericGenerator(
    name = "assigned-sequence",
    strategy = "com.vladmihalcea.book.hpjp.hibernate.identifier.AssignedSequenceStyleGenerator",
    parameters = @org.hibernate.annotations.Parameter(
        name = "sequence_name", 
        value = "post_sequence"
    )
)
@GeneratedValue(
    generator = "assigned-sequence", 
    strategy = GenerationType.SEQUENCE
)
private Long id;

Al koden er tilgængelig på GitHub og fungerer som en charme.



  1. syntaksfejl ved erklæring af variabler i en pl/sql-procedure

  2. Hvordan importerer du en stor MS SQL .sql-fil?

  3. Lagre en fil i en database i modsætning til filsystemet?

  4. 4 måder at kontrollere, om en tabel eksisterer, før du dropper den i SQL Server (T-SQL)