You are on page 1of 15

Home (http://www.androidbrasilprojetos.org/) Projetos (http://www.androidbrasilprojetos.org/projetos-2/) FAQ (http://www.androidbrasilprojetos.org/faq/) Contato (http://www.androidbrasilprojetos.org/contato/) About (http://www.androidbrasilprojetos.

org/about/) Search
(http://www.androidbrasilprojetos.org/feed/) (http://twitter.com/#!/blog_abp)

(http://www.androidbrasilprojetos.org)

Home (http://www.androidbrasilprojetos.org) Android Brasil Projetos (http://www.androidbrasilprojetos.org/category/androidbrasilprojetos/) Tutoriais (http://www.androidbrasilprojetos.org/category/tutoriais/) Projetos (http://www.androidbrasilprojetos.org/category/projetos/) Aplicativos (http://www.androidbrasilprojetos.org/category/aplicativos/) Personalizao (http://www.androidbrasilprojetos.org/category/personalizacao/)

Introduo a banco de dados Android


outubro 31st, 2011 Jlio Csar Bueno Cotta

C r ir

12

(http://twitter.com/share)

(http://fandigunawan.files.wordpress.com/2007/08/sqlite.gif)

Bem, se voc est comeando no desenvolvimento Android agora deve ter vrias duvidas a respeito desse assunto e pretendo, de modo incremental, falar sobre acesso ao SQLite por aqui no blog ABP. Porm no pretendo ensinar os conceitos de SQL por aqui, isso voc aprende na universidade ou lendo um livro e praticando. O que pretendo mostrar, em uma serie de posts, como utilizar a API de acesso ao SQLite, o gerenciador de banco de dados nativo do Android, mostrarei como o Google ensina nos seus exemplos, as falhas na abordagem dos exemplos deles no quesito manutenabilidade, mostrarei como criar uma biblioteca de consultas que possa ser utilizada em todos seus projetos Android e tudo isso falando um pouco

de engenharia de software no acesso as tabelas do banco. No garanto que o meu jeito de fazer as coisas o melhor, o mais otimizado com certeza no , mas acredito que seja uma maneira pratica do ponto de vista do desenvolvedor de manter a consistncia das tabelas do sistema sem ficar espalhando cdigo de consultas SQL por todo o projeto. Antes de falarmos do acesso ao banco, me diga, o que uma tabela? Para mim, uma tabela uma entidade que armazena uma lista de um dado modelo, assim como uma classe Java tambm armazena um modelo de alguma informao, cada linha da tabela armazena a informao de um modelo, seja essa informao a modelagem de um Cliente, uma Cadeira ou um Item emprestado para um amigo. claro que existem muitas diferenas entre tabelas e classes Java, mas no sentido geral, ambas servem para armazenar informaes de acordo com atributos comuns. Uma das diferenas entre tabelas e objetos que um objeto Java no persistente, ou seja, as informaes dentro dele so perdidas ao fechar o programa. Eu falei que no iria ensinar SQL aqui e no irei mesmo, o que estou dizendo que podemos e (acredito) devemos pensar nas tabelas do mesmo modo que pensamos em objetos (com algumas restries). Isso pode no estar claro neste primeiro post, mas ficar claro nos posts subseqentes. Vamos voltar ao banco, vou mostrar como criar um banco de dados simples, mas nem por isso rudimentar. Estou utilizando a modelagem de banco do projeto Emprstimos do grupo, ento criarei um projeto no Eclipse de nome EmprestaAi. O nosso banco de dados contem somente duas tabelas. A tabela Emprstimos e a tabela Categorias, assim como modeladas abaixo:

(http://www.androidbrasilprojetos.org/wpcontent/uploads/2011/10/Emprestimos_dia.jpeg)

Tabelas

A tabela Categoria nada mais do que um INTEGER de nome _ID e um TEXT de nome DESCRICAO, que na verdade o nome da categoria.

A tabela Emprstimos possui mais campos: _ID: Identificador nico; ITEM: Nome do item a ser emprestado; DESCRICAO: Uma pequena descrio do item ou comentrio; STATUS: Diz se o item est sendo emprestado para voc ou se voc est pegando o item emprestado, o SQLite no possui boolean e por isso utilizamos constantes inteiras para definir o estado. STATUS_ALARME: Tambm deveria ser um boolean para indicar se o alarme para lembrar de devolver o item est ativado ou no. Tambm so utilizadas constantes inteiras para representar o estado. DATA_DEVOLUCAO: O SQLite at tem um jeito de guardar DATE no banco, mas na verdade o que ele faz uma converso automtica entre o DATE e um Long (que na verdade um INTEGER no banco), para simplificar as coisas eu guardo o nmero de milisegundos do Date (o do Java) no banco declarando esse campo como INTEGER; (Fica mais claro ao ver o cdigo) ID_CATEGORIA: uma chave extrangeira da tabela Categoria para sabermos a qual categoria o item pertence, algo como CDs , Livros seriam boas categorias. ID_CONTATO: Guarda o ID de um contato da agenda telefnica do aparelho, como no sei dizer ao sistema que uma chave extrangeira de l, sempre necessrio ter uma ateno maior a esse campo para manter a integridade do sistema; NOME_CONTATO: Quando a pessoa que est pegando um item emprestado no consta na lista de contatos, utilizamos esse campo para entrar com o nome dela, caso contrrio, ele permanecer em branco.

Bem, so somente duas tabelas, mas acredito que vamos poder abordar vrios aspectos do banco de dados Android utilizando os atributos das tabelas acima, o manuseio de booleans , datas e chaves extrangeiras so coisas que costumam gerar duvidas a qualquer iniciante no desenvolvimento Android, isso ser explicado no proxmo post sobre o assunto, vamos nos conter ao mais bsico possvel neste aqui. Alm dos tipos utilizados nas tabelas acima, INTEGER e TEXT, existem NULL, REAL e BLOB, mas basicamente utilizamos somente os trs abaixo na maior parte do tempo*:

INTEGER: Serve para guardar int, Integer e Long; TEXT: Guarda String de qualquer tamanho; REAL: Guarda float e double;

Se quiser mais informaes sobre os tipos do SQLite, inclusive sobre a utilizao de DATE, acesse esse link (http://www.sqlite.org/datatype3.html), *Post introdutrio, lembra? J estou falando demais citando sobre o DATE aqui. Como gosto de ter uma viso completa do DB que vou desenvolver, optei por mostrar aqui todas as (duas) tabelas do banco, mesmo que neste post somente trabalhemos com uma delas. Agora que sabemos o que queremos guardar, vamos comear a ver como persistir esses dados no banco. Vamos criar uma classe chamada DbAdapter.java e dentro dela declarar o seguinte:

? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) JAVA

1 2 3 4 5 6

S S S S

( ( ( (

:/ / :/ / :/ / :/ /

. . . .

. . . .

/ / / /

? = &= ? = &= ? = &= ? = &=

%A 3 %A 3 %A 3 %A 3

+ + + +

. . . .

. . . .

& & & &

II2 %0 =%7 2F II2 %0 =%7 2F II2 %0 =%7 2F II2 %0 =%7 2F

%0 2L %0 2L %0 2L %0 2L

)TBL_AEOI ="AEOI" AEACTGRA CTGRA; )CLN_DCTGRA="i" OUAI_AEOI _d; )CLN_ECIA_AEOI ="ECIA" OUADSRCOCTGRA DSRCO )TBL_MRSIO ="MRSIO" AEAEPETMS EPETMS;

7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4 3 5 3 6 3 7 3 8 3 9 4 0 4 1 4 2 4 3 4 4

S S S S S S S S S

( ( ( ( ( ( ( ( (

:/ / :/ / :/ / :/ / :/ / :/ / :/ / :/ / :/ /

. . . . . . . . .

. . . . . . . . .

/ / / / / / / / /

? = &= ? = &= ? = &= ? = &= ? = &= ? = &= ? = &= ? = &= ? = &=

%A 3 %A 3 %A 3 %A 3 %A 3 %A 3 %A 3 %A 3 %A 3 %A 3

+ + + + + + + + + +

. . . . . . . . . .

. . . . . . . . . .

& & & & & & & & & &

II2 %0 =%7 2F II2 %0 =%7 2F II2 %0 =%7 2F II2 %0 =%7 2F II2 %0 =%7 2F II2 %0 =%7 2F II2 %0 =%7 2F II2 %0 =%7 2F II2 %0 =%7 2F II2 %0 =%7 2F

%0 2L %0 2L %0 2L %0 2L %0 2L %0 2L %0 2L %0 2L %0 2L %0 2L

)CLN_DEPETMS="i" OUAI_MRSIO _d; )CLN_TMEPETMS="TM; OUAIE_MRSIO IE" )CLN_ECIA_MRSIO ="ECIA" OUADSRCOEPETMS DSRCO )CLN_TTSEPETMS="TTS; OUASAU_MRSIO SAU"

)CLN_AADVLCOEPETMS="AADV OUADT_EOUA_MRSIO DT_EO

)CLN_TTSAAM_MRSIO ="TTSAA OUASAU_LREEPETMS SAU_L )CLN_DCNAOEPETMS="DCNAO OUAI_OTT_MRSIO I_OTT" )CLN_OTT_MRSIO ="OTT" OUACNAOEPETMS CNAO; )CTGRACET_AL ="RAETBE" AEOI_RAETBE CET AL

)CLN_DCTGRAEPETMS="DCTGR OUAI_AEOI_MRSIO I_AEOI

S ( :/ . / . / ? = &= +TBL_AEOI +" ( +CLN_DCTGRA AEACTGRA " OUAI_AEOI +"ITGRPIAYKYATICEET " NEE RMR E UONRMN, +CLN_ECIA_AEOI +"tx ntnl)" OUADSRCOCTGRA et o ul;;

S ( :/ . / . / ? = &= %A 3 + +TBL_MRSIO +" ( +CLN_DEPETMS AEAEPETMS " OUAI_MRSIO +"ITGRPIAYKYATICEET "+CLN_TMEPETMS NEE RMR E UONRMN, OUAIE_MRSIO +"TX NTNL, +CLN_ECIA_MRSIO ET O UL" OUADSRCOEPETMS +"TX NTNL, +CLN_TTSEPETMS ET O UL" OUASAU_MRSIO +"ITGRNTNL, +CLN_AADVLCOEPETMS NEE O UL" OUADT_EOUA_MRSIO +"ITGRNTNL, +CLN_TTSAAM_MRSIO NEE O UL" OUASAU_LREEPETMS +"ITGRNTNL, +CLN_DCTGRAEPETMS NEE O UL" OUAI_AEOI_MRSIO +"ITGRNTNL, +CLN_DCNAOEPETMS NEE O UL" OUAI_OTT_MRSIO +"ITGR"+CLN_OTT_MRSIO +"TX," NEE, OUACNAOEPETMS ET +"FRINKY("+CLN_DCTGRAEPETMS OEG E OUAI_AEOI_MRSIO +") RFRNE "+TBL_AEOI +"( +CLN_DCTGRA EEECS AEACTGRA " OUAI_AEOI +")O DLT RSRC O UDT CSAE;; N EEE ETIT N PAE ACD)" S ( :/ / DtbsHle mbepr aaaeepr DHle; SLtDtbs mb Qieaaae D; S
( :/ / . . / ? = &= %A 3 +

&

II2 %0 =%7 2F

%0 2L

)EPETMSCET_AL ="RAETBE" MRSIO_RAETBE CET AL

&

II2 %0 =%7 2F

%0 2L

)TG="bdpe" A DAatr;

? = &=

%A 3

&

II2 %0 =%7 2F

%0 2L

)D_AE="B" BNM AP;

DTBS_ESO =1 AAAEVRIN ; C
( :/ / . . / ? = &= %A 3 + . . & II2 %0 =%7 2F %0 2L )mt; Cx

O cdigo acima nada mais do que a declarao do nome das tabelas e suas colunas. Depois essas Strings constantes e estticas so utilizadas para definir as Strings de criao das tabelas do banco e mais algumas coisinhas. D um certo trabalho fazer isso, mas h um ganho enorme em vrios sentidos, antes de seguir em frente pense comigo. J parou para pensar nos problemas que voc teria ao tentar criar uma tabela assim:

? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) JAVA

1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6

/Teh d cdg rtrd d ttra d NtPde /rco e io eiao o uoil o oea m /ht:/eeoe.nri.o/eore/uoil/oea/ne.tl /tp/dvlpradodcmrsucsttrasntpdidxhm S S S
( ( ( :/ / :/ / :/ / . . . . . . / / / ? = &= ? = &= ? = &= %A 3 %A 3 %A 3 + + + . . . . . . & & & II2 %0 =%7 2F II2 %0 =%7 2F II2 %0 =%7 2F %0 2L %0 2L %0 2L )KYTTE="il" E_IL tte; )KYBD ="oy; E_OY bd" )KYRWD="i" E_OI _d;

/* * *Dtbs ceto slsaeet aaae rain q ttmn * / S ( :/ . / . / ? = &= "raetbents(i itgrpiaykyaticeet " cet al oe _d nee rmr e uonrmn, +"il tx ntnl,bd tx ntnl)" tte et o ul oy et o ul;; S S
( ( :/ / :/ / . . . . / / ? = &= ? = &=

%A 3

&

II2 %0 =%7 2F

%0 2L

)DTBS_RAE= AAAECET

%A 3 %A 3

+ +

. .

. .

& &

II2 %0 =%7 2F II2 %0 =%7 2F

%0 2L %0 2L

)DTBS_AE="aa; AAAENM dt" )DTBS_AL ="oe" AAAETBE nts;

O trecho acima foi retirado de um dos tutoriais oficiais do Developer Android (http://www.androidbrasilprojetos.org//http://developer.android.com/resources/tutorials/notepad/index.html). A abordagem acima a seguinte, foram declaradas Strings para definir constantes para cada coluna da tabela notes (assim como eu fiz), mas na hora de definir a String de criao da tabela (DATABASE_CREATE) o texto foi chumbado no cdigo fonte e no utilizaram as constantes previamente criadas. Essa atitude at aceitvel em um tutorial, pois facilita a leitura do cdigo e no existe manuteno do mesmo, mas em um projeto real no me faa isso pelo bem da sua sanidade mental! Em um projeto real temos vrias tabelas, cada tabela com vrias colunas. Voc vai errar ao escrever o nome de pelo menos uma coluna e vai perder horas da sua vida debugando cdigo at ver que trocou uma letra em um nome de coluna em algum lugar. Ento, basicamente, a definio dos nomes de tabelas e colunas com a utilizao de Strings constantes pode consumir algum tempo a principio, mas pode te livrar de erros bobos e que fariam voc perder bastante tempo. O mencionado acima uma das boas praticas de engenharia de software relacionadas ao gerenciamento de banco no Android, porm h muito o que melhorar ainda. Neste tutorial o gerenciamento do banco, a definio das tabelas e as consultas ficaro no mesmo arquivo, se seu projeto tiver umas 5 ou 6 tabelas, esse arquivo vai ficar com umas mil linhas de cdigo cheio de consultas e constantes. Voc acha isso fcil de manter? Eu no, e em dos prximos posts dessa serie j vamos dar um jeito nisso. Voltando a classe DbAdapter.java, constantes de banco definidas certo?! Ok. O prximo passo estender a classe SQLiteOpenHelper e sobrescrever alguns mtodos, como o onOpen(SQLiteDatabase db), onCreate(SQLiteDatabase db) e o onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion). O cdigo abaixo faz isso:

? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) JAVA

1 2

DtbsHle aaaeepr

SLtOeHle { Qiepnepr

3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4 3 5 3 6 3 7 3 8 3 9 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 } 7

@vrie Oerd oOe(Qieaaaed) npnSLtDtbs b { .npnd) oOe(b; (d.sedny) !biRaOl() { d.xcQ(PAM frinky=N"; beeSL"RGA oeg_esO;) } }

DtbsHle( aaaeeprC ( :/ . / (otx,D_AE cnet BNM, } @vrie Oerd

? = &=

%A 3

&

II2 %0 =%7 2F

%0 2L

)cnet { otx)

,DTBS_ESO) AAAEVRIN;

oCet(Qieaaaed){ nraeSLtDtbs b d.xcQ(AEOI_RAETBE; beeSLCTGRACET_AL) d.xcQ(MRSIO_RAETBE; beeSLEPETMSCET_AL) /Isr vlrsiiii n tbl CTGRA /nee aoe ncas a aea AEOI Cnetausvle = otnVle aus Cnetaus) otnVle(; vle.u(OUADSRCOCTGRA "oo"; ausptCLN_ECIA_AEOI, Tds) d.netTBL_AEOI, bisr(AEACTGRA ,vle) aus; vle.la(; auscer) vle.u(OUADSRCOCTGRA "D"; ausptCLN_ECIA_AEOI, Cs) d.netTBL_AEOI, bisr(AEACTGRA ,vle) aus; vle.la(; auscer) vle.u(OUADSRCOCTGRA "irs) ausptCLN_ECIA_AEOI, Lvo"; d.netTBL_AEOI, bisr(AEACTGRA ,vle) aus; Lgw"bdpe""Bcid cmscso"; o.(DAatr,D rao o ues!) } @vrie Oerd oUgaeSLtDtbs d, nprd(Qieaaae b odeso, lVrin nweso){ eVrin LgwTG "taiad obnod ddsd vr o"+odeso o.(A, Aulzno ac e ao a es lVrin +"pr "+nweso aa eVrin +" tdso ddssroprio!) , oo s ao e edds"; d.xcQ(DO TBEI EIT "+TBL_AEOI) beeSL"RP AL F XSS AEACTGRA; d.xcQ(DO TBEI EIT "+TBL_MRSIO) beeSL"RP AL F XSS AEAEPETMS; oCet(b; nraed) }

Note que esta uma classe private de nome DatabaseHelper. onOpen(SQLiteDatabase db) executado toda vez que se cria um objeto dessa classe e o nosso ali faz com que a utilizao de chaves estrangeiras seja ativada para o banco. Acho que at o Android 2.1 a utilizao de chaves extrangeiras no era possvel, mas mesmo se voc executar isso em uma verso sem suporte no haver problemas. DatabaseHelper.onCreate executado somente na primeira vez que a classe DbAdapter instnciada. Esse mtodo recebe como parmetro um objeto do tipo SQLiteDatabase que o verdadeiro objeto de acesso ao banco. Este objeto utilizado para executar a criao das tabelas TABELA_CATEGORIA e TABELA_EMPRESTIMOS, depois disso utilizado para inserir alguns valores padro na tabela TABELA_CATEGORIA. (Explico isso um pouco abaixo). DatabaseHelper.onUpgrade Tambm recebe um SQLiteDatabase como parmetro, mas muitas vezes o que nos interessa nesse mtodo so os outros dois parmetros oldVersion e newVersion. Eles nos informam o valor da verso antiga e da nova verso do banco. Quando estamos atualizando um aplicativo de verso, caso haja uma nova verso do banco definida, o mtodo DatabaseHelper.onUpgrade ser executado e podemos nos basear no nmero da verso para escolher quais alteraes aplicar nas tabelas do banco, por exemplo um ALTER TABLE de uma verso para outra. Falando em verso de banco, voc reparou que o construtor da classe tambm foi sobrescrito?

? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) JAVA

1 2 3 4 5 6. . . 7}

DtbsHle aaaeepr DtbsHle( aaaeeprC ( :/ . / (otx,D_AE cnet BNM, }

SLtOeHle { Qiepnepr
. / ? = &= %A 3 + . . & II2 %0 =%7 2F %0 2L )cnet { otx)

,DTBS_ESO) AAAEVRIN;

Esse construtor obrigado a executar o construtor da classe me atravs do super e passar alguns parmetros, o DB_NAME e o DATABASE_VERSION, respectivamente, o nome do banco e sua verso atual. Este ltimo valor deve ser mudado a cada vez que o banco for editado, fazendo assim que o mtodo DatabaseHelper.onUpgrade seja executado. O valor dessas constantes foram declaradas junto com as que definem as tabelas, colunas e uma instncia da classe que acabamos de definir.

? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) JAVA

1 2 3 4 5

S ( :/ / DtbsHle mbepr aaaeepr DHle; SLtDtbs mb Qieaaae D; S


( :/ /

? = &=

%A 3

&

II2 %0 =%7 2F

%0 2L

)TG="bdpe" A DAatr;

? = &=

%A 3

&

II2 %0 =%7 2F

%0 2L

)D_AE="B" BNM AP;

6 7 8

DTBS_ESO =1 AAAEVRIN ; C
( :/ / . . / ? = &= %A 3 + . . & II2 %0 =%7 2F %0 2L )mt; Cx

Veja bem, temos a classe DbAdapter com as definies das tabelas e colunas, dentro dela temos a classe private DatabaseHelper que a responsvel por criar, atualizar e nos dar um meio de acesso ao mesmo. Agora temos que definir os mtodos de DbAdapter que encapsulam o acesso ao banco. Abaixo temos o construtor de DbAdapter que recebe como parmetro um Context, o mtodo DbAdapter.open e o DbAdapter.close de vital importncia para seu programa que para cada open executado seja tambm executado um close, assim como em qualquer acesso a banco de dados relacionado de qualquer outra plataforma: Abriu o banco, tem que fechar!

? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) JAVA

1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4

DAatrC bdpe( ( .Cx=cx mt t; }

:/ /

? = &=

%A 3

&

II2 %0 =%7 2F

%0 2L

)cx { t)

DAatroe( bdpe pn) SL QE ( mbepr= DHle DtbsHle(Cx; aaaeeprmt) mb=mbeprgtrtbeaaae) D DHle.eWialDtbs(; ; } coe){ ls( mbeprcoe) DHle.ls(; mbcoe) D.ls(; }

:/ /

? = &=

%A 3

&

II2 %0 =%7 2F

%0 2L

){

O mtodo DbAdapter.open o responsvel por instnciar a mDbHelper e por adiquirir acesso com permisso de escrita ao banco (leitura tambm). Veja que mDb tambm instnciado e fechado junto de mDbHelper. Pronto, de agora em diante praticamente no precisamos mais de utilizar o objeto mDbHelper, somente o mDb o suficiente para inserir, atualizar, remover e buscar informaes nas tabelas atravs dos mtodos insert,update, delete e query. Vamos a alguns exemplos e explicaes de cada mtodo.

? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) JAVA

1 2 3

ciraeoi( raCtgraS ( :/ . / . / ? = &= Cnetausvle = otnVle aus Cnetaus) otnVle(; vle.u(OUADSRCOCTGRA dsrco; ausptCLN_ECIA_AEOI, ecia)

%A 3

&

II2 %0 =%7 2F

%0 2L

)dsrco { ecia)

4 5 6}

mbisr(AEACTGRA D.netTBL_AEOI,

,vle) aus;

Mtodo chamado quando se deseja inserir uma categoria no banco, como ID_CATEGORIA possui auto incremento somente precisamos passar sua descrio como parmetro do mtodo. Como regra padro do Android sempre inserimos um ContentValues no banco, esse objeto funciona como um HashMap, com chaves nicas e valores, so que h uma diferena. As Chaves so sempre Strings, no caso, as colunas da tabela. E alm disso, os valores podem ser de qualquer tipo primitivo envelopado do Java, no mesmo ContentValues podemos inserir tanto Strings quanto Integers, Longs ou Doubles. Desse jeito, no mtodo acima estamos dizendo: Insira na tabela TABELA_CATEGORIA uma linha, sendo que na coluna COLUNA_DESCRICAO_CATEGORIA haver o valor da String descricao .

? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) JAVA

1 2 3 4 5}

rmvraeoi( eoeCtgra

iCtgra { daeoi)

mbdlt(AEACTGRA CLN_DCTGRA+"?, D.eeeTBL_AEOI, OUAI_AEOI =" S ( :/ . / . / ? = &= %A 3

&

II2 %0 =%7 2F

%0 2L

)]{S [

:/ /

? = &=

O mtodo delete recebe como parmetros o nome da tabela, uma String com o nome da coluna que ser utilizada no WHERE concatenada com a condio, no caso o = e uma interrogao. A interrogao vai ser substituda pelo primeiro valor do array de String que passado como ltimo parmetro para o mtodo. Estamos dizendo: Remova uma linha da tabela TABELA_CATEGORIA onde COLUNA_ID_CATEGORIA for igual a idCategoria . Caso fosse preciso passar dois parmetros para o WHERE ao invs de somente um, poderamos ter feito como no exemplo abaixo:

? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) JAVA

1 2 3 4 5 6}

rmvraeoi( eoeCtgra

iCtgra S daeoi,

:/ /

? = &=

%A 3

&

II2 %0 =%7 2F

%0 2L

)dsrco ecia)

mbdlt(AEACTGRA CLN_DCTGRA+"?AD" D.eeeTBL_AEOI, OUAI_AEOI = N +CLN_ECIA_AEOI +"?, OUADSRCOCTGRA =" S ( :/ . / . / ? = &= %A 3 +

&

II2 %0 =%7 2F

%0 2L

)]{S [

:/ /

? = &=

Estamos dizendo: Remova as linhas da tabela TABELA_CATEGORIA onde coluna COLUNA_ID_CATEGORIA for igual a idCategoria e coluna COLUNA_DESCRICAO_CATEGORIA seja igual a descricao . Se for preciso ter acesso a todas as linhas guardadas na tabela TABELA_CATEGORIA, o mtodo consultarTodasCategorias o que voc precisa.

? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) JAVA

1 2 3 4 5 6}

:/ /

? = &=

%A 3 :/ /

+ .

. .

& /

II2 %0 =%7 2F ? = &=

%0 2L %A 3

)cnutroaCtgra( { oslaTdsaeois) + . . & II2 %0 =%7 2F %0 2L

mbqeyTBL_AEOI, D.ur(AEACTGRA S ( CLN_ECIA_AEOI } OUADSRCOCTGRA ,

)]{CLN_DCTG [ OUAI_AEO

) ;

O mtodo query o responsvel por fazer SELECTs no banco. O chato dele que possui 7 parmetros e lembrar de todos osso. Por enquanto contenha-se a saber que o primeiro parmetro o nome da tabela e o segundo a projeo (projection) do banco, trocando em miudos, a projeo corresponde a quais colunas sero retornadas pelo SELECT. A consulta acima seria algo como :
? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) SQL

1S L C C L N _ D C T G R A C L N _ E C I A _ A E O I F O T B L _ A E O I ; EET OUAI_AEOI,OUADSRCOCTGRA RM AEACTGRA

No se preocupe com o objeto Cursor retornado por esse mtodo por enquanto, ele ser explicado em breve. Quando for necessrio retornar somente uma categoria, utilizamos o mtodo consultarCategoria:

? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) JAVA

1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 } 5

C C

( (

:/ / :/ /

. .

. .

/ /

? = &= ? = &=

%A 3 %A 3

+ +

. .

. .

& &

II2 %0 =%7 2F II2 %0 =%7 2F ? = &= . . &

%0 2L %0 2L %A 3

)cnutraeoi( oslaCtgra )musr= Cro + . %0 2L . &

iCtgra daeoi)

SL QE

mbqey D.ur( ,TBL_AEOI, AEACTGRA S ( :/ . / . / CLN_ECIA_AEOI } CLN_DCTGRA+"?, OUADSRCOCTGRA , OUAI_AEOI =" S ( :/ . / . / ? = &= %A 3 + ) ; (Cro ! musr = ){ musrmvTFrt) Cro.oeois(; } musr Cro;

II2 %0 =%7 2F (

%0 2L :/ / .

)]{CLN_DCTG [ OUAI_AEO . / ? = &=

II2 %0 =%7 2F

)]{S [

Esse mtodo tambm utiliza o mtodo query, mas dessa vez passamos mais dois parmetros para esse mtodo. Sendo esses campos os mesmos que utilizamos no mtodo delete, eles foram o WHERE da

consulta. A consulta acima seria algo como :


? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) SQL

1S L C C L N _ D C T G R A C L N _ E C I A _ A E O I F O T B L _ A E O I W E E C L N _ D C T G R A i C t g r a EET OUAI_AEOI,OUADSRCOCTGRA RM AEACTGRA HR OUAI_AEOI=daeoi;

Para atualizar o contedo de uma linha na tabela TABELA_CATEGORIA utilizamos um ContentValues como parmetro para o mtodo update, bem como clusulas para o WHERE.
? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) JAVA

1 2 3 4 5 6 7 8}

aulzraeoi( taiaCtgra iCtgra S daeoi, ( Cnetausvle = otnVle aus Cnetaus) otnVle(; vle.u(OUADSRCOCTGRA dsrco; ausptCLN_ECIA_AEOI, ecia)

:/ /

? = &=

%A 3

&

II2 %0 =%7 2F

%0 2L

)dsrco ecia

mbudt(AEACTGRA vle,CLN_DCTGRA+"?, D.paeTBL_AEOI, aus OUAI_AEOI =" S ( :/ . / . / ? = &= %A 3

&

II2 %0 =%7 2F

%0 2L

)]{S [

:/ /

A leitura desse trecho fica assim: Atualize a linha idCategoria da coluna COLUNA_ID_CATEGORIA com os valores values na tabela TABELA_CATEGORIA . Parabns, se voc leu at aqui, voc j sabe como fazer operaes de CRUD (Create, Remove, Update e Delete) no SQLite do Android! Como este post esta MUITO grande, decidi dividi-lo em dois. No prximo mostro os mtodos de acesso a tabela TABELA_EMPRESTIMOS, bem como utilizar um Cursor em Spinners e ListViews. Para fechar esse post vou dar um exemplo simples de acesso a uma categoria atravs de um Cursor.

? (http://w w w .ericbess.com/ericblog/2008/03/03/w p-codebox/#examples)View Code (javascript:;) JAVA

1 2 3 4 5 6 7 8 9 1 0 1 1 1 2

EpetAAtvt mrsaiciiy Atvt { ciiy /*Cle we teatvt i frtcetd * * ald hn h cii s is rae. / @vrie Oerd oCet(udesvdntnett){ nraeBnl aeIsacSae .nraesvdntnett) oCet(aeIsacSae; stotnVe(.aotmi) eCnetiwRlyu.an; DAatrd = bdpe b DAatrgtplctoCnet); bdpe(eApiainotx() d.pn) boe(; L S C
( ( ( :/ / :/ / :/ / . . . . . . / / / ? = &= ? = &= ? = &= %A 3 %A 3 %A 3 + . + + . . . & . . II2 %0 =%7 2F & & II2 %0 =%7 2F II2 %0 =%7 2F %0 2L )iCtgra=1; daeoi L )dsrco="; ecia " )c=d.oslaCtgraiCtgra; bcnutraeoi(daeoi)

%0 2L %0 2L

1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 } 2

( ! c = }

) { dsrco=cgttigcgtounne(bdpe.OUADSRCOCTGRA) ecia .eSrn(.eClmIdxDAatrCLN_ECIA_AEOI);

d.ls(; bcoe) ccoe) .ls(; Lgw"mrsaiciiy,Msrnoctgra "dsrco; o.(EpetAAtvt""otad aeoi: +ecia) }

Em uma Activity, instnciamos um DbAdapter, damos um open nele (lembra do que acontece na primeira vez que fazemos isso?), executamos uma busca por um dado id de categoria, utilizamos o Cursor retornado para, dentro dele, recuperar o valor de uma coluna. O mtodo Cursor.getString recebe como parmetro um inteiro que representa o index de uma coluna, o mtodo Cursor.getColumnIndex nos retorna isso, mas pede como parmetro o nome da coluna, que exatamente o que est guardado em DbAdapter.COLUNA_DESCRICAO_CATEGORIA. Depois de executar a consulta e recuperar a String de descrico, fechamos o banco e o Cursor (sim, o cursor tambm tem que ser fechado.), por fim imprimimos no LogCat a descrio da categoria. Viu ai porque uma boa usar uma constante para os nomes das colunas?! Neste tutorial foram mostradas algumas tcnicas que ajudam na manuteno e acesso ao SQLite no Android, tambm foi mostrado um exemplo de como criar tabelas e executar mtodos CRUD sobre uma tabela. O projeto completo desse tutorial pode ser baixado aqui (http://www.androidbrasilprojetos.org/wp-content/uploads/2011/10/EmprestaAi1.zip). Como sempre,qualquer duvida, entre em contato pelos comentrios.

Celulares 4 Chips s R$99


Frete Gr tis, Desbloqueado com TV! Desconto de 10% no Boleto ou 15x
www.MpxShop.com/Promocao_4_Chips

Posted in Android (http://www.androidbrasilprojetos.org/category/android/), Tutoriais (http://www.androidbrasilprojetos.org/category/tutoriais/) Tags: autoincrement (http://www.androidbrasilprojetos.org/tag/autoincrement/), banco de dados (http://www.androidbrasilprojetos.org/tag/banco-de-dados/), chave extrangeira (http://www.androidbrasilprojetos.org/tag/chave-extrangeira/), close (http://www.androidbrasilprojetos.org/tag/close/), create table (http://www.androidbrasilprojetos.org/tag/create-table/), CRUD (http://www.androidbrasilprojetos.org/tag/crud/), Cursor (http://www.androidbrasilprojetos.org/tag/cursor/), exemplo (http://www.androidbrasilprojetos.org/tag/exemplo/), foreign key (http://www.androidbrasilprojetos.org/tag/foreign-key/), mDb (http://www.androidbrasilprojetos.org/tag/mdb/), mDbHelper (http://www.androidbrasilprojetos.org/tag/mdbhelper/), open (http://www.androidbrasilprojetos.org/tag/open/), SELECT (http://www.androidbrasilprojetos.org/tag/select/), SQL (http://www.androidbrasilprojetos.org/tag/sql/), SQLite (http://www.androidbrasilprojetos.org/tag/sqlite/) Adicionando aes a itens de Custom Adapters (http://www.androidbrasilprojetos.org/android/adicionando-acoes-a-itens-de-custom-adapters/) AndEngine Usando Sprites (http://www.androidbrasilprojetos.org/android/andengine-usando-sprites/) You can leave a response (#respond), or trackback (http://www.androidbrasilprojetos.org/android/introducao-a-banco-de-dados-android/trackback/) from your own site.
Curtir (http://disqus.com/twitter28142653/)

e 4 others apoiaram isso.


(#)

Adicionar novo comentrio

Login (#)

Mostrando 3 comentrios
(http://disqus.com/guest/ef56634749201a8092292496d1e40e15/)

Ordenar por: populares

Leandro Ferreirapaz

Ol Jlio! Por que tem que fechar esses dois objetos?public void close() { mDbHelper.close(); mDb.close(); }Nos prximos ir mostrar como criar uma ListView com dados de uma tabela?Seria muito interessante.Obrigado.
4 meses atrs (#com m ent-352292494) 1 Curtir (#) Curtir (#) Responder (#)

(http://disqus.com/twitter-28142653/) Leonardo Sousa (http://twitter.com/sSousaLeo)

timo post, parabns, ajudou muito :-)


3 meses atrs (#com m ent-362550287) (http://disqus.com/google-b30a3b6e0abce5732f47848cd2e77259/) Curtir (#) Responder (#)

Levy Moreira

'... e vai perder horas da sua vida debugando cdigo at ver que trocou uma letra em um nome de coluna em algum lugar.' rsrsrsrs Muito bom
4 meses atrs (#com m ent-356626669) Curtir (#) Responder (#)

M Notificar por e-mail (#)

RSS (http://androidbrasilprojetos.disqus.com/introducao_a_banco_de_dados_android/latest.rss)

Trackbacks
URL de Trackback http://www.androidbrasilprojetos.org/android/introducao-a-banco-de-dados-android/trackback/ Introduo a banco de dados Android [Parte 2] 11/08/2011 03:17 AM [...] No primeiro post, desta serie, mostrei duas tabelas, a tabela Categoria e a Emprstimos, sendo que implementei [...] Android Brasil Projetos (http://www.androidbrasilprojetos.org/android/introducao-a-banco-de-dados-android-parte-2/)

Topicos recentes (#tab1) Tags (#tab2) Comentarios (#tab3) Agenda (#tab4)

Posts Recentes
3090 (http://www.androidbrasilprojetos.org/android/3090/) Introduo a banco de dados Android [Parte 5] (http://www.androidbrasilprojetos.org/android/introducao-a-banco-de-dados-android-parte-5/) Splash Screen com animaes (http://www.androidbrasilprojetos.org/android/splash-screen-com-animacoes/) Introduo a banco de dados Android [Parte 4] (http://www.androidbrasilprojetos.org/android/introducao-a-banco-de-dados-android-parte-4/) Criando uma notificao com Android (http://www.androidbrasilprojetos.org/android/criando-uma-notificacao-com-android-2/)

Copyright And oid B a il P oje o (http://www.androidbrasilprojetos.org) Powered by Wo dP e (http://wordpress.org/) | Best Verizon Wireless Black Friday (http://www.ifreecellphones.com/verizon-wireless-black-friday-sales-deals-ads.asp) Sale | Thanks to PalmPreBlog.com (http://palmpreblog.com/), Game Soundtracks (http://rpgmusic.org/) and Debt Advice (http://www.debtclear.net) Podcast powered by podPress v8.8.10.13 (http://wordpress.org/extend/plugins/podpress/)

You might also like