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操作的结果完全相同,选择使用哪一种方式就看你个人的喜好了。