Inleiding tot ORMLite

1. Overzicht

ORMLite is een lichtgewicht ORM-bibliotheek voor Java-toepassingen. Het biedt standaardfuncties van een ORM-tool voor de meest voorkomende gebruiksscenario's, zonder de extra complexiteit en overhead van andere ORM-frameworks.

De belangrijkste kenmerken zijn:

  • het definiëren van entiteitsklassen met behulp van Java-annotaties
  • uitbreidbaar DAO klassen
  • een QueryBuilder class voor het maken van complexe queries
  • gegenereerde klassen voor het maken en neerzetten van databasetabellen
  • ondersteuning bij transacties
  • ondersteuning voor entiteitsrelaties

In de volgende secties zullen we bekijken hoe we de bibliotheek kunnen opzetten, entiteitsklassen kunnen definiëren en bewerkingen op de database kunnen uitvoeren met behulp van de bibliotheek.

2. Maven afhankelijkheden

Om ORMLite te gaan gebruiken, moeten we de ormlite-jdbc afhankelijkheid van onze pom.xml:

 com.j256.ormlite ormlite-jdbc 5.0 

Dit brengt standaard ook de h2 afhankelijkheid. In onze voorbeelden gebruiken we een H2 in-memory database, dus we hebben geen ander JDBC-stuurprogramma nodig.

Als je een andere database wilt gebruiken, heb je ook de bijbehorende afhankelijkheid nodig.

3. Entiteitsklassen definiëren

Om onze modelklassen in te stellen voor persistentie met ORMLite, zijn er twee primaire annotaties die we kunnen gebruiken:

  • @DatabaseTable voor de entiteitsklasse
  • @DatabaseField voor de eigendommen

Laten we beginnen met het definiëren van een Bibliotheek entiteit met een naam veld en een bibliotheek-id veld dat ook een primaire sleutel is:

