Você está na página 1de 25

Android

SQLite Database
CS 301
Peter Kemper
Reference: Murphys Busy Coders Guide, SQLite Databases p461 ff
Why Databases on Android?

Common usage for a database

Huge amounts of data

Convenient query language to obtain data

Accessed/modied by huge amount of users

Concurrency: Two-phase commit transaction concept for concurrent access

Applications:

backend for multi-tier web architecture,

backend for business process architectures like SAP

areas: banks, insurance companies, ...

Android

Small scale architecture, little data, few applications ...


SQLite

Popular embedded database

Combines SQL interface with small memory footprint and


decent speed

integrated in Android runtime

Native API not JDBC

Example taken from Androids SensorManager


SQLite vs Content Provider

SQLite

Persistent storage of data

Data accessible to a single application (the owner)

Often wrapped by a Content Provider

Content Provider

Specialized type of data store to share data across apps

Exposes standardized ways to retrieve/manipulate data

Query with URI: <standard_prex>://<authority>/<data_path>/<id>

Examples: content://browser/bookmarks, content://contacts/people

Built in
SQLite example

Constants sample application based on SQLite DB

as initially launched plus its add-constant dialog


This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
Figure 136. The Constants sample application, as initially launched
!"#$%&'$("($#($&$)*'#$+"$&,,$&$'*-$%"'.+&'+/$-01%0$231'4.$#($&$,1&5"4$+"$
6155$1'$+0*$'&)*$&',$7&5#*$"6$+0*$%"'.+&'+8
Figure 137. The Constants sample application's add-constant dialog
456
This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
Figure 136. The Constants sample application, as initially launched
!"#$%&'$("($#($&$)*'#$+"$&,,$&$'*-$%"'.+&'+/$-01%0$231'4.$#($&$,1&5"4$+"$
6155$1'$+0*$'&)*$&',$7&5#*$"6$+0*$%"'.+&'+8
Figure 137. The Constants sample application's add-constant dialog
456
On Using a Database

Creating a database

How to create and ll database when used rst time after


installation of app?

How to update/adjust an existing database to a new


schema that comes with an update for an existing app?

Reading data from a database / writing data to a database

How to open an existing database?

How to create/read/write/modify/delete particular entries?

How to close a database?


SQLite Primer

Implement a Subclass of SQLiteOpenHelper

to create & open a database

The constructor, chaining upward to the SQLiteOpenHelper constructor. This


takes the Context (e.g., an Activity), the name of the database, an optional cursor
factory (typically, just pass null), and an integer representing the version of the
database schema you are using.

Note: following examples from Murphy operate with a simpler constructor

onCreate(), which passes you a SQLiteDatabase object that you need to


populate with tables and initial data, as appropriate.

onUpgrade(), which passes you a SQLiteDatabase object and the old and new
version numbers, so you can gure out how best to convert the database from
the old schema to the new one. The simplest, albeit least friendly, approach is to
simply drop the old tables and create new ones.

to access database:

getReadableDatabase() and getWritableDatabase()


see also: http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html
SQLite Primer

SQL dialect

Data denition: CREATE TABLE

Data manipulation: INSERT

Queries: SELECT ... FROM ... WHERE

deviates from SQL-92 standard, not supported

FOREIGN KEY constraints, nested transactions,


RIGHT OUTER JOIN, FULL OUTER JOIN, ...

Most particular: Manifest typing


