Uvod u ORMLite

1. Pregled

ORMLite je lagana ORM biblioteka za Java programe. Pruža standardne značajke ORM alata za najčešće slučajeve upotrebe, bez dodatne složenosti i općih troškova ostalih ORM okvira.

Glavne su značajke:

  • definiranje klasa entiteta pomoću Java napomena
  • proširivo DAO razreda
  • a QueryBuilder klasa za stvaranje složenih upita
  • generirane klase za stvaranje i ispuštanje tablica baze podataka
  • podrška za transakcije
  • podrška odnosima entiteta

U sljedećim odjeljcima pogledat ćemo kako možemo postaviti knjižnicu, definirati klase entiteta i izvoditi operacije nad bazom podataka pomoću knjižnice.

2. Ovisnosti Mavena

Da bismo počeli koristiti ORMLite, moramo dodati ormlite-jdbc ovisnost o našoj pom.xml:

 com.j256.ormlite ormlite-jdbc 5.0 

Prema zadanim postavkama, ovo također donosi h2 ovisnost. U našim ćemo primjerima koristiti H2 baze podataka u memoriji, tako da nam ne treba još jedan JDBC pokretački program.

Ako želite koristiti drugu bazu podataka, trebat će vam i odgovarajuća ovisnost.

3. Utvrđivanje klasa entiteta

Da bismo postavili klase modela za trajnost s ORMLite, dvije su primarne napomene koje možemo koristiti:

  • @DatabaseTable za klasu entiteta
  • @DatabaseField za svojstva

Počnimo s definiranjem a Knjižnica entitet sa Ime polje i a libraryId polje koje je ujedno i primarni ključ:

