您的位置:首页 > 移动开发 > Android开发

类数据[Android Training视频系列] 6.3 Saving Data in SQL Databases(保存数据到SQLite)

2013-05-06 20:09 591 查看
今天朋友几篇文章介绍了改类数据的文章. 关联文章的地址

一 主要内容

1.概述
2.义定Schema与Contract
3.用使SQL Helper创立数据库
4.向数据库添加信息
5.从数据库中读取信息
6.删除数据库中的信息
7.更新数据库中的信息

二 翻译载转

对于复重或者结构化的数据(如联系人信息)等保存到DB是个不错的主张。这节课假设你已悉熟SQL数据库的作操。在Android上可能会用使到的APIs,可以从android.database.sqlite包中找到。

Define a Schema and Contract [义定Schema与Contract]

SQL中一其中要重的念概是schema:一种DB结构的正式声明。schema是从你创立DB的SQL语句中生成的。你可能会现发创立一个创立一个随同类(companion class)是很益有的,这个类成为合约类(contract class),它用一种系统化并且动自生成档文的方法,示显指定了你的schema款式。

Contract Clsss是一些常量的器容。它义定了例如URIs, 表名,列名等。这个contract类答应你在同一个包下与其他类用使一样的常量。 它让你只须要在一个地方修改列名,然后这个列名以可就动自传递给你个整code。

一个织组你的contract类的好方法是在你的类的根层级义定一些全局变量,然后为每个table来创立内部类。

Note: 通过现实
BaseColumns
的口接,你的内部类可以继承到一个名为_ID的主键,这个对于Android面里的一些相似cursor adaptor类是很有要必的。这样够能使得你的DB与Android的framework够能很好的相容。

例如,上面的例子义定了表名与这个表的列名:

public


static

abstract

class

FeedEntry

implements

BaseColumns

{

public

static

final

String

TABLE_NAME

=

"entry"

;

public

static

final

String

COLUMN_NAME_ENTRY_ID

=

"entryid"

;

public

static

final

String

COLUMN_NAME_TITLE

=

"title"

;

public

static

final

String

COLUMN_NAME_SUBTITLE

=

"subtitle"

;

...

}

为了止防一些人不小心实例化contract类,像上面一样给一个空的构造器。

// Prevents the FeedReaderContract class from being instantiated.


private

FeedReaderContract

()

{}

Create a Database Using a SQL Helper [用使SQL Helper创立DB]

当你义定好了你的DB应当是什么样以后,你应当现实那些创立与维护db与table的方法。上面是一些典范的创立与删除table的语句。

private


static

final

String

TEXT_TYPE

=

" TEXT"

;

private

static

final

String

COMMA_SEP

=

","

;

private

static

final

String

SQL_CREATE_ENTRIES

=

"CREATE TABLE "

+

FeedReaderContract

.

FeedEntry

.

TABLE_NAME

+

" ("

+

FeedReaderContract

.

FeedEntry

.

_ID

+

" INTEGER PRIMARY KEY,"

+

FeedReaderContract

.

FeedEntry

.

COLUMN_NAME_ENTRY_ID

+

TEXT_TYPE

+

COMMA_SEP

+

FeedReaderContract

.

FeedEntry

.

COLUMN_NAME_TITLE

+

TEXT_TYPE

+

COMMA_SEP

+

...

// Any other options for the CREATE command

" )"

;

private

static

final

String

SQL_DELETE_ENTRIES

=

"DROP TABLE IF EXISTS "

+

TABLE_NAME_ENTRIES

;

就像保存文件到备设的 internal storage 一样,Android会保存db到你的程序的private的空间上。你的数据是受护保的,因为那些区域默许是私有的,不可被其他程序所拜访。

SQLiteOpenHelper
类中有一些很用有的APIs。当你用使这个类来做一些与你的db有关的作操时,系统会对那些有可能比拟耗时的作操(例如创立与更新等)在真正须要的时候才去行执,而不是在app刚启动的时候就去做那些动作。你所须要做的仅仅是行执
getWritableDatabase()
或者
getReadableDatabase()
.

Note: 因为那些作操是能可很耗时的,请确保你在background thread(
AsyncTask
or
IntentService
)面里去行执
getWritableDatabase()
或者
getReadableDatabase()


为了用使
SQLiteOpenHelper
, 你须要创立一个子类并写重
onCreate()
,
onUpgrade()
onOpen()
等callback方法。你许也还须要现实
onDowngrade()
, 但是这并非必须的。

例如,上面是一个现实了
SQLiteOpenHelper
类的例子:

public


class

FeedReaderDbHelper

extends

SQLiteOpenHelper

{

// If you change the database schema, you must increment the database version.

public

static

final

int

DATABASE_VERSION

=

1

;

public

static

final

String

DATABASE_NAME

=

"FeedReader.db"

;

public

FeedReaderDbHelper

(

Context

context

)

{

super

(

context

,

DATABASE_NAME

,

null

,

DATABASE_VERSION

);

}

public

void

onCreate

(

SQLiteDatabase

db

)

{

db

.

execSQL

(

SQL_CREATE_ENTRIES

);

}

public

void

onUpgrade

(

SQLiteDatabase

db

,

int

oldVersion

,

int

newVersion

)

{

// This database is only a cache for online data, so its upgrade policy is

// to simply to discard the data and start over

db

.

execSQL

(

SQL_DELETE_ENTRIES

);

onCreate

(

db

);

}

public

void

onDowngrade

(

SQLiteDatabase

db

,

int

oldVersion

,

int

newVersion

)

{

onUpgrade

(

db

,

oldVersion

,

newVersion

);

}

}

为了拜访你的db,须要实例化你的
SQLiteOpenHelper
的子类:

每日一道理

共和国迎来了她五十诞辰。五十年像一条长河,有急流也有缓流;五十年像一幅长卷,有冷色也有暖色;五十年像一首乐曲,有低音也有高音;五十年像一部史诗,有痛苦也有欢乐。长河永远奔流,画卷刚刚展开,乐曲渐趋高潮,史诗还在续写。我们的共和国正迈着坚定的步伐,跨入新时代。

FeedReaderDbHelper

mDbHelper

=

new

FeedReaderDbHelper

(

getContext

());

Put Information into a Database [添加信息到DB]

通过传递一个
ContentValues
对象到
insert()
方法:

// Gets the data repository in write mode


SQLiteDatabase

db

=

mDbHelper

.

getWritableDatabase

();

// Create a new map of values, where column names are the keys

ContentValues

values

=

new

ContentValues

();

values

.

put

(

FeedReaderContract

.

FeedEntry

.

COLUMN_NAME_ENTRY_ID

,

id

);

values

.

put

(

FeedReaderContract

.

FeedEntry

.

COLUMN_NAME_TITLE

,

title

);

values

.

put

(

FeedReaderContract

.

FeedEntry

.

COLUMN_NAME_CONTENT

,

content

);

// Insert the new row, returning the primary key value of the new row

long

newRowId

;

newRowId

=

db

.

insert

(

FeedReaderContract

.

FeedEntry

.

TABLE_NAME

,

FeedReaderContract

.

FeedEntry

.

COLUMN_NAME_NULLABLE

,

values

);

insert()
方法的第一个参数是table名,第二个参数会使得系统动自对那些
ContentValues
没有供给数据的列填充数据为null,如果第二个参数传递的是null,那么系统则不会对那些没有供给数据的列停止填充。

Read Information from a Database [从DB中读取信息]

为了从DB中读取数据,须要用使
, java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String)]query()
方法, 传递你须要询查的件条。询查后会返回一个
Cursor
对象。

SQLiteDatabase

db

=

mDbHelper

.

getReadableDatabase

();

// Define a

projection

that specifies which columns from the database

// you will actually use after this query.

String

[]

projection

=

{

FeedReaderContract

.

FeedEntry

.

_ID

,

FeedReaderContract

.

FeedEntry

.

COLUMN_NAME_TITLE

,

FeedReaderContract

.

FeedEntry

.

COLUMN_NAME_UPDATED

,

...

};

// How you want the results sorted in the resulting Cursor

String

sortOrder

=

FeedReaderContract

.

FeedEntry

.

COLUMN_NAME_UPDATED

+

" DESC"

;

Cursor

c

=

db

.

query

(

FeedReaderContract

.

FeedEntry

.

TABLE_NAME

,

// The table to query

projection

,

// The columns to return

selection

,

// The columns for the WHERE clause

selectionArgs

,

// The values for the WHERE clause

null

,

// don't group the rows

null

,

// don't filter by row groups

sortOrder

// The sort order

);

上面是演示如何从course对象中读取数据信息:

cursor

.

moveToFirst

();

long

itemId

=

cursor

.

getLong

(

cursor

.

getColumnIndexOrThrow

(

FeedReaderContract

.

FeedEntry

.

_ID

)

);

Delete Information from a Database [删除DB中的信息]

和询查信息一样,删除数据,一样须要供给一些删除准标。DB的API供给了一个止防SQL入注的制机来创立询查与删除准标。

SQL Injection[随着B/S式模应用开发的开展,用使这类式模编写应用程序的程序员也越来越多。但是由于程序员的水平及验经也齐不差参,相当大一分部程序员在编写代码的时候,没有对户用入输数据的合法性停止判断,使应用程序存在安全隐患。户用可以提交一段数据库询查代码,根据程序返回的结果,取得某些他想知得的数据,这就是所谓的SQL Injection,即SQL入注。]

这个制机把询查语句划分为选项款条与选项参数两分部。款条分部义定了询查的列是怎么样的,参数分部用来测试是不是符合面前的款条。[这里翻译的怪怪的,附上原文,The clause defines the columns to look at, and also allows you to combine column tests. The arguments are values to test against that are bound into the clause.] 因为理处的结果与常通的SQL语句不同,这样可以防止SQL入注题问。

/ Define 'where' part of query.


String

selection

=

FeedReaderContract

.

FeedEntry

.

COLUMN_NAME_ENTRY_ID

+

" LIKE ?"

;

// Specify arguments in placeholder order.

String

[]

selelectionArgs

=

{

String

.

valueOf

(

rowId

)

};

// Issue SQL statement.

db

.

delete

(

table_name

,

mySelection

,

selectionArgs

);

Update a Database [更新数据]

当你须要修改DB中的某些数据时,用使
)]update()
方法。

更新作操结合了插入与删除的语法。

SQLiteDatabase

db

=

mDbHelper

.

getReadableDatabase

();

// New value for one column

ContentValues

values

=

new

ContentValues

();

values

.

put

(

FeedReaderContract

.

FeedEntry

.

COLUMN_NAME_TITLE

,

title

);

// Which row to update, based on the ID

String

selection

=

FeedReaderContract

.

FeedEntry

.

COLUMN_NAME_ENTRY_ID

+

" LIKE ?"

;

String

[]

selelectionArgs

=

{

String

.

valueOf

(

rowId

)

};

int

count

=

db

.

update

(

FeedReaderDbHelper

.

FeedEntry

.

TABLE_NAME

,

values

,

selection

,

selectionArgs

);

三 视频解讲

http://www.eyeandroid.com/thread-14567-1-1.html




文章结束给大家分享下程序员的一些笑话语录:

古鸽是一种搜索隐禽,在中国快绝迹了…初步的研究表明,古鸽的离去,很可能导致另一种长着熊爪,酷似古鸽,却又习性不同的猛禽类——犤毒鸟
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: