Sök…


Skapa och använda en anpassad ImplicitNamingStrategy

Skapa en anpassad ImplicitNamingStrategy låter dig justera hur Hibernate kommer att tilldela namn till icke-explicit namnges Entity attribut, inklusive främmande nycklar, unika nycklar, Identifier kolumner, Grundläggande kolumner och mycket mer.

Som standard genererar till exempel Hibernate utländska nycklar som är hashade och ser ut som:

FKe6hidh4u0qh8y1ijy59s2ee6m

Även om detta ofta inte är ett problem, kanske du önskar att namnet var mer beskrivande, till exempel:

FK_asset_tenant

Detta kan enkelt göras med en anpassad ImplicitNamingStrategy .

Detta exempel utökar ImplicitNamingStrategyJpaCompliantImpl , men du kan välja att implementera ImplicitNamingStrategy om du vill.

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ImplicitForeignKeyNameSource;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl;

public class CustomNamingStrategy extends ImplicitNamingStrategyJpaCompliantImpl {

    @Override
    public Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source) {
        return toIdentifier("FK_" + source.getTableName().getCanonicalName() + "_" + source.getReferencedTableName().getCanonicalName(), source.getBuildingContext());
    }

}

För att berätta för Viloläge vilken ImplicitNamingStrategy att använda definierar du hibernate.implicit_naming_strategy egenskapen i din persistence.xml eller hibernate.cfg.xml fil som nedan:

<property name="hibernate.implicit_naming_strategy"
                  value="com.example.foo.bar.CustomNamingStrategy"/>

Eller så kan du ange egenskapen i hibernate.properties fil enligt nedan:

hibernate.implicit_naming_strategy=com.example.foo.bar.CustomNamingStrategy

I det här exemplet kommer alla utländska nycklar som inte har ett uttryckligt definierat name nu att få sitt namn från CustomNamingStrategy .

Anpassad fysisk namnstrategi

När vi mappar våra enheter till databastabellnamn förlitar vi oss på en @Table kommentar. Men om vi har en namnkonvention för våra databastabellnamn, kan vi implementera en anpassad fysisk namngivningsstrategi för att säga viloläge att beräkna tabellnamn baserat på namnen på enheterna, utan att uttryckligen ange dessa namn med @Table kommentar. Samma sak gäller för attribut och kolumnkartläggning.

Till exempel är vårt enhetsnamn:

ApplicationEventLog

Och vårt bordnamn är:

application_event_log

Vår fysiska namnstrategi måste konvertera från enhetsnamn som är kamelfall till våra db-tabellnamn som är ormfall. Vi kan uppnå detta genom att utöka viloläge's PhysicalNamingStrategyStandardImpl :

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

public class PhysicalNamingStrategyImpl extends PhysicalNamingStrategyStandardImpl {

    private static final long serialVersionUID = 1L;
    public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl();

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return new Identifier(addUnderscores(name.getText()), name.isQuoted());
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
        return new Identifier(addUnderscores(name.getText()), name.isQuoted());
    }

    protected static String addUnderscores(String name) {
        final StringBuilder buf = new StringBuilder(name);
        for (int i = 1; i < buf.length() - 1; i++) {
            if (Character.isLowerCase(buf.charAt(i - 1)) &&
                    Character.isUpperCase(buf.charAt(i)) &&
                    Character.isLowerCase(buf.charAt(i + 1))) {
                buf.insert(i++, '_');
            }
        }
        return buf.toString().toLowerCase(Locale.ROOT);
    }
}

Vi åsidosätter standardbeteendet för metoder toPhysicalTableName och toPhysicalColumnName att tillämpa vår db-namnkonvention.

För att kunna använda vår anpassade implementering måste vi definiera egenskapen hibernate.physical_naming_strategy och ge den namnet på klassen PhysicalNamingStrategyImpl .

hibernate.physical_naming_strategy=com.example.foo.bar.PhysicalNamingStrategyImpl

På detta sätt kan vi lindra vår kod från @Table och @Column kommentarer, så vår enhetsklass:

@Entity
public class ApplicationEventLog {
    private Date startTimestamp;
    private String logUser;
    private Integer eventSuccess;

    @Column(name="finish_dtl")
    private String finishDetails;
}

kommer att kortläggas korrekt till db-tabellen:

CREATE TABLE application_event_log (
  ...
  start_timestamp timestamp,
  log_user varchar(255),
  event_success int(11),
  finish_dtl varchar(2000),
  ...
)

Som vi kan se i exemplet ovan kan vi fortfarande uttryckligen ange namnet på db-objektet om det av någon anledning inte är i enlighet med vår allmänna namnkonvention: @Column(name="finish_dtl")



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow