Introduktion til ORMLite

1. Oversigt

ORMLite er et let ORM-bibliotek til Java-applikationer. Det giver standardfunktioner i et ORM-værktøj til de mest almindelige brugssager, uden den ekstra kompleksitet og overhead af andre ORM-rammer.

De vigtigste funktioner er:

  • definerer enhedsklasser ved hjælp af Java-kommentarer
  • udvidelig DAO klasser
  • -en QueryBuilder klasse til oprettelse af komplekse forespørgsler
  • genererede klasser til oprettelse og slip af databasetabeller
  • support til transaktioner
  • støtte til enhedsrelationer

I de næste sektioner ser vi på, hvordan vi kan oprette biblioteket, definere enhedsklasser og udføre operationer i databasen ved hjælp af biblioteket.

2. Maven-afhængigheder

For at begynde at bruge ORMLite skal vi tilføje ormlite-jdbc afhængighed af vores pom.xml:

 com.j256.ormlite ormlite-jdbc 5.0 

Som standard bringer dette også ind h2 afhængighed. I vores eksempler bruger vi en H2 in-memory database, så vi ikke har brug for en anden JDBC-driver.

Hvis du vil bruge en anden database, skal du også bruge den tilsvarende afhængighed.

3. Definition af enhedsklasser

For at opsætte vores modelklasser til persistens med ORMLite er der to primære kommentarer, vi kan bruge:

  • @DatabaseTable for enhedsklassen
  • @DatabaseField for ejendommene

Lad os starte med at definere en Bibliotek enhed med en navn felt og en libraryId felt, som også er en primær nøgle:

@DatabaseTable (tableName = "biblioteker") public class-bibliotek {@DatabaseField (generatedId = true) privat langt libraryId; @DatabaseField (canBeNull = false) privat strengnavn; public Library () {} // standard getters, setters}

Det @DatabaseTable annotering har en valgfri tabelnavn attribut, der angiver navnet på tabellen, hvis vi ikke ønsker at stole på et standardklassenavn.

For hvert felt, som vi vil fortsætte som en kolonne i databasetabellen, skal vi tilføje @DatabaseField kommentar.

Ejendommen, der fungerer som en primær nøgle til tabellen, kan markeres med en af ​​dem id, generatedId eller generatedSequence egenskaber. I vores eksempel vælger vi generatedId = sand attribut, så den primære nøgle automatisk øges.

Bemærk også, at klassen skal have en konstruktør uden argument med mindst pakkeomfang sigtbarhed.

Et par andre kendte attributter, vi kan bruge til at konfigurere felterne er kolonnenavn, datatype, standard værdi, canBeNull, enestående.

3.1. Ved brug af JPA Kommentarer

Ud over de ORMLite-specifikke kommentarer, vi kan også bruge JPA-stil kommentarer til at definere vores enheder.

Ækvivalent til Bibliotek enhed, vi definerede inden brug JPA standardkommentarer ville være:

@Entity public class LibraryJPA {@Id @GeneratedValue (strategi = GenerationType.IDENTITY) privat langt libraryId; @Kolonne privat strengnavn; // standard getters, setters}

Selvom ORMLite genkender disse kommentarer, er vi stadig nødt til at tilføje javax.persistence-api afhængighed af at bruge dem.

Den fulde liste over understøttede JPA annoteringer er @Enhed, @Id,@Kolonne,@GeneratedValue, @En til en, @ManyToOne, @Deltag i kolonne, @Version.

4. ConnectionSource

For at arbejde med de definerede objekter, vi er nødt til at oprette en ConnectionSource.

Til dette kan vi bruge JdbcConnectionSource klasse, der skaber en enkelt forbindelse, eller JdbcPooledConnectionSource som repræsenterer en simpel samlet forbindelseskilde:

JdbcPooledConnectionSource connectionSource = ny JdbcPooledConnectionSource ("jdbc: h2: mem: myDb"); // arbejde med connectionSource connectionSource.close ();

Andre eksterne datakilder med bedre ydeevne kan også bruges ved at indpakke dem i en DataSourceConnectionSource objekt.

5. TableUtils Klasse

Baseret på ConnectionSource, vi kan bruge statiske metoder fra TableUtils klasse til at udføre operationer på databaseskemaet:

  • createTable () - at oprette en tabel baseret på en definition af enhedsklassen eller en DatabaseTableConfig objekt
  • createTableIfNotExists () - svarende til den foregående metode, bortset fra at den kun opretter tabellen, hvis den ikke findes; dette fungerer kun på databaser, der understøtter det
  • dropTable () - for at slette en tabel
  • klart bord() - for at slette dataene fra en tabel

Lad os se, hvordan vi kan bruge TableUtils at skabe bordet til vores Bibliotek klasse:

TableUtils.createTableIfNotExists (connectionSource, Library.class);

6. DAO Objekter

ORMLite indeholder -en DaoManager klasse, der kan skabe DAO objekter til os med CRUD-funktionalitet:

Dao libraryDao = DaoManager.createDao (connectionSource, Library.class);

Det DaoManager regenererer ikke klassen for hvert efterfølgende opkald af createDao (), men genbruger det i stedet til bedre ydeevne.

Dernæst kan vi udføre CRUD-operationer på Bibliotek genstande:

Biblioteksbibliotek = nyt bibliotek (); library.setName ("Mit bibliotek"); libraryDao.create (bibliotek); Biblioteksresultat = libraryDao.queryForId (1L); library.setName ("Mit andet bibliotek"); libraryDao.update (bibliotek); libraryDao.delete (bibliotek);

Det DAO er også en iterator, der kan løbe gennem alle poster:

libraryDao.forEach (lib -> {System.out.println (lib.getName ());});

ORMLite lukker dog kun den underliggende SQL-sætning, hvis sløjfen går helt til slutningen. En undtagelse eller en returerklæring kan forårsage en ressourcelækage i din kode.

Af den grund anbefaler ORMLite-dokumentationen, at vi bruger iteratoren direkte:

prøv (CloseableWrappedIterable wrappedIterable = libraryDao.getWrappedIterable ()) {wrappedIterable.forEach (lib -> {System.out.println (lib.getName ());}); }

På denne måde kan vi lukke iteratoren ved hjælp af en prøv med ressourcer eller a langt om længe blokere og undgå enhver ressourcelækage.

6.1. Brugerdefineret DAO-klasse

Hvis vi ønsker at udvide adfærden hos DAO leverede objekter, kan vi oprette en ny grænseflade, der udvider Dao type:

offentlig grænseflade LibraryDao udvider Dao {offentlig liste findByName (strengnavn) kaster SQLException; }

Lad os derefter tilføje en klasse, der implementerer denne grænseflade og udvider BaseDaoImpl klasse:

public class LibraryDaoImpl udvider BaseDaoImpl implementerer LibraryDao {public LibraryDaoImpl (ConnectionSource connectionSource) kaster SQLException {super (connectionSource, Library.class); } @ Override public List findByName (strengnavn) kaster SQLException {returner super.queryForEq ("navn", navn); }}

Bemærk, at vi skal have en konstruktør af denne form.

Endelig at bruge vores brugerdefinerede DAO, vi er nødt til at tilføje klassens navn til Bibliotek klasse definition:

@DatabaseTable (tableName = "biblioteker", daoClass = LibraryDaoImpl.class) bibliotek i offentlig klasse {// ...}

Dette gør det muligt for os at bruge DaoManager for at oprette en forekomst af vores brugerdefinerede klasse:

LibraryDao customLibraryDao = DaoManager.createDao (connectionSource, Library.class);

Så kan vi bruge alle metoderne fra standarden DAO klasse samt vores brugerdefinerede metode:

Biblioteksbibliotek = nyt bibliotek (); library.setName ("Mit bibliotek"); customLibraryDao.create (bibliotek); assertEquals (1, customLibraryDao.findByName ("Mit bibliotek"). størrelse ());

7. Definition af enhedsrelationer

ORMLite bruger begrebet “fremmede” objekter eller samlinger til at definere relationer mellem enheder for persistens.

Lad os se på, hvordan vi kan definere hver type felt.

7.1. Fremmedlegemefelter

Vi kan skabe et ensrettet en-til-en-forhold mellem to enhedsklasser ved hjælp af fremmed = sand attribut på et felt, der er kommenteret med @DatabaseField. Feltet skal være af en type, der også er vedvarende i databasen.

Lad os først definere en ny enhedsklasse kaldet Adresse:

@DatabaseTable (tableName = "adresser") offentlig klasse Adresse {@DatabaseField (generatedId = true) privat lang addressId; @DatabaseField (canBeNull = false) privat String addressLine; // standard getters, setters}

Dernæst kan vi tilføje et felt af typen Adresse til vores Bibliotek klasse, der er markeret som udenlandsk:

@DatabaseTable (tableName = "biblioteker") public class-bibliotek {// ... @DatabaseField (fremmed = sand, fremmedAutoCreate = sand, fremmedAutoRefresh = sand) privat adresse adresse; // standard getters, setters}

Bemærk, at vi også har tilføjet to attributter til @DatabaseField kommentar: ForeignAutoCreate og ForeignAutoRefresh, begge indstillet til rigtigt.

Det foreignAutoCreate = sand attribut betyder, at når vi gemmer en Bibliotek objekt med en adresse felt gemmes fremmedlegemet også, forudsat at det er id er ikke nul og har en generatedId = true attribut.

Hvis vi sætter ForeignAutoCreate til falsk, som er standardværdien, så bliver vi nødt til at fastholde det fremmede objekt eksplicit, før vi gemmer Bibliotek objekt, der refererer til det.

Tilsvarende er ForeignAutoRefresh=rigtigt attribut angiver, at når man henter en Bibliotek objekt, vil den tilknyttede fremmedlegeme også blive hentet. Ellers skal vi opdatere det manuelt.

Lad os tilføje et nyt Bibliotek objekt med en Adresse felt og kalde bibliotekDao at vedvare begge:

Biblioteksbibliotek = nyt bibliotek (); library.setName ("Mit bibliotek"); library.setAddress (ny adresse ("Main Street nr 20")); Dao libraryDao = DaoManager.createDao (connectionSource, Library.class); libraryDao.create (bibliotek);

Så kan vi kalde adresseDao for at kontrollere, at Adresse er også blevet gemt:

Dao addressDao = DaoManager.createDao (connectionSource, Address.class); assertEquals (1, addressDao.queryForEq ("addressLine", "Main Street nr 20"). størrelse ());

7.2. Udenlandske samlinger

Til mange side af et forhold, kan vi bruge typerne ForeignCollection eller Kollektion med en @ForeignCollectionField kommentar.

Lad os oprette et nyt Bestil enhed som dem ovenfor, og tilføj derefter et en-til-mange forhold i Bibliotek klasse:

@DatabaseTable (tableName = "biblioteker") offentlig klasse Bibliotek {// ... @ForeignCollectionField (ivrig = falsk) private ForeignCollection bøger; // standard getters, setters}

Ud over dette kræves det, at vi tilføjer et typefelt Bibliotek i Bestil klasse:

@DatabaseTable public class Book {// ... @DatabaseField (fremmed = sand, fremmedAutoRefresh = sand) privat biblioteksbibliotek; // standard getters, setters}

Det ForeignCollection har tilføje() og fjerne() metoder der fungerer på optegnelser af typen Bestil:

Biblioteksbibliotek = nyt bibliotek (); library.setName ("Mit bibliotek"); libraryDao.create (bibliotek); libraryDao.refresh (bibliotek); library.getBooks (). tilføj (ny bog ("1984"));

Her har vi oprettet en bibliotek objekt, og derefter tilføjet et nyt Bestil modsætter sig bøger felt, som også fortsætter det til databasen.

Bemærk, at da vores samling er markeret som doven (ivrig = falsk), vi er nødt til at kalde Opdater() metode inden du kan bruge bogfeltet.

Vi kan også oprette forholdet ved at indstille bibliotek felt i Bestil klasse:

Bogbog = ny bog ("Det"); book.setLibrary (bibliotek); bookDao.create (bog);

For at kontrollere, at begge dele Bestil objekter føjes til bibliotek vi kan bruge queryForEq () metode til at finde alle Bestil poster med det givne bibliotek_id:

assertEquals (2, bookDao.queryForEq ("bibliotek_id", bibliotek). størrelse ());

Her, den bibliotek_id er standardnavnet på den fremmede nøglekolonne, og den primære nøgle udledes fra bibliotek objekt.

8. QueryBuilder

Hver DAO kan bruges til at opnå en QueryBuilder modsætter os, at vi derefter kan udnytte til at opbygge mere kraftfulde forespørgsler.

Denne klasse indeholder metoder, der svarer til almindelige operationer, der bruges i en SQL-forespørgsel, såsom: selectColumns (), hvor (), groupBy (),have (), countOf (), distinkt (), orderBy (), join ().

Lad os se et eksempel på, hvordan vi kan finde alle de Bibliotek poster, der har mere end en Bestil tilknyttet:

Listebiblioteker = libraryDao.queryBuilder () .where () .in ("libraryId", bookDao.queryBuilder () .selectColumns ("library_id") .groupBy ("library_id") .having ("count (*)> 1") ) .forespørgsel ();

9. Konklusion

I denne artikel har vi set, hvordan vi kan definere enheder ved hjælp af ORMLite samt hovedfunktionerne i biblioteket, som vi kan bruge til at manipulere objekter og deres tilknyttede relationsdatabaser.

Den fulde kildekode for eksemplet kan findes på GitHub.