Android-applikasjoner kan lagre programdata i SQLite-databaser. I denne opplæringen lærer du hvordan SQLite-databaser er utformet og manipulert.
Her begynner vi med å designe og bruke en enkel SQLite database for å administrere sjakk turnering score. Denne opplæringen er ment som en kort oversikt over hvordan SQLite-databaser fungerer. Denne kunnskapen vil da bli brukt i fremtidige utviklingsopplæringer for å implementere database-drevne Android-applikasjoner.
Android-applikasjoner kan opprette og manipulere sine egne private SQLite-relasjonsdatabaser. Utviklere kan også inspisere og modifisere databaser på en gitt Android-emulator eller -enhet ved hjelp av kommandolinjeverktøyet sqlite3 som er levert som en del av Android SDK-verktøyet, kalt Android Debug Bridge (adb).
I denne opplæringen antar vi at du har litt forståelse av relasjonsdatabaser, teoretisk, men trenger litt av en oppfriskningskurs før du bruker dem i Android-applikasjonene dine. Denne spesielle opplæringen krever ingen verktøy; det er mer en teoretisk øvelse.
Men hvis du planlegger å utvikle Android-applikasjoner som er avhengige av SQLite-databaser, må du installere verktøyene som er nødvendige for Android-utvikling, for eksempel Android SDK og Eclipse IDE. Sjekk ut de mange andre nyttige Android-veiledningene som er tilgjengelige her på Mobiletuts + for å hjelpe deg med å jobbe gjennom disse oppgavene.
SQLite er en lett relasjonsdatabase motor. SQLite er rask og har et lite fotavtrykk, noe som gjør det perfekt for Android-enheter. I stedet for de kraftige serverbaserte databasene som Oracle og Microsoft SQL Server, lagres hver SQLite-database i en enkelt fil på disken. Android-applikasjoner kan velge å lagre private applikasjonsdata i en SQLite-database.
Merk: Hvis du er kjent med SQL, vil SQLite være veldig enkelt å plukke opp. SQLite er i utgangspunktet en fjernet SQL-databasemotor for innebygde enheter. For spesifikk informasjon om SQLite og dens funksjoner, funksjonalitet og begrensninger, se SQLite online dokumentasjon.
En database er ganske enkelt en strukturert måte å lagre data på vedvarende måte. Data lagres i tabeller. Et bord har kolonner med forskjellige datatyper. Hver rad i et bord representerer en datapost. Du kan finne det nyttig å tenke på et bord som et Excel-regneark. For et objektorientert programmeringsperspektiv representerer hver tabell i en database ofte en gjenstand (representert av en klasse). Hver tabellkolonne representerer et klassetributt. Hver plate i et bord representerer en bestemt forekomst av objektet.
La oss se på et raskt eksempel. La oss si at du har en bedriftsdatabase med et bord som heter Employee. Medarbeiderbordet kan ha fem skrevet kolonner: AnsattesID (nummer), Fornavn (streng), LastName (streng), Tittel (streng) og Lønn (tall). Du kan da legge til en rekord i databasen for en ansatt ved navn John Doe og en egen post for en ansatt ved navn Anne Droid.
Data i en database er ment å bli inspisert og manipulert. Data i et bord kan være:
SETT INN
kommando)OPPDATER
kommando)SLETT
kommando)Du kan søke etter bestemte data i en database ved hjelp av det som heter et spørsmål. En forespørsel (ved hjelp av SELECT-kommandoen) kan innebære ett bord eller flere tabeller. For å opprette en spørring må du angi tabellene, datakolonnene og dataværdiene av interesse ved hjelp av SQL-kommandospråk. Hver SQL-kommando er avsluttet med et semikolon (;).
Den beste måten å virkelig forstå hvordan SQLite-databaser fungerer, er å jobbe gjennom et enkelt eksempel, så la oss gjøre det. La oss late som om vi har et program som holder styr på spillerpoeng fra en uformell sjakk-turnering. Spillerpoeng blir registrert, og på slutten av en serie kamper blir vinneren avgjort. Hver spillers samlede turneringsscore beregnes ut fra deres ytelse på:
Merk: For turneringen kan spillerscore være basert på en formel som faktorene i tiden det tok å vinne spillet og typen og antall brikker igjen på brettet ved slutten av spillet. På denne måten får en sterk spiller en høy poengsum for å miste noen kraftige stykker og vinne spillet raskt. Kanskje stil og holdning er inkludert av dommerne for å oppmuntre til morsomt, lett lek. Hvordan score beregnes er egentlig ikke viktig for hvordan vi definerer vår database; Vi lagrer dem bare i databasen. For enkelhet, vil vi anta at poengene er basert på en skala fra 0-100.
Et databaseskjema er bare definisjonen av databasens struktur i form av tabeller, datakolonner og så videre. Skjemaet for vår turneringsdatabase er ganske enkelt:
Turneringsscores databaseskema har tre tabeller:
SQLite3 har støtte for følgende vanlige datatyper for kolonner:
INTEGER
(signerte heltall)EKTE
(flytende punktverdier)TEKST
(UTF-8 eller UTF-16-streng, kodet ved å bruke databasekoding)BLOB
(data klump)Når du har bestemt hvilke kolonner som er nødvendige for hvert bord, er du klar til å lage noen tabeller i databaseskjemaet.
La oss begynne med å lage spillertabellen. Denne tabellen krever et unikt spiller ID for å referere til hver spiller. Vi kan gjøre dette til den primære nøkkelen (for å unikt identifisere en post i denne tabellen) og angi sin automatisk innskrivningsattributt. Autoincrement betyr at hver gang en ny spilleroppføring blir lagt til, vil platen få et nytt, unikt spiller-ID. Vi vil også lagre fornavn og etternavn for hver spiller - ingen nulls tillatt.
Her kan vi bruke CREATE TABLE SQL-setningen til å generere spillertabellen:
CREATE TABLE Players (ID INTEGER PRIMARY KEY AUTOINCREMENT, fname TEKST IKKE NULL, LNAME TEKST IKKE NULL);
Spilltabellen er veldig lik. Vi trenger et unikt spill id for å referere til hvert spill. Vi vil også ha et vennlig navn for hvert spill og en vektverdi for hvor mye spillet teller mot spillerens endelige turneringsscore (i prosent). Her er SQL-setningen for å lage spilltabellen:
CREATE TABLE Games (ID INTEGER PRIMARY KEY AUTOINCREMENT, gamename TEXT, vekt REAL DEFAULT .10 CHECK (vekt<=1));
Du kan også slette tabeller ved hjelp av DROP TABLE-setningen. Hvis du for eksempel vil slette spilltabellen, bruker du følgende SQL-kommando:
DROP TABLE Games;
Før vi går videre, la oss legge til noen data i disse tabellene. For å legge til en plate i spillertabellen må du angi kolonnens navn og verdiene i rekkefølge. For eksempel bruker følgende SQL-setningen INSERT-kommandoen for å legge til en plate for sjakk-spilleren Bobby Fisher:
INSERT til spillere (fname, lname) VALUES ('Bobby', 'Fisher');
Mens vi er på det, legger vi til to spillere: Bart Simpson (en veldig ynkelig sjakk spiller) og Garry Kasparov (kanskje den beste sjakkspilleren noensinne). Samtidig må vi legge til en haug med poster i spilltabellen. Først legger vi til semifinalen, som teller for 25 prosent av spillerens turneringsscore:
INSERT til spill (spillnavn, vekt) verdier ('semifinal', .25);
Deretter legger vi til et par varmeoppvarmer, som bruker standardvekten på 10 prosent:
INSERT til spill (gamename) verdier ('oppvarming varme 1');
Til slutt legger vi til en endelig verdi på 35 prosent av den totale turneringsscoren:
INSERT til spill (spillnavn, vekt) verdier ('endelig', .35);
Hvordan vet vi at dataene vi har lagt til er i tabellen? Vel, det er enkelt. Vi spør bare om alle rader i et bord ved hjelp av en SELECT-setning:
VELG * FRA SPILL;
Dette returnerer alle poster i spilltabellen:
id gamename weight ----- --------------- ------ 1 Semi-Final 0.25 2 Oppvarming Heat 1 0.1 3 Oppvarming Heat 2 0.1 4 Warm oppvarming 3 0,1 5 oppvarming varme 4 0,1 6 slutt 0,35
Vi kan også lage egne kolonner og alias dem. For eksempel kan vi opprette et kolonnalias som heter PlayerName, som er en beregnet kolonne: Det er spillerens for- og etternavn sammenkoblet med || operatør, adskilt av et mellomrom:
VELG fname || "|| lname AS Spillernavn, ID FRA Spillere;
Denne spørringen gir følgende resultater:
Spillernavn id ------------ - Bobby Fisher 1 Bart Simpsen 2 Garry Kasparov 3
Barts (spiller id 2) etternavn er stavet feil. For å oppdatere spillertabellen for å gjenspeile riktig stavemåte, kan du bruke UPDATE-kommandoen:
UPDATE Spillere SET lname = "Simpson" WHERE playerid = 2;
Du kan slette rader fra et bord ved hjelp av DELETE-funksjonen. For eksempel, for å slette platen vi nettopp har oppdatert:
DELETE FROM Players WHERE playerid = 2;
Du kan slette alle rader i et bord ved ikke å angi WHERE-klausulen:
DELETE FROM Players;
Nå som vi har satt opp våre spillere og spill, la oss lage GameResults tabellen. Dette er et mer komplisert bord. GameResults-tabellen parrer spilleren ids fra spillertabellen med spill ids fra spilltabellen, og lister deretter poengsummen som spilleren har tjent for det spesifikke spillet. Kolonner, som lenker til andre tabeller på denne måten, kalles ofte utenlandske nøkler. Vi ønsker unike spillerspillsparings, så vi lager en kompositt primærnøkkel fra spilleren og spill utenlandske nøkler for å unikt identifisere en GameResults-plate. Til slutt håndhever vi at resultatene er hele tall mellom 0 og 100.
CREATE TABLE GameResults (playerid INTEGER REFERENSER Spillere (id), gameid INTEGER REFERANSER Spill (id), poeng INTEGER CHECK (poengsummen)<=100 AND score>= 0), PRIMARY KEY (playerid, gameid));
(Merk: SQLite håndhever ikke utenlandske nøkkelbegrensninger, men du kan sette dem opp uansett og håndheve begrensningene ved å skape utløsere.)
Nå er det på tide å sette inn noen data i GameResults-tabellen. La oss si at Bobby Fisher (spiller ID 1) fikk en poengsum på 82 poeng på semifinalen (spill ID 1). Du kan bruke følgende SQL-kommando for å sette inn riktig plate i GameResults-tabellen:
INSERT i GameResults (playerid, gameid, score) VALUES (1,1,82);
La oss nå anta at turneringen spilles og resultatene blir lagt til i GameResults-tabellen. Bobby er en god spiller, Bart er en forferdelig spiller, og Garry spiller alltid et perfekt spill. Når postene er lagt til i GameResults-tabellen, kan vi utføre en SELECT * -kommando for å liste alle poster i tabellen, eller vi kan spesifisere kolonner eksplisitt slik:
VELG playerid, gameid, score FROM GameResults;
Her er resultatene fra denne spørringen:
playerid gameid score ---------- ---------- ----- 1 1 82 1 2 88 1 3 78 1 4 90 1 5 85 1 6 94 2 1 10 2 2 60 2 3 50 2 4 55 2 5 45 2 6 65 3 6 100 3 5 100 3 4 100 3 3 100 3 2 100 3 1 100
Som du kan se, er denne oppføringen ikke spesielt "menneskelig lesbar".
Ville det ikke være mer nyttig hvis navnene på spillerne og spillene ble vist i stedet for deres numeriske ids? Spørring og kombinering av data i SELECT-setninger håndteres ofte ved å utføre et JOIN med flere tabellkilder; Det er forskjellige typer JOINS. Når du arbeider med flere tabeller, må du angi hvilken tabell en kolonne tilhører (spesielt når kolonner heter det samme, for eksempel med alle disse forskjellige id-kolonnene). Du kan referere til kolonner med deres kolonne navn eller ved navn på bordet, deretter en prikk (.) Og deretter kolonnenavnet.
La oss rekonstruere spillerens poengsum igjen, bare denne gangen, inkluderer spillets navn og navnet på spilleren. Også, begrenser vi våre resultater bare til poengsummen for finalen (game id 6):
SELECT Players.fname || "|| Players.lname AS PlayerName, Games.gamename, GameResults.score FROM GameResults GÅ MED SPILLER PÅ (GameResults.playerid = Players.id) GÅ MED SPILL PÅ (GameResults.gameid = Games.id) HVOR gameid = 6;
som gir oss følgende resultater (du kan gå av WHERE for å få alle spillene):
Spillernavn gamename poengsum ------------------ -------------- ----- Bobby Fisher Final 94 Bart Simpson Final 65 Garry Kasparov Endelig 100
Himmelen er grensen når det gjelder spørsmålene du kan utføre her. For vårt eksempel er den viktigste spørringen den som forteller oss hvem som vant turneringen.
Her er den endelige spørringen for å beregne turneringsrangeringene:
SELECT Players.fname || "|| Spillere.lnavn AS Spillernavn, SUM ((Spill.vekt * GameResults.score)) AS TotalvektScore FROM GameResults GÅ MED SPILLER PÅ (GameResults.playerid = Players.id) GÅ MED SPILL PÅ (GameResults.gameid = Games.id) GRUPP AV GameResults.playerid BESTILL AV TotalWeightedScore DESC;
Denne spørringen samler informasjon fra flere forskjellige tabeller ved hjelp av JOINs, og beregner turneringsresultatene på en lesbar måte. Så la oss se på hva dette spørsmålet gjør:
Resultatene fra denne spørringen er vist nedenfor:
Spillernavn TotalWeightedScore ------------------------- ----------------- Garry Kasparov 100.0 Bobby Fisher 87.5 Bart Simpson 46.25
Dette avslutter vår undersøkelse av et enkelt SQLite database eksempel: en sjakk turnering database. Forhåpentligvis har du reacquainted deg selv med relasjonsdatabase konsepter som tabeller, poster og spørringer og kjente deg i mange av de vanlige SQLite-kommandoene. Til slutt har du gått gjennom utformingen og bruken av en eksempeldatabase. Nå som du har et håndtak på hvordan SQLite-databaser fungerer, er du klar til å bruke dem i Android-applikasjonene dine (temaet for vår neste opplæring i denne serien).
Mobilutviklere Lauren Darcey og Shane Conder har medforfatter flere bøker om Android-utvikling: en grundig programmeringsbok med tittel Android Wireless Application Development og Sams TeachYourself Android Application Development i 24 timer. Når de ikke skriver, bruker de sin tid på å utvikle mobil programvare hos deres firma og tilby konsulenttjenester. De kan nås via e-post til [email protected], via bloggen deres på androidbook.blogspot.com, og på Twitter @androidwireless.