Android开发系列之SQLite

卧疾丰暇豫,翰墨时间作。这篇文章主要讲述Android开发系列之SQLite相关的知识,希望能为你提供帮助。
上篇博客提到过SQLite。它是嵌入式数据库,因为其轻巧但功能强大,被广泛的用于嵌入式设备其中。后来在智能手机、平板流行之后,它作为文件型数据库,差点儿成为了智能设备单机数据库的必选,能够随着安卓app打包到apk文件其中。

SQLite的官方站点是http://www.sqlite.org/,能够随意下载,上面也有详尽的文档能够參考,这篇博客重点关注SQLite在android开发中怎样使用。
在Android开发中。推荐建立一个类继承自SQLiteOpenHelper来创建数据库操作类,比方:

public class DBHelper extends SQLiteOpenHelper { private static final String database = "test.db"; private static final Integer version = 1; public DBHelper(Context context) {// 构造函数初始化各成员变量 super(context, database, null, version); } @Override public void onCreate(SQLiteDatabase db) {// 当通过SQLiteOpenHelper的子类获取数据库连接时。假设数据库不存在。则调用onCreate方法来创建数据库 String sql = "create table Score(id integer primary key autoincrement,name varchar(20),point integer)"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 当传入的实例的数据库版本号号高于之前的版本号号时,系统会自己主动调用onUpgrade方法更新数据库 // 更新数据库的操作:备份数据库表数据,又一次创建或改动表、约束等。然后将原来的数据导入到新建的表中。 } }

上面的代码有3点须要注意:
1、构造函数(方法)中指定了数据库的名称和版本号号
它会默认的在data/data/包名/databases/文件夹下创建这个数据库。当然你也能够指定数据库文件存在的路径。版本号号设置为1。假设你要想升级,能够在构造方法的參数中加上version,以便初始化。
Android开发系列之SQLite

2、onCreate是在数据库文件没有创建的时候运行,假设有了的话则不运行
3、onUpgrade是在新的指定版本号号高于旧的指定版本号号的时候运行,一般在数据库升级的时候须要操作
然后我们建一个详细的数据库操作类:

/** * 成绩操作类 * * @author guwei * */ public class ScoreOp { // 插入一条成绩记录 public long insert(SQLiteDatabase db, String name, Integer point) { try { db.beginTransaction(); ContentValues values = new ContentValues(); values.put("name", name); values.put("point", point); long result = db.insert("Score", null, values); if (result != -1) { db.setTransactionSuccessful(); } return result; } finally { db.endTransaction(); } } // 改动一条成绩记录 public int update(SQLiteDatabase db, String name, Integer point) { try { db.beginTransaction(); ContentValues values = new ContentValues(); values.put("name", name); values.put("point", point); int result = db.update("Score", values, "name = ?
【Android开发系列之SQLite】", new String[] { name }); db.setTransactionSuccessful(); return result; } finally { db.endTransaction(); } } // 删除一条成绩记录 public long delete(SQLiteDatabase db, String name) { try { db.beginTransaction(); int result = db.delete("Score", "name = ?", new String[] { name }); db.setTransactionSuccessful(); return result; } finally { db.endTransaction(); } } // 查询依据name正向排序的前10条总分大于指定分数的人员信息 public Cursor query(SQLiteDatabase db, Integer point) { return db.query("Score", new String[] { "name", "sum(point) as points" }, null, null, "name", "sum(point)> =" + point, "name asc", "0,10"); } // 更灵活的查询,SQL随意拼接 public Cursor query(SQLiteDatabase db, String sql, String[] selectionArgs) { return db.rawQuery(sql, selectionArgs); } }

这上面封装了CRUD操作。并且都是带事务的(运行多条SQL时须要),值得关注的是最后的两个query方法。
第一个query是指定了一个复杂sql查询语句的情况。
依照顺序,參数的含义例如以下:
1)、table The table name to compile the query against.    
指定的查询的表名
2)、columns A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn‘t going to be used.
返回的查询列表的列名
3)、selection A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table.
where条件,不包含wherekeyword
4)、selectionArgs You may include ?
s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings.
where条件指定的參数值
5)、groupBy A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped.
group by分组后面跟着的列名
6)、having A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used.
having 后面紧跟着的在分组基础上进一步筛选的内容
7)、orderBy How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.
order by后面依据某字段排序
8)、limit Limits the number of rows returned by the query, formatted as LIMIT clause. Passing null denotes no LIMIT clause.
limitkeyword。分页查询时使用
实际上上面相应的这8个參数,就是相应例如以下SQL查询语句各keyword后面的内容,其原理就是通过指定參数拼接例如以下SQL语句。
Android开发系列之SQLite
这里顺便提一下,SQLite Expert是非常好用的管理SQLite数据库的工具,能够在http://www.sqliteexpert.com/下载到。也能够直接搜索下载相应破解版本号。
回到第二个query方法。參数非常easy,仅仅有一个sql语句以及一个string数组(提供sql语句參数的值)。这种方法的意义就在于它非常灵活,能够直接把能够运行的sql扔进去运行。并且是參数化的。是第一种查询方法非常有力的补充。


好。最后我们就能够写測试代码来验证了。界面非常easy,直接放置一个button就可以。

public class SQLiteActivity extends Activity {@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sqlite); Button btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() {@Override public void onClick(View v) { DBHelper dbHelper = new DBHelper(SQLiteActivity.this); //获得一个可写数据库操作对象 SQLiteDatabase wdb = dbHelper.getWritableDatabase(); //加入纪录 ScoreOp scoreOp = new ScoreOp(); scoreOp.insert(wdb, "zhang3", 98); scoreOp.insert(wdb, "zhang3", 94); scoreOp.insert(wdb, "li4", 92); scoreOp.insert(wdb, "wang5", 89); scoreOp.insert(wdb, "wang5", 82); //改动记录 scoreOp.update(wdb, "li4", 90); //删除记录 scoreOp.delete(wdb, "li4"); //获得一个可读数据库操作对象 SQLiteDatabase rdb = dbHelper.getReadableDatabase(); // 1.能够调用系统提供的query方法,以指定參数的形式返回Cursor对象 // Cursor cursor = scoreOp.query(rdb, 192); // 2.能够直接运行SQL查询语句 Cursor cursor = scoreOp .query(rdb, "select name,sum(point) as points from Score group by name having sum(point)> =192 order by name asc limit ?,?", new String[] { "0", "10" }); while (cursor.moveToNext()) { String name = cursor.getString(cursor .getColumnIndex("name")); Integer points = cursor.getInt(cursor .getColumnIndex("points")); Toast.makeText(SQLiteActivity.this, "姓名:" + name + "。总分:" + points, Toast.LENGTH_SHORT) .show(); } cursor.close(); } }); }}




点击button运行之后就能够弹出符合条件的数据。假设不放心,能够切换到DDMS界面,选择File Explorer选项卡,找到路径下的我们创建的test.db文件,Pull(拉取)到电脑磁盘上,用SQLite Expert等工具打开验证。


















    推荐阅读