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

【Android数据存储】- SQLite Database

2014-03-03 20:14 267 查看
个人学习整理,如有不足之处,请不吝指教。转载请注明:@CSU-Max

SQLite Database 简介:

        SQLite,是一款轻量级的关系型数据库。由于它占用的资源非常少,所以在很多嵌入式设备都是用SQLite来存储数据。并且它目前支持Windows/Linux/Unix等等主流的操作系统,兼容性还不错。我们也可以用多种开发语言如C#、Java、PHP等来通过ODBC接口操作SQLite,十分方便。
        由于 SQLite 数据库占用资源小,使用简单,故在 Android 上存储数据,使用 SQLite 是一种很好的选择。
 

SQLite 支持的常用的 SQL 语句:

 
创建表:
create table if not exists user(_id integer primary key autoincrement, name text)
删除表:
drop table if exists user
查询数据:
select * from user;
select * from user where _id = 2;
select name from user group by city having count(*) > 1
分页查询:
    跳过前面的15跳记录,查询接下来的5跳记录:
select * from user limit 15,5;

select * from user limit 5 offset 15;
插入数据:
insert into user(name) values ('CSUMax');
删除数据:
delete from user where _id = 2;
更新数据:
update user set name = 'Cindy' where _id = 3;

 

基本数据库操作:

    1、操作 SQLite 的一般步骤:

       (1)  获取 SQLiteDatabase 对象,相当于获取数据库连接;
              在 Android 中进行数据库操作时,首先使用我们自定义的 SQLiteOpenHelper 的子类(如下例中的 DBOpenHelper)的getReadableDatabase() 或getWritableDatabase()
获取只读或可写的数据库对象 SQLiteDatabase(如数据库不存在则创建数据库)。
       (2)  调用 SQLiteDatabase 的方法来执行SQL语句;
              SQLiteDatabase 中封装了一系列增删改查的方法,当然,也可以使用 execSQL 方法执行 SQL 语句。
       (3)  操作 SQL 语句执行的结果;
               对于查询结果,我们可以使用 HashMap ,也可以使用 Andorid 为我们提供的 ContentValues 来保存。当使用ListView 等空间来显示多条记录的时候,可以使用我们常用的 List(使用SampleAdapter适配器),也可以直接返回 Cursor(使用 SampleAdapter 适配器)。
       (4)  关闭 SQLiteDatabase 。
               完成数据库相关操作之后,要及时释放资源。

     2、使用 SQLite 进行简单的增删改查操作:

       (1)  查询数据

       db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy)
           各参数含义:
                table :    要查询表的表名;
                columns :    查询的列数组
                selection :    查询条件,中间可以含 “?”;
                selectionArgs :    表示查询条件中参数的数组;
                groupBy :    分组,对应SQL中的  group by ;
                having :    对应SQL中的 having 语句;
                orderBy :    对应SQL中的 order by 语句 ;

           查询所有数据:

           主要代码:

/**
* 查询所有的记录
* @return
*/
public List<User> queryAll() {
List<User> list = new ArrayList<User>();
SQLiteDatabase db = null;
Cursor cursor = null;

try {
//获取只读数据库实例
db = dbOpenHelper.getReadableDatabase();
cursor = db.query("user", null, null, null, null, null, "_id desc");
//遍历 Cursor
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor
.moveToNext()) {
User user = new User();
user.setId(cursor.getInt(cursor.getColumnIndex("_id")));
user.setName(cursor.getString(cursor.getColumnIndex("name")));
list.add(user);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
if (db != null) {
db.close();
}
}
return list;
}


     根据 id 查询一条数据:

               主要代码:
/**
* 根据 id 查询记录
* @param id
* @return
*/
public User queryUserById(int id) {
User user = new User();
SQLiteDatabase db = null;
Cursor cursor = null;

try {
//获取只读数据库
db = dbOpenHelper.getReadableDatabase();
cursor = db.query("user", null, "_id = ?",
new String[] { String.valueOf(id) }, null, null, null);
if (cursor.moveToFirst()) {
user.setId(cursor.getInt(cursor.getColumnIndex("_id")));
user.setName(cursor.getString(cursor.getColumnIndex("name")));
}

} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
if (db != null) {
db.close();
}
}
return user;
}


     模糊查询:

        主要代码:

/**
* 根据某一字段的部分值进行模糊查询
*
* @param word
* @return
*/
public List<User> queryByWord(String word) {
List<User> list = new ArrayList<User>();
SQLiteDatabase db = null;
Cursor cursor = null;

try {
// 获取只读数据库
db = dbOpenHelper.getReadableDatabase();
cursor = db.query("user", null, "name like ?", new String[] { word
+ "%" }, null, null, null);
// 遍历 Cursor
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor
.moveToNext()) {
User user = new User();
user.setId(cursor.getInt(cursor.getColumnIndex("_id")));
user.setName(cursor.getString(cursor.getColumnIndex("name")));
list.add(user);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
if (db != null) {
db.close();
}
}
return list;
}


(2)  插入数据

           db.insert(table, nullColumnHack, values)
     各参数含义:
                  table :    要插入数据的表名;
                  nullColumnHack :   表示当 ContentValues 为空时,那一列赋 null 值;
                  values :   表示要插入的列和值。
         返回插入成功的行数。
             主要代码:

   
/**
* 向 user 表中 插入一个 user,将 user 的 name 属性插入到 user 表中的 name 列
* @param user
* @return
*/
public long insert(User user) {
SQLiteDatabase db = null;
long id = -1;
try {
db = dbOpenHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", user.getName());
id = db.insert("user", null, values);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (db != null) {
db.close();
}
}
return id;
}


 

     (3)  删除数据

      db.delete(table, whereClause, whereArgs)          
           各参数含义:
                table :    要删除数据的表名;
                whereClause :    删除条件,即普通 SQL 语句 where 后面的部分,可以带 “?”;
                whereArgs:     参数值数组。
           主要代码:

 
/**
* 删除指定 id 的数据
* @param id
*/
public void delete(int id) {
SQLiteDatabase db = null;
try {
db = dbOpenHelper.getWritableDatabase();
db.delete("user", "_id = ?", new String[] { String.valueOf(id) });
} catch (Exception e) {
e.printStackTrace();
} finally {
if (db != null) {
db.close();
}
}
}


      (4)  更新数据

       db.update(table, values, whereClause, whereArgs)         
           各参数含义:
                table :    要更新数据的表名;
                values :  修改的列名和修改后的值;
                whereClause :   修改条件,即普通 SQL 语句 where 后面的部分,可以带 “?”;
                whereArgs:     参数值数组。
       返回更新成功的行数。
           主要代码:

 
/**
* 更新数据操作
* @param user
* @return
*/
public long update(User user) {
SQLiteDatabase db = null;
long id = -1;
try {
db = dbOpenHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", user.getName());
id = db.update("user", values, "_id = ?",
new String[] { String.valueOf(user.getId()) });
} catch (Exception e) {
e.printStackTrace();
} finally {
if (db != null) {
db.close();
}
}
return id;
}


   2、使用 SQLite 进行数据分页:

      (1)  创建一个分页的类 Page类

public class Page {
// 每页显示的记录数
private int pageSize = 3;
// 当前打的页数
private int pageNum = 1;
// 总的记录数
private int totalCount = 0;
// 总的页数
private int totalNum = 0;
/**
* 是否有下一页
* @return
*/
public boolean isHasNext() {
if (pageNum < totalNum) {
return true;
} else {
return false;
}
}
/**
* s是否有上一页
* @return
*/
public boolean isHasPre() {
if (pageNum > 1) {
return true;
} else {
return false;
}
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getTotalNum() {
return totalNum;
}
public void setTotalNum(int totalNum) {
this.totalNum = totalNum;
}
}


(2)  获取某一页的数据

/**
* 获取某一页的数据
*
* @param pageSize
*            每页显示记录数
* @param pageNum
*            当前的页码
* @return
*/
public List<User> getPageUser(int pageSize, int pageNum) {
List<User> list = new ArrayList<User>();
SQLiteDatabase db = null;
Cursor cursor = null;
try {
// 获取只读数据库实例
db = dbOpenHelper.getReadableDatabase();
// 使用 limit ? offset ? 来进行分页
cursor = db.query("user", null, null, null, null, null,
"_id asc limit " + String.valueOf(pageSize) + " offset "
+ String.valueOf((pageNum - 1) * pageSize));
// 遍历 Cursor
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor
.moveToNext()) {
User user = new User();
user.setId(cursor.getInt(cursor.getColumnIndex("_id")));
user.setName(cursor.getString(cursor.getColumnIndex("name")));
list.add(user);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
if (db != null) {
db.close();
}
}
return list;
}