@DatabaseTable (tableName = "bibliotheken") openbare klasse Bibliotheek {@DatabaseField (generatedId = true) lange privé libraryId; @DatabaseField (canBeNull = false) private String-naam; openbare bibliotheek () {} // standaard getters, setters}

De @DatabaseTable annotatie heeft een optionele tafel naam attribuut dat de naam van de tabel specificeert als we niet willen vertrouwen op een standaard klassenaam.

Voor elk veld dat we als kolom in de databasetabel willen behouden, moeten we de @DatabaseField annotatie.

De eigenschap die als primaire sleutel voor de tabel zal dienen, kan met een van beide worden gemarkeerd ID kaart, gegenereerde id of gegenereerdeSequence attributen. In ons voorbeeld kiezen we voor de GeneratedId = true attribuut zodat de primaire sleutel automatisch wordt verhoogd.

Merk ook op dat de klasse een constructor zonder argument moet hebben met ten minste pakket-scope zichtbaarheid.

Een paar andere bekende attributen die we kunnen gebruiken voor het configureren van de velden zijn kolomnaam, data type, standaardwaarde, canBeNull, uniek.

3.1. Gebruik makend van JPA Annotaties

Naast de ORMLite-specifieke annotaties, we kunnen ook gebruiken JPA-stijl annotaties om onze entiteiten te definiëren.

Het equivalent van de Bibliotheek entiteit die we hebben gedefinieerd voordat we gebruikten JPA standaard annotaties zouden zijn:

@Entity openbare klasse LibraryJPA {@Id @GeneratedValue (strategie = GenerationType.IDENTITY) privé lange libraryId; @Column private String naam; // standaard getters, setters}

Hoewel ORMLite deze annotaties herkent, moeten we nog steeds de extensie javax.persistence-api afhankelijkheid om ze te gebruiken.

De volledige lijst met ondersteunde JPA annotaties is @Entiteit, @ID kaart,@Kolom,@GeneratedValue, @Een op een, @ManyToOne, @JoinColumn, @Versie.

4. ConnectionSource

Om met de gedefinieerde objecten te werken, we moeten een ConnectionSource.

Hiervoor kunnen we de JdbcConnectionSource klasse die een enkele verbinding maakt, of de JdbcPooledConnectionSource wat een eenvoudige gepoolde verbindingsbron vertegenwoordigt:

JdbcPooledConnectionSource connectionSource = nieuwe JdbcPooledConnectionSource ("jdbc: h2: mem: myDb"); // werk met de connectionSource connectionSource.close ();

Andere externe gegevensbronnen met betere prestaties kunnen ook worden gebruikt door ze in een DataSourceConnectionSource voorwerp.

5. TableUtils Klasse

Gebaseerd op de ConnectionSource, we kunnen statische methoden gebruiken van de TableUtils class om bewerkingen uit te voeren op het databaseschema:

  • createTable () - om een ​​tabel te maken op basis van een entiteitsklasse-definitie of een DatabaseTableConfig voorwerp
  • createTableIfNotExists () - vergelijkbaar met de vorige methode, behalve dat de tabel alleen wordt aangemaakt als deze niet bestaat; dit werkt alleen op databases die dit ondersteunen
  • dropTable () - om een ​​tabel te verwijderen
  • clearTable() - om de gegevens uit een tabel te verwijderen

Laten we eens kijken hoe we kunnen gebruiken TableUtils om de tafel voor ons te maken Bibliotheek klasse:

TableUtils.createTableIfNotExists (connectionSource, Library.class);

6. DAO Voorwerpen

ORMLite bevat een DaoManager klasse die kan creëren DAO objecten voor ons met CRUD-functionaliteit:

Dao librarybao = DaoManager.createão (connectionSource, Library.class);

De DaoManager genereert de klasse niet opnieuw voor elke volgende aanroep van create¥ (), maar hergebruikt het in plaats daarvan voor betere prestaties.

Vervolgens kunnen we CRUD-bewerkingen uitvoeren op Bibliotheek voorwerpen:

Bibliotheek bibliotheek = nieuwe bibliotheek (); library.setName ("Mijn bibliotheek"); librarybao.create (bibliotheek); Bibliotheekresultaat = librarybao.queryForId (1L); library.setName ("Mijn andere bibliotheek"); librarybao.update (bibliotheek); libraryrency.delete (bibliotheek);

De DAO is ook een iterator die alle records kan doorlopen:

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

ORMLite zal de onderliggende SQL-instructie echter alleen sluiten als de lus helemaal tot het einde loopt. Een uitzondering of een retourinstructie kan een bronlek in uw code veroorzaken.

Om die reden raadt de ORMLite-documentatie aan om de iterator rechtstreeks te gebruiken:

probeer (CloseableWrappedIterable wrapIterable = librarybao.getWrappedIterable ()) {wrapIterable.forEach (lib -> {System.out.println (lib.getName ());}); }

Op deze manier kunnen we de iterator sluiten met een probeer-met-middelen of een Tenslotte blokkeer en voorkom lekken van bronnen.

6.1. Aangepaste DAO-klasse

Als we het gedrag van de DAO objecten voorzien, kunnen we een nieuwe interface maken die de extensie Dao type:

openbare interface Librarybao breidt Dao uit {openbare lijst findByName (tekenreeksnaam) gooit SQLException; }

Laten we vervolgens een klasse toevoegen die deze interface implementeert en de extensie BaseensionalImpl klasse:

openbare klasse LibrarybaoImpl breidt Base DaoImpl uit implementeert Librarybao {openbare LibrarybaoImpl (ConnectionSource connectionSource) gooit SQLException {super (connectionSource, Library.class); } @Override openbare lijst findByName (tekenreeksnaam) genereert SQLException {retourneer super.queryForEq ("naam", naam); }}

Merk op dat we een constructor van dit formulier nodig hebben.

Eindelijk, om onze gewoonte te gebruiken DAO, we moeten de klassenaam toevoegen aan de Bibliotheek klasse definitie:

@DatabaseTable (tableName = "bibliotheken", daoClass = LibrarybaoImpl.class) openbare klasse Bibliotheek {// ...}

Dit stelt ons in staat om de DaoManager om een ​​instantie van onze aangepaste klasse te maken:

Librarybao customLibrarybao = DaoManager.createbao (connectionSource, Library.class);

Dan kunnen we alle methoden uit de standaard gebruiken DAO klasse, evenals onze aangepaste methode:

Bibliotheek bibliotheek = nieuwe bibliotheek (); library.setName ("Mijn bibliotheek"); customLibrarybao.create (bibliotheek); assertEquals (1, customLibrarybao.findByName ("Mijn bibliotheek"). size ());

7. Entiteitsrelaties definiëren

ORMLite gebruikt het concept van "vreemde" objecten of verzamelingen om relaties tussen entiteiten te definiëren voor persistentie.

Laten we eens kijken hoe we elk type veld kunnen definiëren.

7.1. Velden met vreemde objecten

We kunnen een unidirectionele een-op-een-relatie tussen twee entiteitsklassen creëren door de buitenlandse = waar attribuut op een veld geannoteerd met @DatabaseField. Het veld moet van een type zijn dat ook in de database aanwezig is.

Laten we eerst een nieuwe entiteitsklasse definiëren met de naam Adres:

@DatabaseTable (tableName = "adressen") openbare klasse Adres {@DatabaseField (generatedId = true) privé lang adres-id; @DatabaseField (canBeNull = false) privé String addressLine; // standaard getters, setters}

Vervolgens kunnen we een veld met type toevoegen Adres naar onze Bibliotheek klasse die is gemarkeerd als buitenlands:

@DatabaseTable (tableName = "bibliotheken") openbare klasse Bibliotheek {// ... @DatabaseField (foreign = true, foreignAutoCreate = true, foreignAutoRefresh = true) privéadresadres; // standaard getters, setters}

Merk op dat we ook nog twee attributen hebben toegevoegd aan de @DatabaseField annotatie: foreignAutoCreate en foreignAutoRefresh, beide ingesteld op waar.

De foreignAutoCreate = true attribuut betekent dat wanneer we een Bibliotheek object met een adres veld, wordt het vreemde object ook opgeslagen, op voorwaarde dat het ID kaart is niet nul en heeft een GeneratedId = true attribuut.

Als we gaan foreignAutoCreate naar false, wat de standaardwaarde is, dan moeten we het vreemde object expliciet behouden voordat we het Bibliotheek object dat ernaar verwijst.

Evenzo is het foreignAutoRefresh=waar attribuut specificeert dat bij het ophalen van een Bibliotheek object, wordt het bijbehorende vreemde object ook opgehaald. Anders moeten we het handmatig vernieuwen.

Laten we een nieuwe toevoegen Bibliotheek object met een Adres veld en bel het bibliotheekbao om beide vol te houden:

Bibliotheek bibliotheek = nieuwe bibliotheek (); library.setName ("Mijn bibliotheek"); library.setAddress (nieuw adres ("Hoofdstraat nr 20")); Dao librarybao = DaoManager.createão (connectionSource, Library.class); librarybao.create (bibliotheek);

Dan kunnen we de addressensional om te verifiëren dat het Adres is ook opgeslagen:

Dao addressensional = DaoManager.createão (connectionSource, Address.class); assertEquals (1, addressensional.queryForEq ("addressLine", "Main Street nr 20") .size ());

7.2. Buitenlandse collecties

Voor de veel kant van een relatie kunnen we de typen gebruiken Buitenlandse collectie of Verzameling met een @BuienRadarNL annotatie.

Laten we een nieuw maken Boek entiteit zoals hierboven, en voeg vervolgens een een-op-veel-relatie toe in het Bibliotheek klasse:

@DatabaseTable (tableName = "bibliotheken") openbare klasse Bibliotheek {// ... @ForeignCollectionField (eager = false) privé ForeignCollection-boeken; // standaard getters, setters}

Daarnaast is het vereist dat we een veld met type toevoegen Bibliotheek in de Boek klasse:

@DatabaseTable openbare klasse Boek {// ... @DatabaseField (foreign = true, foreignAutoRefresh = true) privébibliotheekbibliotheek; // standaard getters, setters}

De Buitenlandse collectie heeft toevoegen() en verwijderen() methoden die werken op de records van het type Boek:

Bibliotheek bibliotheek = nieuwe bibliotheek (); library.setName ("Mijn bibliotheek"); librarybao.create (bibliotheek); librarybao.refresh (bibliotheek); library.getBooks (). add (nieuw boek ("1984"));

Hier hebben we een bibliotheek object en vervolgens een nieuw Boek bezwaar maken tegen de boeken veld, dat het ook in de database houdt.

Merk op dat aangezien onze collectie is gemarkeerd als lui geladen (gretig = false), we moeten de vernieuwen () methode voordat u het boekveld kunt gebruiken.

We kunnen de relatie ook creëren door de bibliotheek veld in het Boek klasse:

Boek boek = nieuw boek ("het"); book.setLibrary (bibliotheek); bookbao.create (boek);

Om te verifiëren dat beide Boek objecten worden toegevoegd aan de bibliotheek we kunnen de queryForEq () methode om alle Boek records met de gegeven bibliotheek_id:

assertEquals (2, bookbao.queryForEq ("library_id", bibliotheek) .size ());

Hier de bibliotheek_id is de standaardnaam van de kolom met de externe sleutel en de primaire sleutel wordt afgeleid uit de bibliotheek voorwerp.

8. QueryBuilder

Elk DAO kan worden gebruikt om een QueryBuilder object dat we vervolgens kunnen gebruiken voor het bouwen van krachtigere zoekopdrachten.

Deze klasse bevat methoden die overeenkomen met veelgebruikte bewerkingen die in een SQL-query worden gebruikt, zoals: selectColumns (), where (), groupBy (),met (), countOf (), distinct (), orderBy (), join ().

Laten we een voorbeeld bekijken van hoe we alle Bibliotheek records die er meer dan één hebben Boek geassocieerd:

Lijst bibliotheken = librarybao.queryBuilder () .where () .in ("libraryId", bookbao.queryBuilder () .selectColumns ("library_id") .groupBy ("library_id") .having ("count (*)> 1") ) .query ();

9. Conclusie

In dit artikel hebben we gezien hoe we entiteiten kunnen definiëren met ORMLite, evenals de belangrijkste kenmerken van de bibliotheek die we kunnen gebruiken om objecten en de bijbehorende relationele databases te manipuleren.

De volledige broncode van het voorbeeld is te vinden op GitHub.


$config[zx-auto] not found$config[zx-overlay] not found