This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
!"#$%&'()*')$+($)"#'$*,,#,$)&$)"#$-+().$/$-&'01)*2$&'$*'$#3+()+'0$%&'()*')$
4+--$56+'0$72$*$%&')#3)$8#'7$4+)"$*$9:#-#)#9$&2)+&'$;$*<)#6$%&'<+68*)+&'=$
)"*)$4+--$,#-#)#$)"#$%&'()*').
/',=$&<$%&76(#=$*--$&<$)"+($+($()&6#,$+'$*$>?@+)#$,*)*5*(#.
A uick SLite Primer
>?@+)#= $*($ )"#$ '*8#$(700#()(= $ 7(#($*$,+*-#%)$&<$ >?@$ <&6$A7#6+#($ B!"#"$%C=$
,*)*$8*'+27-*)+&'$B&'!"(%=$#).$*-.C=$*',$,*)*$,#<+'+)+&'$B$(")%"*%)+#"=$#).$*-.C.$
>?@+)#$ "*($*$ <#4$2-*%#($4"#6#$ +)$,#D+*)#($ <6&8$)"#$ >?@1EF$()*',*6,= $ '&$
,+<<#6#') $ )"*'$ 8&()$ >?@$ ,*)*5*(#(. $ !"#$ 0&&,$ '#4($ +($ )"*) $ >?@+)#$ +($ (&$
(2*%#1#<<+%+#') $ )"*) $ )"#$ /',6&+,$ 67')+8#$ %*'$ +'%-7,#$ *-- $ &< $ >?@+)#= $ '&)$
(&8#$*65+)6*6G$(75(#)$)&$)6+8$+)$,&4'$)&$(+H#.
!"#$ 5+00#() $ ,+<<#6#'%#$ <6&8$ &)"#6 $ >?@$ ,*)*5*(#( $ G&7$ 4+-- $ #'%&7')#6 $ +($
26&5*5-G$)"#$,*)*$)G2+'0.$I"+-#$G&7$%*'$(2#%+<G$)"#$,*)*$)G2#($<&6$%&-78'($
+'$*$$(")%"*%)+#"$()*)#8#')=$*',$4"+-#$>?@+)#$4+--$7(#$)"&(#$*($*$"+')=$)"*)$
+($*($<*6$*($+)$0&#(.$J&7$%*'$27)$4"*)#D#6$,*)*$G&7$4*')$+'$4"*)#D#6$%&-78'$
G&7$4*').$K7)$*$()6+'0$+'$*'$&'%","($%&-78'L$>76#M$N&$26&5-#8M$O+%#$D#6(*L$
I&6P($)&&M$>?@+)#$6#<#6($)&$)"+($*($98*'+<#()$)G2+'09=$*($,#(%6+5#,$+'$)"#$
,&%78#')*)+&'Q
ln monifest typinq, tbe Jototype is o property of tbe volue it-
self, not of tbe column in wbicb tbe volue is storeJ. SQlite
tbus ollows tbe user to store ony volue of ony Jototype into
ony column reqorJless of tbe JecloreJ type of tbot column.
R'$*,,+)+&'=$)"#6#$*6#$*$"*',<7-$&<$()*',*6,$>?@$<#*)76#($'&)$(722&6)#,$+'$
>?@+)#= $ '&)*5-G $-.("&,'*/"0$ %&'()6*+')(= $ '#()#,$ )6*'(*%)+&'(= $(&,1%*.2%"(*
3.&'$*',$-2##*.2%"(*3.&'=$*',$(&8#$<-*D&6($&<$)#%"(*%)+#".
S#G&',$ )"*)= $ )"&70"= $G&7$0#)$*$ <7-- $ >?@$ (G()#8= $%&82-#)#$4+)"$ )6+00#6(=$
)6*'(*%)+&'(=$*',$)"#$-+P#.$>)&%P$>?@$()*)#8#')(=$-+P#$!"#"$%=$4&6P$26#))G$
87%"$*($G&7$8+0")$#32#%).
307
Example: Database/Constants
This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
If you aie used io woiling wiil a majoi daiabase, lile Oiacle, you may lool
upon SQLiie as being a ioy daiabase. Please beai in mind ilai Oiacle and
SQLiie aie meani io solve diffeieni pioblems, and ilai you will noi be
seeing a full copy of Oiacle on a plone any iime soon, in all lilelilood.
Start at the Beginning
No daiabases aie auiomaiically supplied io you by Andioid. If you wani io
use SQLiie, you lave io cieaie youi own daiabase, ilen populaie ii wiil
youi own iables, indexes, and daia.
To cieaie and open a daiabase, youi besi opiion is io ciafi a subclass of
!"#$%&'(&)*&+(&,. Tlis class wiaps up ile logic io cieaie and upgiade a
daiabase, pei youi specificaiions, as needed by youi applicaiion. Youi
subclass of !"#$%&'(&)*&+(&, will need iliee meilods:
! Tle consiiucioi, claining upwaid io ile !"#$%&'(&)*&+(&,-
consiiucioi. Tlis iales ile ./)%&0% (e.g., an 12%$3$%4), ile name of
ile daiabase, an opiional cuisoi facioiy (iypically, jusi pass null),
and an iniegei iepieseniing ile veision of ile daiabase sclema you
aie using.
! /).,&5%&67, wlicl passes you a !"#$%&85%595:& objeci ilai you need
io populaie wiil iables and iniiial daia, as appiopiiaie.
! /);(<,5=&67, wlicl passes you a !"#$%&85%595:& objeci and ile old
and new veision numbeis, so you can figuie oui low besi io conveii
ile daiabase fiom ile old sclema io ile new one. Tle simplesi,
albeii leasi fiiendly, appioacl is io simply diop ile old iables and
cieaie new ones.
Foi example, leie is a 85%595:&*&+(&, class fiom 85%595:&>./):%5)%: ilai, in
/).,&5%&67, cieaies a iable and adds a numbei of iows, and in /);(<,5=&67-
cleais by diopping ile exisiing iable and execuiing /).,&5%&67:
(52?5<&-2/@A2/@@/):B5,&A5)=,/$=A2/):%5)%:C
$@(/,%-5)=,/$=A2/)%&)%A./)%&)%D5+E&:C
$@(/,%-5)=,/$=A2/)%&)%A./)%&0%C
$@(/,%-5)=,/$=A=5%595:&A.E,:/,C
308
This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
!"#$%&'()*%$!*+*(&(,(-.+/01234.#&!$)5
!"#$%&'()*%$!*+*(&(,(-.+-67!&.+/01!&.8#.)9.7#.%5
!"#$%&'()*%$!*+*(&(,(-.+-67!&.+/01!&.:(&(,(-.5
!"#$%&'()*%$!*+;(%*<(%.+/.)-$%=()(>.%5
#?,7!4'47(--':(&(,(-.9.7#.%'.3&.)*-'/01!&.8#.)9.7#.%'@
''#%!A(&.'-&(&!4'B!)(7'/&%!)>':CDCEC/2FGC=2HI*,I5
''#?,7!4'-&(&!4'B!)(7'/&%!)>'DJD12HI&!&7.I5
''#?,7!4'-&(&!4'B!)(7'/&%!)>'KC1L2HIA(7?.I5
''
''#?,7!4'!"#"$"%&'&()&*MN$)&.3&'4$)&.3&O'@
''''-?#.%M4$)&.3&P':CDCEC/2FGC=2P')?77P'QO5
''R
''
''S8A.%%!*.
''#?,7!4'A$!*'+,-*&"#&M/01!&.:(&(,(-.'*,O'@
''''*,+&.&/012MINT2CD2'DCE12'4$)-&()&-'MF!*'JGD2U2T'VTJ=CTW'X2W'CLD8JGNT2=2GDP'
&!&7.'D2YDP'A(7?.'T2C1O5IO5
''''
''''N$)&.)&K(7?.-'4AH).<'-+,#&,#3"(4&%MO5
''''
''''4A+)4#MDJD12P'IU%(A!&ZP':.(&;'/&(%'JIO5
''''4A+)4#MKC1L2P'/.)-$%=()(>.%+UTCKJDWF:2CD9F/DCTFJO5
''''*,+5,%&*#MI4$)-&()&-IP'DJD12P'4AO5
''''
''''4A+)4#MDJD12P'IU%(A!&ZP'2(%&;IO5
''''4A+)4#MKC1L2P'/.)-$%=()(>.%+UTCKJDWF2CTD9O5
''''*,+5,%&*#MI4$)-&()&-IP'DJD12P'4AO5
''''
''''4A+)4#MDJD12P'IU%(A!&ZP'[?#!&.%IO5
''''4A+)4#MKC1L2P'/.)-$%=()(>.%+UTCKJDWF[LVJD2TO5
''''*,+5,%&*#MI4$)-&()&-IP'DJD12P'4AO5
''''
''''4A+)4#MDJD12P'IU%(A!&ZP'=(%-IO5
''''4A+)4#MKC1L2P'/.)-$%=()(>.%+UTCKJDWF=CT/O5
''''*,+5,%&*#MI4$)-&()&-IP'DJD12P'4AO5
''''
''''4A+)4#MDJD12P'IU%(A!&ZP'=.%4?%ZIO5
''''4A+)4#MKC1L2P'/.)-$%=()(>.%+UTCKJDWF=2TNLTWO5
''''*,+5,%&*#MI4$)-&()&-IP'DJD12P'4AO5
''''
''''4A+)4#MDJD12P'IU%(A!&ZP'=$$)IO5
''''4A+)4#MKC1L2P'/.)-$%=()(>.%+UTCKJDWF=88GO5
''''*,+5,%&*#MI4$)-&()&-IP'DJD12P'4AO5
''''
''''4A+)4#MDJD12P'IU%(A!&ZP'G.#&?).IO5
''''4A+)4#MKC1L2P'/.)-$%=()(>.%+UTCKJDWFG2VDLG2O5
''''*,+5,%&*#MI4$)-&()&-IP'DJD12P'4AO5
''''
''''4A+)4#MDJD12P'IU%(A!&ZP'V7?&$IO5
''''4A+)4#MKC1L2P'/.)-$%=()(>.%+UTCKJDWFV1LD8O5
''''*,+5,%&*#MI4$)-&()&-IP'DJD12P'4AO5
''''
''''4A+)4#MDJD12P'IU%(A!&ZP'/(&?%)IO5
309
Note:
Example slightly
different in
Murphy 4.3
Example: Database/Constants
This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
!!!!"#$!"#%&'()*+!,-./0123.34-1$56'&789:,'8)6;<=
!!!!>?$$%&'(#%@"0./A3.A/@+!878(*+!"#<=
!!!!
!!!!"#$!"#%878(*+!@513#BAC+!,D.@<=
!!!!"#$!"#%&'()*+!,-./0123.34-1$56'&789:,);<=
!!!!>?$$%&'(#%@"0./A3.A/@+!878(*+!"#<=
!!!!
!!!!"#$!"#%878(*+!@513#BAC+!8E-!7/F3.>@<=
!!!!"#$!"#%&'()*+!,-./0123.34-1$56'&789:8G*:7,(';H<=
!!!!>?$$%&'(#%@"0./A3.A/@+!878(*+!"#<=
!!!!
!!!!"#$!"#%878(*+!@513#BAC+!)13.D/@<=
!!!!"#$!"#%&'()*+!,-./0123.34-1$56'&789:)6';),<=
!!!!>?$$%&'(#%@"0./A3.A/@+!878(*+!"#<=
!!!!
!!!!"#$!"#%878(*+!@513#BAC+!&-.D/@<=
!!!!"#$!"#%&'()*+!,-./0123.34-1$56'&789:&*;),<=
!!!!>?$$%&'(#%@"0./A3.A/@+!878(*+!"#<=
!!I
!!JK#-11B>-
!!LD?FB"!#0B>!)%*!+(,-'%,M(BA-H3A3?3/-!>?+!B.A!0F>&-1/B0.+!B.A!.-N&-1/B0.<!O
!!!!3.>10B>$DABF$(04$.%@P0./A3.A/@+!@)L413>B.4!>3A3?3/-+!NEB"E!NBFF!>-/A10C!3FF!
0F>!>3A3@<=
!!!!>?$'/'0123%@H6KQ!8'R(*!7S!*T7,8,!"0./A3.A/@<=
!!!!)%4(',#'%>?<=
!!I
I
To use youi ,M(BA-KL-.G-FL-1 subclass, cieaie and lold onio an insiance of
ii. Tlen, wlen you need a ,M(BA-H3A3?3/- objeci io do queiies oi daia
modificaiions, asl youi ,M(BA-KL-.G-FL-1 io 4-A6-3>3?F-H3A3?3/-%< oi
4-AU1BA-3?F-H3A3?3/-%<, depending upon wleilei oi noi you will be
clanging iis conienis. Foi example, oui P0./A3.A/R10N/-1 aciiviiy opens ile
daiabase in 0.P1-3A-%< as paii of doing a queiy:
"0./A3.A/PD1/01V>?
!!!!!!!!!!!!!!!!!!$+'#5',-,67'8,#,6,&'%<
!!!!!!!!!!!!!!!!!!$(,.2"'(9%@,*(*P8!:7H+!ABAF-+!#3FD-!@W
!!!!!!!!!!!!!!!!!!!!!!!!!!!@S6K2!"0./A3.A/!K6H*6!R9!ABAF-@+
!!!!!!!!!!!!!!!!!!!!!!!!!!!.DFF<=
Wlen you aie done wiil ile daiabase (e.g., youi aciiviiy is being closed),
simply call "F0/-%< on youi ,M(BA-KL-.G-FL-1 io ielease youi conneciion.
310
...
to open database for read / write access use helper db
This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
!!!!"#$!"#%&'()*+!,-./0123.34-1$56'&789:,'8)6;<=
!!!!>?$$%&'(#%@"0./A3.A/@+!878(*+!"#<=
!!!!
!!!!"#$!"#%878(*+!@513#BAC+!,D.@<=
!!!!"#$!"#%&'()*+!,-./0123.34-1$56'&789:,);<=
!!!!>?$$%&'(#%@"0./A3.A/@+!878(*+!"#<=
!!!!
!!!!"#$!"#%878(*+!@513#BAC+!8E-!7/F3.>@<=
!!!!"#$!"#%&'()*+!,-./0123.34-1$56'&789:8G*:7,(';H<=
!!!!>?$$%&'(#%@"0./A3.A/@+!878(*+!"#<=
!!!!
!!!!"#$!"#%878(*+!@513#BAC+!)13.D/@<=
!!!!"#$!"#%&'()*+!,-./0123.34-1$56'&789:)6';),<=
!!!!>?$$%&'(#%@"0./A3.A/@+!878(*+!"#<=
!!!!
!!!!"#$!"#%878(*+!@513#BAC+!&-.D/@<=
!!!!"#$!"#%&'()*+!,-./0123.34-1$56'&789:&*;),<=
!!!!>?$$%&'(#%@"0./A3.A/@+!878(*+!"#<=
!!I
!!JK#-11B>-
!!LD?FB"!#0B>!)%*!+(,-'%,M(BA-H3A3?3/-!>?+!B.A!0F>&-1/B0.+!B.A!.-N&-1/B0.<!O
!!!!3.>10B>$DABF$(04$.%@P0./A3.A/@+!@)L413>B.4!>3A3?3/-+!NEB"E!NBFF!>-/A10C!3FF!
0F>!>3A3@<=
!!!!>?$'/'0123%@H6KQ!8'R(*!7S!*T7,8,!"0./A3.A/@<=
!!!!)%4(',#'%>?<=
!!I
I
To use youi ,M(BA-KL-.G-FL-1 subclass, cieaie and lold onio an insiance of
ii. Tlen, wlen you need a ,M(BA-H3A3?3/- objeci io do queiies oi daia
modificaiions, asl youi ,M(BA-KL-.G-FL-1 io 4-A6-3>3?F-H3A3?3/-%< oi
4-AU1BA-3?F-H3A3?3/-%<, depending upon wleilei oi noi you will be
clanging iis conienis. Foi example, oui P0./A3.A/R10N/-1 aciiviiy opens ile
daiabase in 0.P1-3A-%< as paii of doing a queiy:
"0./A3.A/PD1/01V>?
!!!!!!!!!!!!!!!!!!$+'#5',-,67'8,#,6,&'%<
!!!!!!!!!!!!!!!!!!$(,.2"'(9%@,*(*P8!:7H+!ABAF-+!#3FD-!@W
!!!!!!!!!!!!!!!!!!!!!!!!!!!@S6K2!"0./A3.A/!K6H*6!R9!ABAF-@+
!!!!!!!!!!!!!!!!!!!!!!!!!!!.DFF<=
Wlen you aie done wiil ile daiabase (e.g., youi aciiviiy is being closed),
simply call "F0/-%< on youi ,M(BA-KL-.G-FL-1 io ielease youi conneciion.
310
once done, call close()
SQLite Primer

DB queries generated as strings and executed.

Creating a table with

a primary key column named _id and auto-incremented


integer ids

data column named title

data column named value

other indexes could be added with CREATE INDEX


statements

INSERT, UPDATE, DELETE operations in a similar manner


This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
Setting the Table
Foi cieaiing youi iables and indexes, you will need io call !"!#$%&'( on youi
$%&)*!+,*,-,.!, pioviding ile DDL siaiemeni you wisl io apply againsi ile
daiabase. Baiiing a daiabase eiioi, ilis meilod ieiuins noiling.
So, foi example, you can call !"!#$%&'( io cieaie ile #/0.*,0*. iable, as
slown in ile +,*,-,.!1!23!4 /054!,*!'( meilod:
6-7!"!#$%&'859:;<:=<;>&:=#/0.*,0*.='?)6=@A<:B:9=C9@D;9E=F:E=;G<H@A59:D:A<I=*)*2!=
<:J<I=K,2L!=9:;&(M8(M
Tlis will cieaie a iable, named #/0.*,0*., wiil a piimaiy ley column
named ?)6 ilai is an auio-inciemenied iniegei (i.e., SQLiie will assign ile
value foi you wlen you inseii iows), plus iwo daia columns: *)*2! (iexi)
and K,2L! (a floai, oi ieal in SQLiie ieims). SQLiie will auiomaiically
cieaie an index foi you on youi piimaiy ley column - you could add oilei
indexes leie via some 59:;<:=@A+:J siaiemenis, if you so close io.
Mosi lilely, you will cieaie iables and indexes wlen you fiisi cieaie ile
daiabase, oi possibly wlen ile daiabase needs upgiading io accommodaie
a new ielease of youi applicaiion. If you do noi clange youi iable sclemas,
you migli nevei diop youi iables oi indexes, bui if you do, jusi use
!"!#$%&'( io invole +9HC=@A+:J and +9HC=<;>&: siaiemenis as needed.
Makin' Data
Given ilai you lave a daiabase and one oi moie iables, you piobably wani
io pui some daia in ilem and sucl. You lave iwo majoi appioacles foi
doing ilis.
You can always use !"!#$%&'(, jusi lile you did foi cieaiing ile iables. Tle
!"!#$%&'( meilod woils foi any SQL ilai does noi ieiuin iesulis, so ii can
landle @A$:9<, GC+;<:, +:&:<:, eic. jusi fine.
311
SQLite Primer

Alternative to add/delete/modify data: use insert(), update(),


delete() methods on SQLiteDatabase object

Makes use of ContentValues objects

get() to obtain a value by its key

getAsInteger(), getAsString() ....

Insert() parameters: 1) name of table,


2) one column as null column hack, 3) values
This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
Youi alieinaiive is io use ile !"#$%&'(, )*+,&$'(, and +$-$&$'( meilods on
ile ./0!&$1,&,2,#$ objeci. Tlese aie buildei soiis of meilods, in ilai iley
bieal down ile SQL siaiemenis inio discieie clunls, ilen iale ilose
clunls as paiameieis.
Foi example, leie we !"#$%&'( a new iow inio oui 34"#&,"&# iable:
*%!5,&$654!+6!"#$%&&'(('1!,-478%,**$%69%,**$%(6:
66;4"&$"&<,-)$#65,-)$#="$96)#*+%*+,-./%&'>(?
665,-)$#@!/+'A&!&-$AB69%,**$%@0%+12+.%'((?
665,-)$#@!/+'A5,-)$AB69%,**$%@0%+,-./%'((?
66+2@0%+3"2+-4.%5-+-4-&%'(@2*&%"+'A34"#&,"&#AB6A&!&-$AB65,-)$#(?
6634"#&,"&#;)%#4%@"%6/%"7'(?
C
Tlese meilods male use of ;4"&$"&<,-)$# objecis, wlicl implemeni a D,*-
esque inieiface, albeii one ilai las addiiional meilods foi woiling wiil
SQLiie iypes. Foi example, in addiiion io 7$&'( io ieiiieve a value by iis ley,
you lave 7$&E#F"&$7$%'(, 7$&E#.&%!"7'(, and so foiil.
Tle !"#$%&'( meilod iales ile name of ile iable, ile name of one column
as ile null column lacl, and a ;4"&$"&<,-)$# wiil ile iniiial values you
wani pui inio ilis iow. Tle null column lacl is foi ile case wleie ile
;4"&$"&<,-)$# insiance is empiy - ile column named as ile null column
lacl will be expliciily assigned ile value GH00 in ile SQL FG.IJK siaiemeni
geneiaied by !"#$%&'(.
Tle )*+,&$'( meilod iales ile name of ile iable, a ;4"&$"&<,-)$#6
iepieseniing ile columns and ieplacemeni values io use, an opiional 8LIJI6
clause, and an opiional lisi of paiameieis io fill inio ile 8LIJI clause, io
ieplace any embedded quesiion mails (M). Since )*+,&$'( only ieplaces
columns wiil fixed values, veisus ones compuied based on oilei
infoimaiion, you may need io use $N$3./0'( io accomplisl some ends. Tle
8LIJI clause and paiameiei lisi woils alin io ile posiiional SQL
paiameieis you may be used io fiom oilei SQL APIs.
312
SQLite Primer

Alternative to add/delete/modify data: use insert(), update(),


delete() methods on SQLiteDatabase object

Delete() has parameters:

table,

optional where clause

corresponding parameters to ll the where clause ?

Example: remove single row with matching _ID value


This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
Tle !"#"$"%& meilod woils alin io '(!)$"%&, ialing ile name of ile iable,
ile opiional *+,-, clause, and ile coiiesponding paiameieis io fill inio ile
*+,-, clause. Foi example, leie we !"#"$"%& a iow fiom oui ./01$)0$1 iable,
given iis _ID:
(234)$"54/3!5!"#$%&&'%(%)%%#/0652/78!&59
55:$2306;<5)261=9:$2306>*+(,%-.%2/78!&?@
55!A>/%)0"1)+2(%'+)+2+&%%&>3%(%)%%B./01$)0$1BC5BD8E=FBC5)261&@
55./01$)0$1G'21/2>"%4,%"5%&@
?
What Goes Around, Comes Around
As wiil 8H:,-I, JKELI,, and E,M,I,, you lave iwo main opiions foi ieiiieving
daia fiom a SQLiie daiabase using :,M,GI:
i. You can use 2)7N'"2O%& io invole a :,M,GI siaiemeni diiecily, oi
:. You can use P'"2O%& io build up a queiy fiom iis componeni paiis
Confounding maiieis fuiilei is ile :NM3$"N'"2OQ'3#!"2 class and ile issue
of cuisois and cuisoi facioiies. Lei's iale all of ilis one piece ai a iime.
!"#$%&'()'*
Tle simplesi soluiion, ai leasi in ieims of ile API, is 2)7N'"2O%&. Simply call
ii wiil youi SQL :,M,GI siaiemeni. Tle :,M,GI siaiemeni can include
posiiional paiameieis; ile aiiay of ilese foims youi second paiameiei io
2)7N'"2O%&. So, we wind up wiil:
./01$)0$1G'21/2=!A
555555555555555555>/%)6%+3+2(%'+)+2+&%%&
555555555555555555>"+78,%"5%B:,M,GI5D8EC5$3$#"C54)#'"5BR
555555555555555555555555555BS-TU5./01$)0$15T-E,-5QV5$3$#"BC
5555555555555555555555555550'##&@
Tle ieiuin value is a G'21/2, wlicl coniains meilods foi iieiaiing ovei
iesulis (see below).
313
SQLite Primer
Two ways to retrieve data using SELECT:

use rawQuery() to invoke a SELECT statement directly, or

use query() to build up a query from its component parts

Example for a raw query:

get (id,title,value) triple for all rows in table constants

results are ordered by entries in column title

result is accessible via a Cursor object


This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
Tle !"#"$"%& meilod woils alin io '(!)$"%&, ialing ile name of ile iable,
ile opiional *+,-, clause, and ile coiiesponding paiameieis io fill inio ile
*+,-, clause. Foi example, leie we !"#"$"%& a iow fiom oui ./01$)0$1 iable,
given iis _ID:
(234)$"54/3!5!"#$%&&'%(%)%%#/0652/78!&59
55:$2306;<5)261=9:$2306>*+(,%-.%2/78!&?@
55!A>/%)0"1)+2(%'+)+2+&%%&>3%(%)%%B./01$)0$1BC5BD8E=FBC5)261&@
55./01$)0$1G'21/2>"%4,%"5%&@
?
What Goes Around, Comes Around
As wiil 8H:,-I, JKELI,, and E,M,I,, you lave iwo main opiions foi ieiiieving
daia fiom a SQLiie daiabase using :,M,GI:
i. You can use 2)7N'"2O%& io invole a :,M,GI siaiemeni diiecily, oi
:. You can use P'"2O%& io build up a queiy fiom iis componeni paiis
Confounding maiieis fuiilei is ile :NM3$"N'"2OQ'3#!"2 class and ile issue
of cuisois and cuisoi facioiies. Lei's iale all of ilis one piece ai a iime.
!"#$%&'()'*
Tle simplesi soluiion, ai leasi in ieims of ile API, is 2)7N'"2O%&. Simply call
ii wiil youi SQL :,M,GI siaiemeni. Tle :,M,GI siaiemeni can include
posiiional paiameieis; ile aiiay of ilese foims youi second paiameiei io
2)7N'"2O%&. So, we wind up wiil:
./01$)0$1G'21/2=!A
555555555555555555>/%)6%+3+2(%'+)+2+&%%&
555555555555555555>"+78,%"5%B:,M,GI5D8EC5$3$#"C54)#'"5BR
555555555555555555555555555BS-TU5./01$)0$15T-E,-5QV5$3$#"BC
5555555555555555555555555550'##&@
Tle ieiuin value is a G'21/2, wlicl coniains meilods foi iieiaiing ovei
iesulis (see below).
313
SQLite-Primer