  通过以上的代码,我们就完成了初步的分页操作,下面我们对此进行完善一下,获得总页数,增加上一页和下一页功能。

     (3)  获取总页数

               先获取总的记录数,在根据 pageSize 来计算得出总页数:

/**
* 获取表中总的记录数
*
* @return
*/
public int getTotalCount() {
SQLiteDatabase db = null;
Cursor cursor = null;
int totalCount = 0;
try {
// 获取只读数据库实例
db = dbOpenHelper.getReadableDatabase();
cursor = db.query("user", null, null, null, null, null, null);
// 获取记录数
totalCount = cursor.getCount();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
if (db != null) {
db.close();
}
}
return totalCount;
}
/**
* 得到中的页数
*
* @param pageSize
* @return
*/
public int getTotalNum(int pageSize) {
int totalNum = 0;
totalNum = getTotalCount() / pageSize + 1;
return totalNum;
}


(4)  上下翻页功能

/**
* 显示下一页的数据
*
* @param pageSize
*            每页显示记录数
* @param pageNum
*            当前的页码
* @return
*/
public List<User> getNextPage(int pageSize, int pageNum) {
List<User> list = new ArrayList<User>();
//设置Page对象的属性
Page page = new Page();
page.setPageSize(pageSize);
page.setPageNum(pageNum);
page.setTotalCount(getTotalCount());
page.setTotalNum(getTotalNum(pageSize));
// 判断是否有下一页,有下一页则显示下一页的数据
if (page.isHasNext()) {
list = getPageUser(pageSize, pageNum + 1);
}
return list;
}
/**
* 显示上一页的数据
*
* @param pageSize
*            每页显示记录数
* @param pageNum
*            当前的页码
* @return
*/
public List<User> getPrePage(int pageSize, int pageNum) {
List<User> list = new ArrayList<User>();
Page page = new Page();
page.setPageSize(pageSize);
page.setPageNum(pageNum);
page.setTotalCount(getTotalCount());
// 判断是否有上一页,有上一页则显示上一页的数据
if (page.isHasNext()) {
list = getPageUser(pageSize, pageNum - 1);
}
return list;
}


SQLite中的事务管理:

 

           SQLite 中同样支持事务。 当我们要向数据库中插入很多的数据时,若使用 for 遍历 insert 插入的话,会很消耗资源,影响效率,也不能保证插入的稳定性。因为 SQLite插入数据的时候,默认一条插入语句就是一个事务,这样在进行多条数据插入的时候就会进行多次的磁盘操作,而且不能保证所有的数据都插入正确,这时候使用事务就很方便了。

 

     1、SQLite中事务操作的常用方法:

 
     beginTransaction() : 开启事务;
     endTransaction() : 关闭事务;
     setTransactionSuccessful() : 设置事务标志位的为成功,当标志位为成功时,endTransaction()就会提交事务, 否则 endTransaction() 会回滚事务。

 

   2、SQLite中事务操作的实例代码:

public long insert() {
SQLiteDatabase db = null;
long id = 0;
try {
db = dbOpenHelper.getWritableDatabase();
// 开启事务
db.beginTransaction();
ContentValues values = new ContentValues();
for (int i = 0; i < 5; i++) {
values.put("name", "姓名" + 1);
id = db.insert("user", null, values) + id;
}
// 设置事务标志位为成功
db.setTransactionSuccessful();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (db != null) {
// 结束事务,根据标志位来决定是提交还是回滚
db.endTransaction();
db.close();
}
}
return id;
}


 关于  SQLite的简单使用方法就介绍到这里,下一节将总结 Android 中的文件存储数据。

个人学习整理,如有不足之处,请不吝指教。转载请注明:@CSU-Max
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: