现在的主流移动设备像Android、iPhone等都使用SQLite作为复杂数据的存储引擎,在我们为移动设备开发应用程序时,也许就要使用到SQLite来存储我们大量的数据,所以我们就需要掌握移动设备上的SQLite开发技巧。对于Android平台来说,系统内置了丰富的API来供开发人员操作SQLite,我们可以轻松的完成对数据的存取。

1. SQLite常用的操作方法

MainActivity.java

package com.example.db;

import android.os.Bundle;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {

	private Button insertButton;
	private Button deleteButton;
	private Button updateButton;
	private Button findButton;
	private SQLiteDatabase db;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		insertButton = (Button) findViewById(R.id.Insert);
		insertButton.setOnClickListener(this);
		deleteButton = (Button) findViewById(R.id.Delete);
		deleteButton.setOnClickListener(this);
		updateButton = (Button) findViewById(R.id.Update);
		updateButton.setOnClickListener(this);
		findButton = (Button) findViewById(R.id.Find);
		findButton.setOnClickListener(this);
		createDB();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		if (v.equals(insertButton)) {
			ContentValues val = new ContentValues();
			Person person = new Person("join", 30);
			val.put("name", person.getName());
			val.put("age", person.getAge());
			db.insert("person", null, val);
		}
		if (v.equals(deleteButton)) {
			db.delete("person", "age > ?", new String[] { "33" });
		}
		if (v.equals(updateButton)) {
			ContentValues val = new ContentValues();
			val.put("age", 35);
			db.update("person", val, "name = ?", new String[] { "join" });
		}
		if (v.equals(findButton)) {
			Cursor c = db.rawQuery("SELECT * FROM person WHERE age >= ?", new String[]{"33"});  
	        while (c.moveToNext()) {  
	            int _id = c.getInt(c.getColumnIndex("_id"));  
	            String name = c.getString(c.getColumnIndex("name"));  
	            int age = c.getInt(c.getColumnIndex("age"));  
	            Log.i("test", "_id=>" + _id + ", name=>" + name + ", age=>" + age);  
	        } 
		}
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		db.close();
	}
	
	public void createDB() {
		db = openOrCreateDatabase("test.db", Context.MODE_PRIVATE, null);
		db.execSQL("DROP TABLE IF EXISTS person");
		db.execSQL("CREATE TABLE person (_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age SMALLINT)");
	}
}

Person.java

package com.example.db;

public class Person {
	private Integer id;
	private String name;
	private int age;

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public Person(Integer id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(Short age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
}


(1)在执行完上面的代码后,系统就会在/data/data/[PACKAGE_NAME]/databases目录下生成一个“test.db”的数据库文件.

(2)Android中对数据库进行操作的相关的接口、类等都在andorid.database和android.database.sqlite两个包里面。里面存在着很多的与数据库操作相关的类,但是在平时普通的开发中最经常遇到的仅仅就是那几个

db.insert(String table, String nullColumnHack, ContentValues values);  
	db.update(String table, Contentvalues values, String whereClause, String whereArgs);  
	db.delete(String table, String whereClause, String whereArgs);


以上三个方法的第一个参数都是表示要操作的表名;insert中的第二个参数表示如果插入的数据每一列都为空的话,需要指定此行中某一列的名称,系统将此列设置为NULL,不至于出现错误;insert中的第三个参数是ContentValues类型的变量,是键值对组成的Map,key代表列名,value代表该列要插入的值;update的第二个参数也很类似,只不过它是更新该字段key为最新的value值,第三个参数whereClause表示WHERE表达式,比如“age > ? and age < ?”等,最后的whereArgs参数是占位符的实际参数值;delete方法的参数也是一样。

(3)查询操作相对于上面的几种操作要复杂些,因为我们经常要面对着各种各样的查询条件,所以系统也考虑到这种复杂性,为我们提供了较为丰富的查询形式:

db.rawQuery(String sql, String[] selectionArgs);  
	db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy);  
	db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);  
	db.query(String distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);


上面几种都是常用的查询方法,第一种最为简单,将所有的SQL语句都组织到一个字符串中,使用占位符代替实际参数,selectionArgs就是占位符实际参数集;下面的几种参数都很类似,columns表示要查询的列所有名称集,selection表示WHERE之后的条件语句,可以使用占位符,groupBy指定分组的列名,having指定分组条件,配合groupBy使用,orderBy指定排序的列名,limit指定分页参数,distinct可以指定“true”或“false”表示要不要过滤重复值。需要注意的是,selection、groupBy、having、orderBy、limit这几个参数中不包括“WHERE”、“GROUP BY”、“HAVING”、“ORDER BY”、“LIMIT”等SQL关键字。 最后,他们同时返回一个Cursor对象,代表数据集的游标,有点类似于JavaSE中的ResultSet。


(4)最后当我们完成了对数据库的操作后,记得调用SQLiteDatabase的close()方法释放数据库连接,否则容易出现SQLiteException。