Android为了让我们能够更加方便地管理数据库,专门提供了一个SQLiteOpenHelper帮助类,借助这个类就可以非常简单地对数据库进行创建和升级。既然有好东西可以直接使用,那我们自然要尝试一下了,下面我就将对SQLiteOpenHelper的基本用法进行介绍。首先你要知道SQLiteOpenHelper是一个抽象类,这意味着如果我们想要使用它的话, 就需要创建一个自己的帮助类去继承它。SQLiteOpenHelper 中有两个抽象方法,分别是onCreate()和onUpgrade(),我们必须在自己的帮助类里面重写这两个方法,然后分别在这两个方法中去实现创建、升级数据库的逻辑。SQLiteOpenHelper 中还有两个非常重要的实例方法,getReadableDatabase()和getWritableDatabase()。这两个方法都可以创建或打开一个现有的数据库 (如果数据库已存在则直接打开,否则创建一个新的数据库),并返回一个可对数据库进行读写操作的对象。不同的是,当数据库不可写入的时候(如磁盘空间已满)getReadableDatabase()方法返回的对象将以只读的方式去打开数据库,而getWritableDatabase()方法则将出现异常。SQLiteOpenHelper中有两个构造方法可供重写,一般使用参数少一点的那个构造方法即可。这个构造方法中接收四个参数,第一个参数是Context,这个没什么好说的,必须要它才能对数据库进行操作。第二个参数是数据库名,创建数据库时使用的就是这里指定的名称。第三个参数允许我们在查询数据的时候返回一个自定义的Cursor,一般都是传入null。第四个参数表示当前数据库的版本号,可用于对数据库进行升级操作。构建出SQLiteOpenHelper的实例之后,再调用它的getReadableDatabase()或getWritableDatabase()方法就能够创建数据库了,数据库文件会存放在/data/data/<packagename>/databases/目录下。 此时,重写的onCreate()方法也会得到执行,所以通常会在这里去处理一些创建表的逻辑。
创建数据库如下所示
public class DbOpenHelper extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 1;
private static DbOpenHelper instance;
private DbOpenHelper(Context context) {
super(context, getUserDatabaseName(), null, DATABASE_VERSION);
}
public static DbOpenHelper getInstance(Context context) {
if (instance == null) {
instance = new DbOpenHelper(context.getApplicationContext());
}
return instance;
}
//
private static String getUserDatabaseName() {
return 你自己的命名的数据库名称.db";
}
@Override
public void onCreate(SQLiteDatabase db) {
//写入你自己要创建的表
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void closeDB() {
if (instance != null) {
try {
SQLiteDatabase db = instance.getWritableDatabase();
db.close();
} catch (Exception e) {
e.printStackTrace();
}
instance = null;
}
}
}
其实我们可以对数据进行的操作也就无非四种,即CRUD。其中C代表添加 (Create),R代表查询 (Retrieve),U代表更新 (Update),D代表删除 (Delete)。每一种操作又各自对应了一种SQL命令,如果你比较熟悉SQL语言的话,一定会知道添加数据时使用insert,查询数据时使用select,更新数据时使用update,删除数据时使用delete。但是开发者的水平总会是参差不齐的,未必每一个人都能非常熟悉地使用SQL语言,因此Android也是提供了一系列的辅助性方法,使得在Android中即使不去编写SQL语句,也能轻松完成所有的CRUD操作。前面我们已经知道,调用SQLiteOpenHelper的getReadableDatabase()或getWritableDatabase() 方法是可以用于创建和升级数据库的,不仅如此,这两个方法还都会返回一个SQLiteDatabase对象,借助这个对象就可以对数据进行CRUD操作了。
如一下查询user 信息为例 里面包含了查询更删除 增加的例子:
public class UserDao {
public static final String TABLE_NAME = "uers";
public static final String COLUMN_NAME_ID = "username";
public static final String COLUMN_NAME_NICK = "nick";
public static final String COLUMN_NAME_AVATAR = "avatar";
public static final String PREF_TABLE_NAME = "pref";
public static final String COLUMN_NAME_DISABLED_GROUPS = "disabled_groups";
public static final String COLUMN_NAME_DISABLED_IDS = "disabled_ids";
private DbOpenHelper dbHelper;
public UserDao(Context context) {
dbHelper = DbOpenHelper.getInstance(context);
}
/**
* 保存好友list
*
* @param contactList
*/
public void saveContactList(List<User> contactList) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
if (db.isOpen()) {
db.delete(TABLE_NAME, null, null);
for (User user : contactList) {
ContentValues values = new ContentValues();
values.put(COLUMN_NAME_ID, user.getUsername());
if(user.getNick() != null)
values.put(COLUMN_NAME_NICK, user.getNick());
if(user.getAvatar() != null)
values.put(COLUMN_NAME_AVATAR, user.getAvatar());
db.replace(TABLE_NAME, null, values);
}
}
}
/**
* 获取好友list
*
* @return
*/
public Map<String, User> getContactList() {
SQLiteDatabase db = dbHelper.getReadableDatabase();
Map<String, User> users = new HashMap<String, User>();
if (db.isOpen()) {
Cursor cursor = db.rawQuery("select * from " + TABLE_NAME /* + " desc" */, null);
while (cursor.moveToNext()) {
String username = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_ID));
String nick = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_NICK));
String avatar = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_AVATAR));
User user = new User();
user.setUsername(username);
user.setNick(nick);
user.setAvatar(avatar);
String headerName = null;
if (!TextUtils.isEmpty(user.getNick())) {
headerName = user.getNick();
} else {
headerName = user.getUsername();
}
if (username.equals(Constant.NEW_FRIENDS_USERNAME) || username.equals(Constant.GROUP_USERNAME)
|| username.equals(Constant.CHAT_ROOM)) {
user.setHeader("");
} else if (Character.isDigit(headerName.charAt(0))) {
user.setHeader("#");
} else {
user.setHeader(HanziToPinyin.getInstance().get(headerName.substring(0, 1))
.get(0).target.substring(0, 1).toUpperCase());
char header = user.getHeader().toLowerCase().charAt(0);
if (header < 'a' || header > 'z') {
user.setHeader("#");
}
}
users.put(username, user);
}
cursor.close();
}
return users;
}
/**
* 删除一个联系人
* @param username
*/
public void deleteContact(String username){
SQLiteDatabase db = dbHelper.getWritableDatabase();
if(db.isOpen()){
db.delete(TABLE_NAME, COLUMN_NAME_ID + " = ?", new String[]{username});
}
}
/**
* 保存一个联系人
* @param user
*/
public void saveContact(User user){
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_NAME_ID, user.getUsername());
if(user.getNick() != null)
values.put(COLUMN_NAME_NICK, user.getNick());
if(user.getAvatar() != null)
values.put(COLUMN_NAME_AVATAR, user.getAvatar());
if(db.isOpen()){
db.replace(TABLE_NAME, null, values);
}
}
public void setDisabledGroups(List<String> groups){
setList(COLUMN_NAME_DISABLED_GROUPS, groups);
}
public List<String> getDisabledGroups(){
return getList(COLUMN_NAME_DISABLED_GROUPS);
}
public void setDisabledIds(List<String> ids){
setList(COLUMN_NAME_DISABLED_IDS, ids);
}
public List<String> getDisabledIds(){
return getList(COLUMN_NAME_DISABLED_IDS);
}
private void setList(String column, List<String> strList){
StringBuilder strBuilder = new StringBuilder();
for(String hxid:strList){
strBuilder.append(hxid).append("$");
}
SQLiteDatabase db = dbHelper.getWritableDatabase();
if (db.isOpen()) {
ContentValues values = new ContentValues();
values.put(column, strBuilder.toString());
db.update(PREF_TABLE_NAME, values, null,null);
}
}
private List<String> getList(String column){
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select " + column + " from " + PREF_TABLE_NAME,null);
if (!cursor.moveToFirst()) {
cursor.close();
return null;
}
String strVal = cursor.getString(0);
if (strVal == null || strVal.equals("")) {
return null;
}
cursor.close();
String[] array = strVal.split("$");
if(array != null && array.length > 0){
List<String> list = new ArrayList<String>();
for(String str:array){
list.add(str);
}
return list;
}
return null;
}
}
使用SQL操作数据库
虽然Android 已经给我们提供了很多非常方便的API用于操作数据库,不过总会有一些 人不习惯去使用这些辅助性的方法,而是更加青睐于直接使用SQL来操作数据库。
添加数据的方法如下:
db.execSQL("insert intoBook (name,author,pages,price)values(?, ?,?,?)",
new String[] { "The Da Vinci Code", "Dan Brown", "454", "16.96" });
db.execSQL("insert intoBook (name,author,pages,price)values(?, ?,?,?)",
new String[] {"TheLost Symbol", "DanBrown", "510", "19.95" });
更新数据的方法如下:
db.execSQL("update Book setprice = ?where name = ?",new String[] {"10.99",
"The Da Vinci Code" });
删除数据的方法如下:
db.execSQL("delete from Book where pages > ?", new String[] { "500" });
查询数据的方法如下:
db.rawQuery("select * from Book", null);
可以看到,除了查询数据的时候调用的是SQLiteDatabase的rawQuery()方法,其他的操 作都是调用的execSQL()方法。以上演示的几种方式,执行结果会和前面几小节中我们学习的CRUD操作的结果完全相同,选择使用哪一种方式就看你个人的喜好了。