Alternative: Regular Query: takes discrete pieces of SELECT statement


and builds the query from them

The name of the table to query against

The list of columns to retrieve

The WHERE clause, optionally including positional parameters

The list of values to substitute in for those positional parameters

The GROUP BY clause, if any

The HAVING clause, if any

The ORDER BY clause, if any


This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
!"#$%&#%$'()$")*+,
------------------.!"#$"%&%'(")%#%'%*"/0
------------------.+%,-."+//12343'5-6789-%:%;<9-=&;(<-1>
---------------------------1?@AB-!"#$%&#%$-A@83@-CD-%:%;<19
---------------------------#(;;0E
Tle ieiuin value is a '()$"), wlicl coniains meilods foi iieiaiing ovei
iesulis (see below).
If youi queiies aie pieiiy mucl baled inio youi applicaiion, ilis is a veiy
siiaiglifoiwaid way io use ilem. Howevei, ii geis complicaied if paiis of
ile queiy aie dynamic, beyond wlai posiiional paiameieis can ieally
landle. Foi example, if ile sei of columns you need io ieiiieve is noi
lnown ai compile iime, puiieiing aiound concaienaiing column names
inio a comma-delimiied lisi can be annoying...wlicl is wleie F(<)G/0-
comes in.
!"#$%&'()$"'*"+
Tle F(<)G/0 meilod iales ile discieie pieces of a SELECT siaiemeni and
builds ile queiy fiom ilem. Tle pieces, in oidei ilai iley appeai as
paiameieis io F(<)G/0, aie:
! Tle name of ile iable io queiy againsi
! Tle lisi of columns io ieiiieve
! Tle HI3@3 clause, opiionally including posiiional paiameieis
! Tle lisi of values io subsiiiuie in foi ilose posiiional paiameieis
! Tle J@AKL-CD clause, if any
! Tle IMN7OJ clause, if any
! Tle A@83@-CD clause, if any
Tlese can be #(;; wlen iley aie noi needed (excepi ile iable name, of
couise):
2%):#PQR-!";(S#$*T17819-1:#=<#%")G1UE
2%):#PQR-V&)S$*T1$#:!W;<X):%Y1UE
464
This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
!"#$%#&#'$"()*+,-!"#$%./01+2')$/3&4%("56$3&/675'*8/3
&&&&&&&&&&&&&&&&&&&&&&&97#5$3&6"((3&6"((3&6"((:;
!"#$%&'()"*)"
No maiiei low you execuie ile queiy, you gei a !"#$%# bacl. Tlis is ile
Andioid]SQLiie ediiion of ile daiabase cuisoi, a concepi used in many
daiabase sysiems. Wiil ile cuisoi, you can:
! Find oui low many iows aie in ile iesuli sei via 2')!%"6).:
! Iieiaie ovei ile iows via 5%<'=%>1#$).:, 5%<'=%?'@).:, and
1$AB)'#C7$).:
! Find oui ile names of ile columns via 2')!%("56?75'$.:, conveii
ilose inio column numbeis via 2')!%("56D6+'@.:, and gei values foi
ile cuiieni iow foi a given column via meilods lile 2')E)#162.:,
2')D6).:, eic.
! Re-execuie ile queiy ilai cieaied ile cuisoi via #'F"'#G.:
! Release ile cuisoi's iesouices via 4(%$'.:
Foi example, leie we iieiaie ovei a 01+2')$ iable eniiies:
!"#$%#&#'$"()*
&&+,-$&'("#$%./EHCH!=&DI3&675'3&16<'6)%#G&>JKL&01+2')$/3&6"((:;
0M1('&.N#'$"()-)*+#,*-#./.::&O
&16)&1+*#'$"()-0#/12/.P:;
&E)#162&675'*#'$"()-0#/3/$420.Q:;
&16)&16<'6)%#G*#'$"()-0#/12/.R:;
&SS&+%&$%5')M162&"$'B"(&01)M&)M'$'
T
#'$"()-56*7#.:;
You can also wiap a !"#$%# in a E159('!"#$%#A+79)'# oi oilei
implemeniaiion, ilen land ile iesuliing adapiei io a C1$)U1'0 oi oilei
seleciion widgei. Noie, ilougl, ilai if you aie going io use !"#$%#A+79)'# oi
iis subclasses (lile E159('!"#$%#A+79)'#), youi iesuli sei of youi queiy !"#$%
coniain an iniegei column named VDI ilai is unique foi ile iesuli sei. Tlis
465
SQLite-Primer

A Query returns a Cursor to iterate over returned results:

With the cursor, you can:

Find out how many rows are in the result set via getCount()

Iterate over the rows via moveToFirst(), moveToNext(), and isAfterLast()

Find out the names of the columns via getColumnNames(), convert those into column
numbers via getColumnIndex(), and get values for the current row for a given column
via methods like getString(), getInt(), etc.

Re-execute the query that created the cursor via requery()

Release the cursor's resources via close()


This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Managing and Accessing Local Databases
!"#$%#&#'$"()*+,-!"#$%./01+2')$/3&4%("56$3&/675'*8/3
&&&&&&&&&&&&&&&&&&&&&&&97#5$3&6"((3&6"((3&6"((:;
!"#$%&'()"*)"
No maiiei low you execuie ile queiy, you gei a !"#$%# bacl. Tlis is ile
Andioid]SQLiie ediiion of ile daiabase cuisoi, a concepi used in many
daiabase sysiems. Wiil ile cuisoi, you can:
! Find oui low many iows aie in ile iesuli sei via 2')!%"6).:
! Iieiaie ovei ile iows via 5%<'=%>1#$).:, 5%<'=%?'@).:, and
1$AB)'#C7$).:
! Find oui ile names of ile columns via 2')!%("56?75'$.:, conveii
ilose inio column numbeis via 2')!%("56D6+'@.:, and gei values foi
ile cuiieni iow foi a given column via meilods lile 2')E)#162.:,
2')D6).:, eic.
! Re-execuie ile queiy ilai cieaied ile cuisoi via #'F"'#G.:
! Release ile cuisoi's iesouices via 4(%$'.:
Foi example, leie we iieiaie ovei a 01+2')$ iable eniiies:
!"#$%#&#'$"()*
&&+,-$&'("#$%./EHCH!=&DI3&675'3&16<'6)%#G&>JKL&01+2')$/3&6"((:;
0M1('&.N#'$"()-)*+#,*-#./.::&O
&16)&1+*#'$"()-0#/12/.P:;
&E)#162&675'*#'$"()-0#/3/$420.Q:;
&16)&16<'6)%#G*#'$"()-0#/12/.R:;
&SS&+%&$%5')M162&"$'B"(&01)M&)M'$'
T
#'$"()-56*7#.:;
You can also wiap a !"#$%# in a E159('!"#$%#A+79)'# oi oilei
implemeniaiion, ilen land ile iesuliing adapiei io a C1$)U1'0 oi oilei
seleciion widgei. Noie, ilougl, ilai if you aie going io use !"#$%#A+79)'# oi
iis subclasses (lile E159('!"#$%#A+79)'#), youi iesuli sei of youi queiy !"#$%
coniain an iniegei column named VDI ilai is unique foi ile iesuli sei. Tlis
465
Wheres the
bug?
Transactions beyond a single SQL statement

Default behavior:

Each SQL statement executes its own transaction

Why bother to have more statements in a single transaction?

Data integrity may depend on success of set of statements

Performance as each transaction involves disk I/O

How to achieve this?


This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Tle InsertTask is supplied a ContentValues objeci wiil oui title and value, jusi
as we used in onCreate() of DatabaseHelper. In doInBackground(), we gei a
wiiiable daiabase fiom DatabaseHelper and peifoim ile insert() call, so ile
daiabase I]O does noi iie up ile main applicaiion iliead.
Howevei, in doInBackground(), we '.* call doQuery() again. Tlis ieiiieves a fiesl
Cursor wiil ile new iosiei of consianis. including ile one we jusi inseiied. As wiil
LoadCursorTask, we execuie doQuery() in doInBackground() io leep ile daiabase
I]O o ile main applicaiion iliead.
Tlen, in onPostExecute(), we can safely updaie ile UI wiil ile new Cursor. We do
ilis by calling changeCursor() on oui CursorAdapter, ieiiieved fiom ile fiagmeni
via getListAdapter(). changeCursor() will swap oui oui old Cursor in oui
SimpleCursorAdapter wiil ile new one, auiomaiically updaiing ile ListView along
ile way.
Setting Transaction Bounds
By defauli, eacl SQL siaiemeni execuies in iis own iiansaciion ilis is faiily
iypical belavioi foi a SQL daiabase, and SQLiie is no excepiion.
Tleie aie iwo ieasons wly you migli wani io lave youi own iiansaciion bounds,
laigei ilan a single siaiemeni:
i. Tle classic "we need ile siaiemenis io succeed oi fail as a wlole" iaiionale,
foi mainiaining daia iniegiiiy
:. Peifoimance, as eacl iiansaciion involves disl I]O and, as las been noied,
disl I]O can be iailei slow
Tle basic iecipe foi youi own iiansaciions is:
try try {
db.beginTransaction();
// several SQL statements in here
db.setTransactionSuccessful();
}
finally finally {
db.endTransaction();
}
SQLITE DATABASES
477
SQLite-Primer

SQLite Database resides on machines ash memory

fairly quick read operations,

potentially slow write operations

Emulator works on les, may mislead you with quick write


operations

DB operations should operate in an asyncTask or separate


thread to avoid disruption to the UI thread

Database can be explored from adb shell with sqlite3

Database can also be pulled from device, manipulated


externally with SQLite-aware client and pushed back onto
device
Background Operations with SQLite

SQLite is thread safe if threads operate on same instance of


DataBaseHelper.

suggests use of Singleton Pattern (Horstmann Ch 10)

SQLite operations are heavy:

Instantiation on demand:

rst access causes call to dbhelper.onCreate()

Queries & updates can be time consuming

should run on AsyncTask or separate thread


Singleton Pattern (Horstmann, Ch 10)

Context

All clients need to access a single shared instance of a


class.

You want to ensure that no additional instances can be


created accidentally.

Solution

Dene a class with a private constructor.

The class constructs a single instance of itself.

Supply a static method that returns a reference to the


single instance.
Singleton Random Number Generator
public nal class SingleRandom {
private nal Random generator;
private static SingleRandom instance = null ;
private static long theSeed = 0 ;
private SingleRandom() {
generator = (0 != theSeed) ? new Random(theSeed) : new Random();
}
public static void setSeed(nal long seed) { theSeed = seed; }
public static SingleRandom getRandom() {
if (null == instance)
instance = new SingleRandom();
return instance;
}
public int nextInt() { return generator.nextInt(); }
}
Instantiating a Single DataBaseHelper

Constructor of DataBaseHelper needs a Context

if current activity is used (which may come and go) the


DataBaseHelper prohibits garbage collection thanks to its
reference

Suggestion: use getActivity().getApplicationContext() to


obtain Context of overall application which is a singleton
itself and guaranteed to exist (as it is created shortly after
process creation).

Apply Singleton Pattern

less robust: use public static variable to share reference for


single DataBaseHelper
Asynchronous DB Update

Constants Demo Example

User adds a title & value pair

App needs to:

obtain data from UI

add data to SQLite DB

update data on screen

in a separate thread or AsynchTask


This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Fiqure i6,. Tbe ConstontsBrowser Somple, AJJ Constont Dioloq
If ile usei flls in a consiani and clicls ile "OK" buiion, we need io inseii a new
iecoid in ile daiabase. Tlai is landled via an InsertTask:
private private class class InsertTask InsertTask extends extends AsyncTask<ContentValues, Void, Void> {
private private Cursor constantsCursor=null null;
@Override
protected protected Void doInBackground(ContentValues... values) {
db.getWritableDatabase().insert(DatabaseHelper.TABLE,
DatabaseHelper.TITLE, values[0]);
constantsCursor=doQuery();
constantsCursor.getCount();
return return(null null);
}
@Override
public public void onPostExecute(Void arg0) {
((CursorAdapter)getListAdapter()).changeCursor(constantsCursor);
}
}
SQLITE DATABASES
476
Image: M.Murphy, Android 4.3 Fig 167
Asynchronous DB Update

constantsCursor shared to deliver query results to UI


This document is licensed for Peter Kemper's exclusive use by CommonsWare, LLC
Fiqure i6,. Tbe ConstontsBrowser Somple, AJJ Constont Dioloq
If ile usei flls in a consiani and clicls ile "OK" buiion, we need io inseii a new
iecoid in ile daiabase. Tlai is landled via an InsertTask:
private private class class InsertTask InsertTask extends extends AsyncTask<ContentValues, Void, Void> {
private private Cursor constantsCursor=null null;
@Override
protected protected Void doInBackground(ContentValues... values) {
db.getWritableDatabase().insert(DatabaseHelper.TABLE,
DatabaseHelper.TITLE, values[0]);
constantsCursor=doQuery();
constantsCursor.getCount();
return return(null null);
}
@Override
public public void onPostExecute(Void arg0) {
((CursorAdapter)getListAdapter()).changeCursor(constantsCursor);
}
}
SQLITE DATABASES
476
On Using a Database

Creating a database

How to create and ll database when used rst time after


installation of app?

How to update/adjust an existing database to a new


schema that comes with an update for an existing app?

Reading data from a database / writing data to a database

How to open an existing database?

How to create/read/write/modify/delete particular entries?

How to close a database?

Você também pode gostar