hibernate
Anpassad namnstrategi
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")