Android数据存储之SQLite数据库存储

总结SQLite花了好多时间,参考了不少资料。以下知识如果觉得眼熟,不要怀疑,这些总结中的代码,虽然很多不是我自己写的,但是这些代码都是通用的。SQLite存储并不难,就是麻烦而已,希望下面的总结能够对你们有帮助。

Android中每一个数据库对创建它的应用程序包套件来说都是私有的,默认情况下其他应用程序无法直接访问此私有数据库。所有的数据库文件存放在手机中的/data/data/package_name/databases路径下,以下是常用的与数据库相关的函数:

返回值

函数

备注

static SQLiteDatabase

create(SQLiteDatabase.CursorFactory factory)

创建一个数据库

factory:可选的数据库游标工厂类,当查询(query)被提交时,该对象会被调用来实例化一个游标。

static SQLiteDatabase

openDatabase(String path,SQLiteDatabase.CursorFactory factory,int flags)

根据提供的模式打开一个数据库

path:打开或创建的数据库文件

factory:可选的数据库游标工厂类,当查询(query)被提交时,该对象会被调用来实例化一个游标。默认为null。

flags:控制数据库的访问模式。主要有以下几种模式:

l OPEN_READWRITE

l OPEN_READONLY

l CREATE_IF_NECESSARY

l NO_LOCALIZED_COLLATORS

static SQLiteDatabase

openOrCreateDatabase(File file, SQLiteDatabase.CursorFactory factory)

等同于openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY)

static SQLiteDatabase

openOrCreateDatabase(String path, SQLiteDatabase.CursorFactory factory)

等同于openDatabase(path,factory, CREATE_IF_NECESSARY)

void

close()

关闭数据库

boolean

deleteDatabase(String name)

删除指定的数据库

name:要关闭的数据库的名字

示例代码如下:

//创建数据库

SQLiteDatabase mydataBase=SQLiteDatabase.create(new CursorFactory(){

//工厂类,一个可选工厂类,当查询时调用来实例化一个游标

@Override

public Cursor newCursor(SQLiteDatabase db,

SQLiteCursorDriver masterQuery, String editTable,

SQLiteQuery query) {

// TODO Auto-generated method stub

return null;

}

});

//创建或打开数据库

SQLiteDatabase myDataBase=this.openOrCreateDatabase("myDataBase.db",

MODE_PRIVATE, new CursorFactory(){

//创建新的数据库,名称myDatabase,模式MODE_PRIVATE,可选的游标工厂类

@Override

public Cursor newCursor(SQLiteDatabase db,

SQLiteCursorDriver masterQuery, String editTable,

SQLiteQuery query) {

// TODO Auto-generated method stub

return null;

}

});

SQLiteDatabase myDataBase=this.openOrCreateDatabase("myDataBase.db",MODE_PRIVATE,null);

//关闭数据库

myDataBase.close();

//删除指定名称的数据库

this.deleteDatabase(“myDatabase.db”);

在对数据库中的表进行相关操作时,可以使用非查询的execSQL(String sql)来执行。示例代码如下:

String CREATE_TABLE = “create table table1 (_id integer primary key autoincrement,number integer,data text)”; //创建表

myDataBase.execSQL(CREATE_TABLE);

Android提供了非SQL指令的对数据表进行操作的方法,以下表格是一些常用方法:

返回值

函数

备注

long

insert(String table, String nullColumnHack, ContentValues values)

向表中插入一条数据

table:想要插入数据的表名

nullColumnHack:SQL不允许插入空行,初始化值为空时,这一列将会被显示地赋一个null值

values:要插入的值,具体解释见表格后的解释

int

delete(String table, String whereClause, String[] whereArgs)

从表中删除一行数据

table:想要删除数据的表名

whereClause:可选的where子句,如果其值为null,将会删除所有的行。

whereArgs:当在whereClause中包含”?”时,如果whereArgs的值不为null,则这个数组中的值将依次替换whereClause中出现的”?”

Cursor

query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)

查询数据表

table:要查询数据的表名

columns:要返回的列的列名数组

selection:可选的where子句 ,如果其值为null,将会返回所有的行

selectionArgs:当在selection中包含”?”时,如果selectionArgs的值不为null,则这个数组中的值将依次替换selection中出现的”?”

groupBy:可选的group by子句,如果其值为null,将不会对行进行分组

having:可选的having子句,如果其值为null,将会包含所有的分组

orderBy:可选的order by子句,如果其值为null,将会使用默认的排序规则

limit:可选的limit子句,如果其值为null,将不会包含limit子句

关于返回值类型Cursor将在表格后面进行解释

int

update(String table, ContentValues values, String whereClause, String[] whereArgs)

修改表中的数据

table:想要修改数据的表名

values:要更新的值,具体解释见表格后的解释

whereClause:可选的where子句,如果其值为null,将会修改所有的行。

whereArgs:当在whereClause中包含”?”时,如果whereArgs的值不为null,则这个数组中的值将依次替换whereClause中出现的”?”

ContentValues主要是存放表中的数据段,以及其对应的值,与Hashtable一样采用名值对的形式存储,但是它存储的名值对中,名是一个String类型,值是基本数据类型。其使用示例如下:

ContentValues args = new ContentValues();

args.put(KEY_TITLE, title);

args.put(KEY_BODY, body);

myDataBase.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null);

Android采用游标对从数据库中查询出来的结果进行随机的读写访问,在查询数据库后,将结果返回给游标(即android.database.Cursor),这是查询结果的记录集,示意图如下:

 

_id

someNumber

clip_image002

1

8

 

2

10

 

3

2

Cursor类常见的方法如下:

返回值

函数

备注

boolean

move(int offset)

以当前位置为参考,将Cursor移动指定数目的位置(相对位置)

boolean

moveToPosition(int position)

将Cursor移动到指定位置(绝对位置)

boolean

moveToNext()

将Cursor向前移动一个位置

boolean

moveToLast()

将Cursor向后移动一个位置

boolean

moveToFirst()

将Cursor移动到第一行

boolean

isBeforeFirst()

返回Cursor是否指向第一项数据之前

boolean

isAfterLast()

返回Cursor是否指向最后一项数据之后

boolean

isClosed()

返回Cursor是否关闭

boolean

isFirst()

返回Cursor是否指向第一项数据

boolean

isLast()

返回Cursor是否指向最后一项数据

boolean

isNull(int columnIndex)

返回指定位置的值是否为null

int

getCount()

返回总的项目总数

int

getInt(int columnIndex)

返回指定列中的数据的int型表示

int

getColumnIndex(String columnName)

按给定的列的名字返回列的索引值,如果不存在则返回 -1

要创建一个Cursor(游标),必须执行一个查询,通过SQL使用rawQuery()方法或是更精心的query()方法,而不能使用execSQL(String sql)方法。以下为Cursor的使用示例:

Cursor cur=myDataBase.rawQuery("select * from test", null);

if(cur!=null){//游标不为空

//返回给定名称的列的基于0开始的index,如果该属性列不存在则返回-1

//通过它们的index来检索属性值

int numColumn=cur.getColumnIndex("someNumber");

if(cur.moveToFirst()){ //cur.moveToFirst()让游标指向第一行,如果游标指向第一行,则返回true

do {

int num=cur.getInt(numColumn);//获得当前行该属性的值

/*Cursor提供了不同的方法来回索不同的数据类型,例如getInt(int index)/getString(int index)等等*/

/*做一些事情*/

} while (cur.moveToNext());

/*游标移动到下一行,如果游标已经到达结果集中的最后,即没有行可以移动时,则返回false*/

//其他可能移动的是 moveToPrevious() 和moveToFirst()方法

}

}

在实际使用的时候,通常都要封装一个继承SQLiteOpenHelper类的数据库操作类。SQLiteOpenHelper类是一个抽象的辅助类,主要用来生成一个数据库并对数据库的版本进行管理,在SQLiteOpenHelper类的构造方法中分别传入Context、数据库名称,CursorFactory(一般传入null,否则为默认数据库),数据库版本号(不能为负数)。在SQLiteOpenHelper中首先执行的是onCreate方法(当数据库第一次创建时),一般在这个方法里生成数据表。要注意的是,在构造函数时并没有真正创建数据库,而是在调用getWriteableDatabase()或者getReadableDatabase()方法的时候系统才会真正创建数据库,如果当时系统中不存在这个数据库,系统会自动生成一个数据库,然后返回SQLiteDatabase对象。在继承这个类的时候,要实现里面的3个方法,其中前两个方法是必须重写的。见如下表格:

返回值

函数

备注

public void

onCreate(SQLiteDatabase db)

在数据库第一次生成时会调用这个方法,一般我们在这个方法里生成数据表

public void

onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion)

当数据库需要升级时,系统会自动调用这个方法,一般我们在这个方法里删除数据表,并建立新的数据表,并根据实际需求做其他的操作

public void

onOpen(SQLiteDatabase db)

这是打开数据库时的回调函数,一般不会用到

以下示例代码详细给出一封装好的数据库操作类:

public class MyDbHelper {
    public static final String KEY_TITLE = "title";    //数据表字段
    public static final String KEY_BODY = "body";    //数据表字段
    public static final String KEY_ROWID = "_id";    //数据表字段
 
    private DatabaseHelper mDbHelper;    //SQLiteOpenHelper实例对象
    private SQLiteDatabase mDb;    //数据库实例对象
    
    //数据表创建语句
    private static final String DATABASE_CREATE  = "create table notes (_id integer primary key autoincrement, "
                    + "title text not null, body text not null);";
 
    private static final String DATABASE_NAME = "data";    //数据库名
    private static final String DATABASE_TABLE = "notes";    //数据库表名
    private static final int DATABASE_VERSION = 2;    //数据库版本号
 
    private final Context mCtx;    //上下文实例
 
    private static class DatabaseHelper extends SQLiteOpenHelper {    //数据库辅助类
        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(DATABASE_CREATE);
        }
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS notes");
            onCreate(db);
        }
    }
 
    /**
     * Constructor - takes the context to allow the database to be opened/created
     * 
     * @param ctx the Context within which to work
     */
    public MyDbHelper(Context ctx) {
        this.mCtx = ctx;
    }
 
    /**
     * Open the notes database. If it cannot be opened, try to create a new instance of the database. 
* If it cannot be created, throw an exception to signal the failure
     * 
     * @return this (self reference, allowing this to be chained in an initialization call)
     * @throws SQLException if the database could be neither opened or created
     */
    public MyDbHelper open() throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }
    
    public void close() {
        mDbHelper.close();
    }
 
 
    /**
     * Create a new note using the title and body provided. If the note is successfully created 
* return the new rowId for that note, otherwise return a -1 to indicate failure.
     * 
     * @param title the title of the note
     * @param body the body of the note
     * @return rowId or -1 if failed
     */
    public long createNote(String title, String body) {
        ContentValues initialValues = new ContentValues();
        initialValues.put(KEY_TITLE, title);
        initialValues.put(KEY_BODY, body);
        return mDb.insert(DATABASE_TABLE, null, initialValues);
    }
 
    /**
     * Delete the note with the given rowId
     * 
     * @param rowId id of note to delete
     * @return true if deleted, false otherwise
     */
    public boolean deleteNote(long rowId) {
        return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
    }
 
    /**
     * Return a Cursor over the list of all notes in the database
     * 
     * @return Cursor over all notes
     */
    public Cursor fetchAllNotes() {
        return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_TITLE,KEY_BODY}, null, null, null, null, null);
    }
 
    /**
     * Return a Cursor positioned at the note that matches the given rowId
     * 
     * @param rowId id of note to retrieve
     * @return Cursor positioned to matching note, if found
     * @throws SQLException if note could not be found/retrieved
     */
    public Cursor fetchNote(long rowId) throws SQLException {
 
        Cursor mCursor = mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,KEY_TITLE, 
KEY_BODY}, KEY_ROWID + "=" + rowId, null, null, null, null, null);
        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;
    }
 
    /**
     * Update the note using the details provided. The note to be updated is specified using the rowId, 
*and it is altered to use the title and body values passed in
     * 
     * @param rowId id of note to update
     * @param title value to set note title to
     * @param body value to set note body to
     * @return true if the note was successfully updated, false otherwise
     */
    public boolean updateNote(long rowId, String title, String body) {
        ContentValues args = new ContentValues();
        args.put(KEY_TITLE, title);
        args.put(KEY_BODY, body);
        return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
    }
}
posted @ 2010-04-15 15:13  陆止于此 海始于斯  阅读(9177)  评论(3编辑  收藏  举报