Java >> Java tutorial >  >> Tag >> hibernate

Implementering af en brugerdefineret navnestrategi med Hibernate

Som alle jer, der er bekendt med Hibernate, ved, er ikke alle enhedsannoteringer obligatoriske. Disse ikke-obligatoriske annoteringer inkluderer @Table og @Column annoteringer. Men selvom disse annoteringer ikke er påkrævet, har det aldrig været en mulighed for mig at udelade dem. Jeg kan simpelthen ikke lide de tabel- og kolonnenavne, der genereres af Hibernate, medmindre de udtrykkeligt er angivet.

Navnekonventionen for databaseobjekter og skemaelementer styres af den anvendte implementering af org.hibernate.cfg.NamingStrategy interface. Hibernate 3.6 har fire implementeringer af denne grænseflade:

  • org.hibernate.cfg.DefaultComponentSafeNamingStrategy
  • org.hibernate.cfg.DefaultNamingStrategy
  • org.hibernate.cfg.EJB3NamingStrategy
  • org.hibernate.cfg.ImprovedNamingStrategy

Ingen af ​​disse implementeringer opfylder dog mine krav, som er:

  • Alle tegn skal være små bogstaver.
  • Tabelnavne skal være i flertalsform.
  • Ord skal adskilles ved at bruge en understregning.

Siden ImprovedNamingStrategy klasse er næsten, hvad jeg leder efter (den eneste fejl er, at den returnerer tabelnavnet i en ental form), besluttede jeg at oprette en brugerdefineret navnestrategi ved at udvide den og tilsidesætte dens classToTableName() metode. Kildekoden til min implementering er angivet i følgende:

package net.petrikainulainen.hibernate.util;
import org.hibernate.cfg.ImprovedNamingStrategy;

/**
 * A custom naming strategy implementation which uses following naming conventions:
 * <ul>
 *     <li>Table names are lower case and in plural form. Words are separated with '_' character.</li>
 *     <li>Column names are lower case and words are separated with '_' character.</li>
 * </ul>
 * @author Petri Kainulainen
 */
public class CustomNamingStrategy extends ImprovedNamingStrategy {

    private static final String PLURAL_SUFFIX = "s";

    /**
     * Transforms class names to table names by using the described naming conventions.
     * @param className
     * @return  The constructed table name.
     */
    @Override
    public String classToTableName(String className) {
        String tableNameInSingularForm = super.classToTableName(className);
        return transformToPluralForm(tableNameInSingularForm);
    }

    private String transformToPluralForm(String tableNameInSingularForm) {
        StringBuilder pluralForm = new StringBuilder();

        pluralForm.append(tableNameInSingularForm);
        pluralForm.append(PLURAL_SUFFIX);

        return pluralForm.toString();
    }
}

Det næste trin er at konfigurere Hibernate til at bruge min brugerdefinerede navngivningsstrategi. Hvis du bruger Hibernate, kan du enten

  1. Du kan angive en reference til den tilpassede navnestrategi ved at kalde setNamingStrategy() metode til konfiguration klasse som beskrevet i afsnittet Implementering af en navnestrategi i Hibernate-referencedokumentationen.
  2. Du kan indstille værdien af ​​hibernate.ejb.naming_strategy ejendom til net.petrikainulainen.hibernate.util.CustomNamingStrategy i Hibernate XML-konfigurationsfilen som beskrevet i XML Configuration Section i Hibernate Reference Manual.

Hvis du bruger JPA, kan du indstille den brugte navnestrategi ved at indstille værdien af ​​hibernate.ejb.naming_strategy ejendom til net.petrikainulainen.hibernate.util.CustomNamingStrategy i persistence.xml som beskrevet i emballageafsnittet i Hibernate EntityManager-referencemanualen.

Efter du har konfigureret Hibernate til at bruge den implementerede brugerdefinerede navngivningsstrategi, kan du fjerne @Tabel- og @Kolonne-annoteringerne fra enhedsklasser (Dette er ikke helt sandt, men jeg vil beskrive manglerne ved min løsning senere). For eksempel, hvis du har en enhedsklasse Person , dens kildekode kunne se sådan ud:

@Entity
@Table("persons")
public class Person {

	@Column(name="first_name")
	private String firstName;

  	@Column(name="last_name")
  	private String lastName;

	public Person() {
	
	}
}

Efter Hibernate bruger den nye navnestrategi, kildekoden for Personen enhed ville se sådan ud (men Hibernate ville stadig bruge de samme tabel- og kolonnenavne, som var eksplicit angivet i det forrige eksempel):

@Entity
public class Person {

	private String firstName;

  	private String lastName;

	public Person() {
	
	}
}

Jeg har nu beskrevet for dig, hvordan du kan implementere og konfigurere en brugerdefineret navnestrategi med Hibernate. Løsningen beskrevet i dette blogindlæg er dog langt fra perfekt. Den har følgende mangler:

  • Det producerer ikke altid grammatisk korrekte tabelnavne. For eksempel:flertalsformen er et ord entitet er ikke entiteter. Det er enheder. Dette problem er ret svært at løse automatisk, men husk, at du altid kan bruge @Table-annotationen til at løse disse sager.
  • Hvis du vil tilføje begrænsninger til kolonnen i enhedsklassen, skal du stadig tilføje @Column-annoteringen. Dette er ikke et problem for mig, fordi jeg altid genererer scripts til oprettelse af database manuelt og tilføjer begrænsninger til databasen. Men hvis du vil generere din database ved at bruge Hibernate, skal du angive begrænsningerne ved at bruge @Column-annotationen eller tilføje de nødvendige begrænsninger manuelt til den oprettede database.
  • Du skal stadig konfigurere relationerne mellem enheder ved at bruge annoteringer. At skabe en automatisk løsning på dette problem ville betyde, at jeg skulle opfinde en form for navnekonvention for navnene på sammenføjningstabeller og -kolonner. Det er noget, jeg ikke er villig til at gøre. Men hvis du har en anden løsning i tankerne, så lad mig det vide!

Java tag