Guide til MapDB
1. Introduksjon
I denne artikkelen vil vi se på MapDB-bibliotek - en innebygd databasemotor som er tilgjengelig via et samlingslignende API.
Vi starter med å utforske kjerneklassene DB og DBMaker som hjelper med å konfigurere, åpne og administrere databasene våre. Deretter dykker vi inn i noen eksempler på MapDB-datastrukturer som lagrer og henter data.
Til slutt vil vi se på noen av minnemodusene før vi sammenligner MapDB med tradisjonelle databaser og Java-samlinger.
2. Lagring av data i MapDB
Først, la oss introdusere de to klassene som vi vil bruke konstant gjennom denne opplæringen - DB og DBMaker. De DB klasse representerer en åpen database. Dens metoder påkaller handlinger for å opprette og lukke lagringssamlinger for å håndtere databaseposter, samt håndtere transaksjonshendelser.
DBMaker håndterer databasekonfigurasjon, oppretting og åpning. Som en del av konfigurasjonen kan vi velge å være vert for databasen vår enten i minnet eller i vårt filsystem.
2.1. En enkel HashMap Eksempel
For å forstå hvordan dette fungerer, la oss starte en ny database i minnet.
La oss først lage en ny database i minnet ved hjelp av DBMaker klasse:
DB db = DBMaker.memoryDB (). Make ();
En gang vår DB objektet er i gang, kan vi bruke det til å bygge et HTreeMap for å jobbe med databaseregistrene våre:
String welcomeMessageKey = "Velkomstmelding"; String welcomeMessageString = "Hei Baeldung!"; HTreeMap myMap = db.hashMap ("myMap"). CreateOrOpen (); myMap.put (welcomeMessageKey, welcomeMessageString);
HTreeMap er MapDB HashMap gjennomføring. Så nå som vi har data i databasen vår, kan vi hente dem ved hjelp av få metode:
String welcomeMessageFromDB = (String) myMap.get (welcomeMessageKey); assertEquals (welcomeMessageString, welcomeMessageFromDB);
Til slutt, nå som vi er ferdige med databasen, bør vi lukke den for å unngå ytterligere mutasjoner:
db.close ();
For å lagre dataene våre i en fil, i stedet for i minnet, er alt vi trenger å gjøre å endre måten vår DB objektet er instantiert:
DB db = DBMaker.fileDB ("file.db"). Make ();
Eksemplet vårt ovenfor bruker ingen typeparametere. Som et resultat sitter vi fast med å kaste resultatene våre til å jobbe med bestemte typer. I vårt neste eksempel vil vi introdusere Serializers for å eliminere behovet for støping.
2.2. Samlinger
MapDB inkluderer forskjellige samlingstyper. For å demonstrere, la oss legge til og hente data fra databasen vår ved hjelp av a NavigableSet, som fungerer som du kan forvente av en Java Sett:
La oss starte med en enkel instantiering av vår DB gjenstand:
DB db = DBMaker.memoryDB (). Make ();
La oss deretter lage vår NavigableSet:
NavigableSet set = db .treeSet ("mySet") .serializer (Serializer.STRING) .createOrOpen ();
Her, den serializer sørger for at inngangsdataene fra databasen vår blir serialisert og deserialisert ved hjelp av String gjenstander.
La oss deretter legge til noen data:
set.add ("Baeldung"); set.add ("er kjempebra");
La oss nå sjekke at våre to forskjellige verdier er lagt til databasen riktig:
assertEquals (2, set.size ());
Til slutt, siden dette er et sett, la oss legge til en duplikatstreng og kontrollere at databasen vår fremdeles bare inneholder to verdier:
set.add ("Baeldung"); assertEquals (2, set.size ());
2.3. Transaksjoner
I likhet med tradisjonelle databaser, er DB klasse gir metoder for å begå og tilbakeføring dataene vi legger til i databasen vår.
For å aktivere denne funksjonaliteten, må vi initialisere DB med transaksjon Aktiver metode:
DB db = DBMaker.memoryDB (). TransactionEnable (). Make ();
Deretter la oss lage et enkelt sett, legge til noen data og forplikte dem til databasen:
NavigableSet set = db .treeSet ("mySet") .serializer (Serializer.STRING) .createOrOpen (); set.add ("One"); set.add ("To"); db.commit (); assertEquals (2, set.size ());
La oss nå legge til en tredje, uforpliktet streng i databasen vår:
set.add ("Tre"); assertEquals (3, set.size ());
Hvis vi ikke er fornøyd med dataene våre, kan vi tilbakestille dataene ved hjelp av DBs tilbakeslag metode:
db.rollback (); assertEquals (2, set.size ());
2.4. Serializers
MapDB tilbyr et stort utvalg av serialisatorer som håndterer dataene i samlingen. Den viktigste konstruksjonsparameteren er navnet, som identifiserer den enkelte samlingen i DB gjenstand:
HTreeMap map = db.hashMap ("indentification_name") .keySerializer (Serializer.STRING) .valueSerializer (Serializer.LONG) .create ();
Selv om serialisering anbefales, er den valgfri og kan hoppes over. Det er imidlertid verdt å merke seg at dette vil føre til en langsommere generisk serialiseringsprosess.
3. HTreeMap
MapDB-er HTreeMap gir HashMap og HashSet samlinger for å jobbe med databasen vår. HTreeMap er et segmentert hash-tre og bruker ikke en hash-tabell i fast størrelse. I stedet bruker den et automatisk utvidende indekstret og kaster ikke opp alle dataene etter hvert som tabellen vokser. For å toppe det, HTreeMap er trådsikker og støtter parallelle skrivinger ved bruk av flere segmenter.
Til å begynne med, la oss sette i gang et enkelt HashMap som bruker String for både nøkler og verdier:
DB db = DBMaker.memoryDB (). Make (); HTreeMap hTreeMap = db .hashMap ("myTreeMap") .keySerializer (Serializer.STRING) .valueSerializer (Serializer.STRING) .create ();
Ovenfor har vi definert separat serialisere for nøkkelen og verdien. Nå som vår HashMap er opprettet, la oss legge til data ved hjelp av sette metode:
hTreeMap.put ("key1", "value1"); hTreeMap.put ("key2", "value2"); assertEquals (2, hTreeMap.size ());
Som HashMap fungerer på en Objektets hashCode metode, ved å legge til data ved hjelp av samme nøkkel, blir verdien overskrevet:
hTreeMap.put ("key1", "value3"); assertEquals (2, hTreeMap.size ()); assertEquals ("value3", hTreeMap.get ("key1"));
4. SortedTableMap
MapDB-er SortedTableMap lagrer nøkler i en tabell med fast størrelse og bruker binært søk for henting. Det er verdt å merke seg at når kartet er klar, er det skrivebeskyttet.
La oss gå gjennom prosessen med å lage og spørre en SortedTableMap. Vi starter med å lage et minnekartet volum for å holde dataene, samt en vask for å legge til data. Ved den første påkallingen av volumet vårt setter vi det skrivebeskyttede flagget til falsk, slik at vi kan skrive til volumet:
String VOLUME_LOCATION = "sortedTableMapVol.db"; Volum vol = MappedFileVol.FACTORY.makeVolume (VOLUME_LOCATION, false); SortedTableMap.Sink sink = SortedTableMap.create (vol, Serializer.INTEGER, Serializer.STRING) .createFromSink ();
Deretter legger vi til dataene våre og kaller skape metode på vasken for å lage kartet vårt:
for (int i = 0; i <100; i ++) {sink.put (i, "Value" + Integer.toString (i)); } vask.opprett ();
Nå som kartet vårt eksisterer, kan vi definere et skrivebeskyttet volum og åpne kartet vårt ved hjelp av SortedTableMap er åpen metode:
Volum openVol = MappedFileVol.FACTORY.makeVolume (VOLUME_LOCATION, sant); SortedTableMap sortedTableMap = SortedTableMap .open (openVol, Serializer.INTEGER, Serializer.STRING); assertEquals (100, sortedTableMap.size ());
4.1. Binær søk
Før vi går videre, la oss forstå hvordan SortedTableMap bruker binært søk mer detaljert.
SortedTableMap deler lagringen i sider, med hver side som inneholder flere noder som består av nøkler og verdier. Innenfor disse nodene er nøkkelverdiparene som vi definerer i Java-koden vår.
SortedTableMap utfører tre binære søk for å hente riktig verdi:
- Tastene for hver side lagres i bunken i en matrise. De SortedTableMap utfører et binært søk for å finne riktig side.
- Deretter skjer dekompresjon for hver nøkkel i noden. Et binært søk etablerer riktig node, i henhold til tastene.
- Til slutt, SortedTableMap søker over nøklene i noden for å finne riktig verdi.
5. In-Memory Mode
MapDB tilbyr tre typer minnebutikk. La oss se raskt på hver modus, forstå hvordan den fungerer, og studere fordelene.
5.1. On-Heap
On-heap-modus lagrer objekter i en enkel Java-samling Kart. Den bruker ikke serialisering og kan være veldig rask for små datasett.
Men siden dataene er lagret i bunken, administreres datasettet av søppelinnsamling (GC). Varigheten av GC øker med størrelsen på datasettet, noe som resulterer i ytelsesfall.
La oss se et eksempel som spesifiserer on-heap-modus:
DB db = DBMaker.heapDB (). Make ();
5.2. Byte []
Den andre butiktypen er basert på byte-arrays. I denne modusen dataene serialiseres og lagres i matriser opptil 1 MB i størrelse. Mens den er teknisk på bunken, er denne metoden mer effektiv for søppeloppsamling.
Dette anbefales som standard, og ble brukt i vårHei Baeldung ' eksempel:
DB db = DBMaker.memoryDB (). Make ();
5.3. DirectByteBuffer
Den endelige butikken er basert på DirectByteBuffer. Direkte minne, introdusert i Java 1.4, tillater overføring av data direkte til native-minne i stedet for Java-heap. Som et resultat vil dataene bli lagret helt utenfor haugen.
Vi kan påkalle en butikk av denne typen med:
DB db = DBMaker.memoryDirectDB (). Make ();
6. Hvorfor MapDB?
Så hvorfor bruke MapDB?
6.1. MapDB vs tradisjonell database
MapDB tilbyr et stort utvalg av databasefunksjonalitet konfigurert med bare noen få linjer med Java-kode. Når vi bruker MapDB, kan vi unngå det ofte tidkrevende oppsettet av ulike tjenester og forbindelser som trengs for å få programmet til å fungere.
Utover dette gir MapDB oss tilgang til kompleksiteten i en database med kjennskapen til en Java-samling. Med MapDB trenger vi ikke SQL, og vi kan få tilgang til poster med enkle få metode samtaler.
6.2. MapDB vs Simple Java Collections
Java Collections samler ikke dataene i applikasjonen vår når den slutter å kjøres. MapDB tilbyr en enkel, fleksibel, pluggbar tjeneste som lar oss raskt og enkelt vedvare dataene i applikasjonen vår, samtidig som vi opprettholder nytten av Java-samlingstyper.
7. Konklusjon
I denne artikkelen har vi tatt et dypdykk i MapDBs innebygde databasemotor og samlingsrammeverk.
Vi startet med å se på kjerneklassene DB og DBMaker for å konfigurere, åpne og administrere databasen vår. Deretter gikk vi gjennom noen eksempler på datastrukturer som MapDB tilbyr for å jobbe med postene våre. Til slutt så vi på fordelene med MapDB fremfor en tradisjonell database eller Java Collection.
Som alltid er eksempelkoden tilgjengelig på GitHub.