@DatabaseTable (tableName = "libraries") biblioteka javne klase {@DatabaseField (generatedId = true) private long libraryId; @DatabaseField (canBeNull = false) ime privatnog niza; javna knjižnica () {} // standardni getteri, postavljači}

The @DatabaseTable napomena je neobavezna tableName atribut koji specificira naziv tablice ako se ne želimo oslanjati na zadani naziv klase.

Za svako polje koje želimo zadržati kao stupac u tablici baze podataka, moramo dodati @DatabaseField bilješka.

Svojstvo koje će služiti kao primarni ključ za tablicu može se označiti s bilo kojim iskaznica, generirani id ili generatedSequence atributi. U našem primjeru odabiremo generatedId = true atribut tako da će se primarni ključ automatski povećavati.

Također, imajte na umu da klasa mora imati konstruktor bez argumenta sa najmanje opseg paketa vidljivost.

Nekoliko drugih poznatih atributa koje možemo koristiti za konfiguriranje polja je stupacName, vrsta podataka, zadana vrijednost, canBeNull, jedinstven.

3.1. Koristeći JPA Bilješke

Pored bilješki specifičnih za ORMLite, također možemo koristiti U stilu JPA napomene za definiranje naših entiteta.

Ekvivalent Knjižnica entitet koji smo definirali prije upotrebe JPA standardne bilješke bile bi:

@Entity javna klasa LibraryJPA {@Id @GeneratedValue (strategija = GenerationType.IDENTITY) private long libraryId; @ Privatni naziv niza stupca; // standardni getteri, postavljači}

Iako ORMLite prepoznaje ove napomene, ipak moramo dodati javax.postojanost-api ovisnost o njihovoj upotrebi.

Potpuni popis podržanih JPA napomena je @Entitet, @Iskaznica,@Stupac,@GeneratedValue, @Jedan na jedan, @ManyToOne, @JoinColumn, @Verzija.

4. ConnectionSource

Za rad s definiranim objektima, trebamo postaviti a ConnectionSource.

Za to možemo koristiti JdbcConnectionSource klasa koja stvara jedinstvenu vezu ili JdbcPooledConnectionSource koji predstavlja jednostavan skupni izvor veze:

JdbcPooledConnectionSource connectionSource = novi JdbcPooledConnectionSource ("jdbc: h2: mem: myDb"); // radimo s connectionSource connectionSource.close ();

Drugi vanjski izvor podataka s boljim performansama također se može upotrijebiti umotavanjem u DataSourceConnectionSource objekt.

5. TableUtils Razred

Bazirano na ConnectionSource, možemo koristiti statičke metode iz TableUtils klasa za izvođenje operacija na shemi baze podataka:

  • createTable () - stvoriti tablicu na temelju definicije klase entiteta ili a DatabaseTableConfig objekt
  • createTableIfNotExists () - slično prethodnoj metodi, osim što će stvoriti tablicu samo ako ne postoji; ovo radi samo na bazama podataka koje to podržavaju
  • dropTable () - za brisanje tablice
  • clearTable() - za brisanje podataka iz tablice

Pogledajmo kako se možemo koristiti TableUtils stvoriti tablicu za naše Knjižnica razred:

TableUtils.createTableIfNotExists (connectionSource, Library.class);

6. DAO Predmeti

ORMLite sadrži a DaoManager klasa koja može stvarati DAO objekti za nas s CRUD funkcionalnošću:

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

The DaoManager ne regenerira klasu za svaki sljedeći poziv createDao (), ali ga umjesto toga ponovno koristi za bolje performanse.

Dalje, možemo izvoditi CRUD operacije Knjižnica objekti:

Knjižnična knjižnica = nova knjižnica (); library.setName ("Moja knjižnica"); libraryDao.create (knjižnica); Rezultat knjižnice = libraryDao.queryForId (1L); library.setName ("Moja druga knjižnica"); libraryDao.update (knjižnica); libraryDao.delete (knjižnica);

The DAO je također iterator koji može petljati kroz sve zapise:

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

Međutim, ORMLite će zatvoriti temeljni SQL izraz samo ako petlja ide sve do kraja. Iznimka ili povratna izjava može uzrokovati curenje resursa u vašem kodu.

Iz tog razloga, dokumentacija ORMLite preporučuje da izravno koristimo iterator:

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

Na ovaj način iterator možemo zatvoriti pomoću a pokušajte s resursima ili a konačno blokirati i izbjeći curenje resursa.

6.1. Prilagođena DAO klasa

Ako želimo proširiti ponašanje DAO ponuđenih objekata, možemo stvoriti novo sučelje koje proširuje Dao tip:

javno sučelje LibraryDao proširuje Dao {javni popis findByName (naziv niza) baca SQLException; }

Zatim, dodajmo klasu koja implementira ovo sučelje i proširuje BaseDaoImpl razred:

javna klasa LibraryDaoImpl proširuje BaseDaoImpl implementira LibraryDao {javna LibraryDaoImpl (ConnectionSource connectionSource) baca SQLException {super (connectionSource, Library.class); } @Override javni popis findByName (naziv niza) baca SQLException {return super.queryForEq ("name", name); }}

Imajte na umu da trebamo imati konstruktor ovog oblika.

Napokon, da se poslužimo našim običajem DAO, moramo dodati naziv klase u Knjižnica definicija razreda:

@DatabaseTable (tableName = "libraries", daoClass = LibraryDaoImpl.class) Biblioteka javne klase {// ...}

To nam omogućuje upotrebu DaoManager za stvaranje instance naše prilagođene klase:

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

Tada možemo koristiti sve metode iz standarda DAO klase, kao i naša prilagođena metoda:

Knjižnična knjižnica = nova knjižnica (); library.setName ("Moja knjižnica"); customLibraryDao.create (knjižnica); assertEquals (1, customLibraryDao.findByName ("Moja knjižnica"). size ());

7. Utvrđivanje odnosa entiteta

ORMLite koristi koncept "stranih" predmeta ili zbirki za definiranje odnosa između entiteta radi trajnosti.

Pogledajmo kako možemo definirati svaku vrstu polja.

7.1. Polja stranih predmeta

Jednosmjerni odnos jedan prema jedan možemo stvoriti između dvije klase entiteta pomoću strano = istinito atribut na polju označenom s @DatabaseField. Polje mora biti tipa koji se također zadržao u bazi podataka.

Prvo, definirajmo novu klasu entiteta koja se zove Adresa:

@DatabaseTable (tableName = "adrese") Adresa javne klase {@DatabaseField (generatedId = true) private long addressId; @DatabaseField (canBeNull = false) privatni niz addressLine; // standardni getteri, postavljači}

Dalje, možemo dodati polje tipa Adresa našem Knjižnica razred koji je označen kao strani:

@DatabaseTable (tableName = "libraries") biblioteka javne klase {// ... @DatabaseField (Foreign = true, ForeignAutoCreate = true, ForeignAutoRefresh = true) adresa privatne adrese; // standardni getteri, postavljači}

Primijetite da smo također dodali još dva atributa @DatabaseField napomena: stranaAutoCreate i stranaAutoRefresh, oba postavljena na pravi.

The ForeignAutoCreate = true atribut znači da kada spremimo a Knjižnica objekt s adresa polje, strani će objekt također biti spremljen pod uvjetom da je iskaznica nije null i ima a generatedId = true atribut.

Ako postavimo stranaAutoCreate do lažno, koja je zadana vrijednost, tada bismo morali eksplicitno istrajati strani objekt prije spremanja Knjižnica objekt koji ga upućuje.

Slično tome, stranaAutoRefresh=pravi atribut određuje da se prilikom dohvaćanja a Knjižnica objekt, pridruženi strani objekt također će biti dohvaćen. Inače bismo ga trebali ručno osvježiti.

Dodajmo novu Knjižnica objekt s Adresa polje i nazovite knjižnicaDao ustrajati na oba:

Knjižnična knjižnica = nova knjižnica (); library.setName ("Moja knjižnica"); library.setAddress (nova adresa ("Glavna ulica br. 20")); Dao libraryDao = DaoManager.createDao (connectionSource, Library.class); libraryDao.create (knjižnica);

Tada možemo nazvati adresaDao kako bi potvrdio da Adresa je također spremljeno:

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

7.2. Strane kolekcije

Za puno stranu veze, možemo koristiti vrste Strana Zbirka ili Kolekcija s @ForeignCollectionField bilješka.

Stvorimo novu Knjiga entiteta poput onih gore, a zatim dodajte odnos jedan prema više u Knjižnica razred:

@DatabaseTable (tableName = "libraries") knjižnica javne klase {// ... @ForeignCollectionField (željno = netačno) privatne knjige ForeignCollection; // standardni getteri, postavljači}

Uz to, potrebno je dodati i polje tipa Knjižnica u Knjiga razred:

Knjiga javne klase @DatabaseTable {// ... @DatabaseField (Foreign = true, ForeignAutoRefresh = true) private Library Library; // standardni getteri, postavljači}

The Strana kolekcija ima dodati() i ukloniti() metode koji djeluju na zapisima tipa Knjiga:

Knjižnična knjižnica = nova knjižnica (); library.setName ("Moja knjižnica"); libraryDao.create (knjižnica); libraryDao.refresh (knjižnica); library.getBooks (). add (nova Knjiga ("1984"));

Evo, stvorili smo knjižnica objekt, a zatim je dodao novi Knjiga prigovoriti na knjige polje, koje ga također zadržava u bazi podataka.

Imajte na umu da je naša zbirka označena kao lijeno učitana (željno = lažno), moramo nazvati osvježiti() metoda prije nego što bude mogao koristiti polje knjige.

Odnos možemo stvoriti i postavljanjem knjižnica polje u Knjiga razred:

Knjiga knjiga = nova knjiga ("It"); book.setLibrary (knjižnica); bookDao.create (knjiga);

Da provjerim da i jedno i drugo Knjiga objekti se dodaju u knjižnica možemo koristiti queryForEq () metoda za pronalaženje svih Knjiga evidencije s danim knjižnica_id:

assertEquals (2, bookDao.queryForEq ("biblioteka_id", biblioteka) .size ());

Evo, knjižnica_id je zadani naziv stupca stranog ključa, a primarni ključ se zaključuje iz knjižnica objekt.

8. QueryBuilder

Svaki DAO može se koristiti za dobivanje a QueryBuilder objekt koji možemo iskoristiti za izgradnju snažnijih upita.

Ova klasa sadrži metode koje odgovaraju uobičajenim operacijama koje se koriste u SQL upitu, kao što su: selectColumns (), where (), groupBy (),having (), countOf (), distinct (), orderBy (), join ().

Pogledajmo primjer kako možemo pronaći sve Knjižnica zapisi koji imaju više od jednog Knjiga povezano:

Popis biblioteka = libraryDao.queryBuilder () .where () .in ("libraryId", bookDao.queryBuilder () .selectColumns ("library_id") .groupBy ("library_id") .having ("count (*)> 1") ) .query ();

9. Zaključak

U ovom smo članku vidjeli kako možemo definirati entitete pomoću ORMLitea, kao i glavne značajke knjižnice koje možemo koristiti za manipulaciju objektima i povezanim relacijskim bazama podataka.

Puni izvorni kod primjera može se naći na GitHubu.