一:前言
之前介绍过Android中保存数据的两种方式:SharedPreferences和File,这篇介绍另一种存储数据的方式——数据库SQLite——轻量级数据库系统。
数据库:简单来说可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
二:用法
举一个保存用户信息的栗子:
创建一个数据库mySQLite,在该数据库中创建一个user表,用来保存用户信息,用户属性name(姓名:String类型)、age(年龄:int类型)。
1、创建一个用户类(方便后面的操作)
/**
* 用户
* Created by Gavin on 2016/5/30.
*/
public class User {
/**
* id
*/
private int id;
/**
* 用户名
*/
private String name;
/**
* 年龄
*/
private int age;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
public int getId() {
return id;
}
public void setId(int 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(int age) {
this.age = age;
}
}
2、创建一个DatabaseHelper类 用来处理所有的数据库操作。(这用到了SQL语句,不懂的看解释)
/** * Created by Gavin on 2016/5/30. */ public class DatabaseHelper extends SQLiteOpenHelper { /** * 数据库版本,需要升级数据库时只要加一即可 */ private static final int DATABASE_VERSION = 1; /** * 数据库名 */ private static final String DATABASE_NAME = "mySQLite.db"; /** * 构造方法 * 每次创建DatabaseHelper对象时,若本应用无该数据库,则新建数据库并调用onCreate方法; * 若该数据库已创建则直接使用已存在的数据库且跳过onCreate方法 * @param context 上下文 */ public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } /** * 创建数据库是时调用(只被调用一次) * @param db 数据库 */ @Override public void onCreate(SQLiteDatabase db) { //创建user表,属性:id(用户id,主键)、name(姓名)、age(年龄) db.execSQL("CREATE TABLE user (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(10),age INTEGER)"); } /** * 跟新数据库时调用 * @param db 数据库 * @param oldVersion 旧版本号 * @param newVersion 新版本号 */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //升级:往user表,添加性别属性 //db.execSQL("ALTER TABLE user ADD COLUMN gender VARCHAR(2)"); } }
数据库mySQLite在构造方法中创建,其中super()的参数有4个:
context:上下文;
datebaseName:数据库名,一般以.db结尾;
factory : 当打开的数据库执行查询语句的时候 会创建一个Cursor对象, 这时会调用Cursor工厂类 factory, 可以填写null默认值;
version:数据库版本,需要升级数据库时将版本号加一,将升级的内容写在onUpgrade中即可。
- onCreate
当数据库第一次创建的时候,会执行onCreate()方法。这里的onCreate方法中创建了一张user表,db.execSQL()方法执行了里面SQL语句。- onUpgrade
数据库升级时会调用onUpgrade()方法,这里的onUpgrade()方法往user表中添加了性别(gender)属性。3、操作数据库
操作数据库,增删查改是免不了的。下面的方法都是在DatabaseHelper 中添加。
-
增(Create)
/** * 插入一条数据 * @param user 用户对象 */ public void insertAUser(User user) { //如果要对数据进行更改,就调用此方法得到用于操作数据库的实例, //该方法以读和写方式打开数据库 SQLiteDatabase database = getWritableDatabase(); //向user表插入一条数据 database.execSQL( "INSERT INTO user(name, age) VALUES(?,?)", new Object[]{user.getName(), user.getAge()}); }
insertAUser()中使用了execSQL()执行了插入数据的操作。
这里用到的execSQL()有两个参数:
参数1:SQL指令,这里是一条插入命令,命令中的问号(?)为占位符
参数2:Object数组,数组中的内容对应参数1中的问号(?) -
删(Delete)
/** * 根据id删除一条数据 * @param id 用户id */ public void deleteAUser(Integer id) { SQLiteDatabase database = getWritableDatabase(); //根据id删除一条数据 database.execSQL("DELETE FROM user WHERE id=?", new Object[]{id}); }
deleteAUser()根据用户id,删除了对应的用户信息。这里也是用了execSQL()执行数据操作。
-
查(Read)
/** * 读取一条数据 * @param id 用户id * @return 用户对象 */ public User readAUser(Integer id) { //如果只对数据进行读取,建议使用此方法 SQLiteDatabase database = getReadableDatabase(); Cursor cursor = database.rawQuery( "SELECT * FROM user WHERE id=?", new String[]{id.toString()}); if (cursor.moveToFirst()) { //读取数据,并返回 User user = new User(); user.setId(cursor.getInt(cursor.getColumnIndex("id"))); user.setName(cursor.getString(cursor.getColumnIndex("name"))); user.setAge(cursor.getInt(cursor.getColumnIndex("age"))); cursor.close(); return user; } else { //未读出数据,返回空数据 return null; } } /** * 获取整个用户列表 * @return */ public List<User> readAllUser() { SQLiteDatabase database = getReadableDatabase(); Cursor cursor = database.rawQuery("SELECT * FROM user", new String[]{}); List<User> list = new ArrayList<User>(); //使用moveToNext()逐条读取 while (cursor.moveToNext()) { User user = new User(); user.setId(cursor.getInt(cursor.getColumnIndex("id"))); user.setName(cursor.getString(cursor.getColumnIndex("name"))); user.setAge(cursor.getInt(cursor.getColumnIndex("age"))); list.add(user); } cursor.close(); return list; }
readAUser()中使用rawQuery方法获取到用户信息,通过cursor.moveToFirst()来获取cursor的第一条数据,接着通过cursor.getInt()、cursor.getString()来获取对应的数据。
这里使用了getReadableDatabase()而不是getWritableDatabase()
- Cursor
是每行的集合。详情请参考Android 中关于 【Cursor】 类的介绍
- Cursor
-
改(Update)
/** * 更新一条用户数据 * @param user 用户对象 */ public void updateAUser(User user) { SQLiteDatabase database = getWritableDatabase(); //根据id更新一条数据 database.execSQL( "UPDATE user SET name=?, age=? WHERE id=?", new Object[]{user.getName(), user.getAge(), user.getId()}); }
这也没什么好说的~~
execSQL()中用到的都最基础的是SQL指令,至于复杂的自己去查吧
4、辅助类DatabaseHelper写完了,接下来就是使用
-
插入一条数据
DatabaseHelper helper = new DatabaseHelper(this); User user1 = new User(); user1.setName("lisa"); user1.setAge(20); helper.insertAUser(user1);//插入一条数据 Log.i(TAG, helper.readAllUser().toString());//查看所有用户
结果
结果 -
根据id获取一条数据,修改,删除。上面我们看到,插入的那条数据id是1
DatabaseHelper helper = new DatabaseHelper(this); User user1 = helper.readAUser(1); //查找id为1的用户 Log.i(TAG, helper.readAUser(1).toString()); //显示id为1的用户 user1.setAge(30); //将年龄改为30 helper.updateAUser(user1); //更新数据库 Log.i(TAG, helper.readAUser(1).toString()); //显示id为1的用户 helper.deleteAUser(user1.getId()); //删除user1 Log.i(TAG, helper.readAUser(1).toString()); //显示id为1的用户
结果
结果
上面的代码中,分别打印了三次log。
第一次使用id为1的用户;
第二次是年龄被修改为30的用户;
第三次是被删除的用户,因为用户不存在了,所以没有第三条log
(由于helper.readAUser(1)没有获取到数据,返回null,接着使用了toString()出现空指针异常,闪退了,做了一个反面教材~~)。
不管怎么说,这次的目的达到了,增删查改都ok了。
三:小结
使用SQLite就是在本地建了一个数据库,使用数据库中的表来保存数据。SQLite对数据的操作十分灵活,不过相比SharedPreferences和File在使用上要复杂一些,而且要一点的数据库基础。
附:DatabaseHelper完整代码
package com.nostra13.universalimageloader.sample; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import java.util.ArrayList; import java.util.List; /** * Created by Gavin on 2016/5/30. */ public class DatabaseHelper extends SQLiteOpenHelper { /** * 数据库版本,需要升级数据库时只要加一即可 */ private static final int DATABASE_VERSION = 1; /** * 数据库名 */ private static final String DATABASE_NAME = "mySQLite.db"; /** * 构造方法 * 每次创建DatabaseHelper对象时,若本应用无该数据库,则新建数据库并调用onCreate方法; * 若该数据库已创建则直接使用已存在的数据库且跳过onCreate方法 * factory : 当打开的数据库执行查询语句的时候 会创建一个Cursor对象, 这时会调用Cursor工厂类 factory, 可以填写null默认值 * @param context 上下文 */ public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } /** * 创建数据库是时调用(只被调用一次) * @param db 数据库 */ @Override public void onCreate(SQLiteDatabase db) { //创建user表,属性:id(用户id,主键)、name(姓名)、age(年龄) db.execSQL("CREATE TABLE user (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(10),age INTEGER)"); } /** * 跟新数据库时调用 * @param db 数据库 * @param oldVersion 旧版本号 * @param newVersion 新版本号 */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //升级user表,添加性别 //db.execSQL("ALTER TABLE user ADD COLUMN gender VARCHAR(2)"); } /** * 插入一条数据 * @param user 用户对象 */ public void insertAUser(User user) { //如果要对数据进行更改,就调用此方法得到用于操作数据库的实例,该方法以读和写方式打开数据库 SQLiteDatabase database = getWritableDatabase(); //向user表插入一条数据 database.execSQL( "INSERT INTO user(name, age) VALUES(?,?)", new Object[]{user.getName(), user.getAge()}); } /** * 更新一条用户数据 * @param user 用户对象 */ public void updateAUser(User user) { SQLiteDatabase database = getWritableDatabase(); //根据id更新一条数据 database.execSQL( "UPDATE user SET name=?, age=? WHERE id=?", new Object[]{user.getName(), user.getAge(), user.getId()}); } /** * 根据id删除一条数据 * @param id 用户id */ public void deleteAUser(Integer id) { SQLiteDatabase database = getWritableDatabase(); //根据id删除一条数据 database.execSQL("DELETE FROM user WHERE id=?", new Object[]{id}); } /** * 获取整个用户列表 * @return */ public List<User> readAllUser() { SQLiteDatabase database = getReadableDatabase(); Cursor cursor = database.rawQuery("SELECT * FROM user", new String[]{}); List<User> list = new ArrayList<User>(); while (cursor.moveToNext()) { User user = new User(); user.setId(cursor.getInt(cursor.getColumnIndex("id"))); user.setName(cursor.getString(cursor.getColumnIndex("name"))); user.setAge(cursor.getInt(cursor.getColumnIndex("age"))); list.add(user); } cursor.close(); return list; } /** * 读取一条数据 * @param id 用户id * @return 用户对象 */ public User readAUser(Integer id) { //如果只对数据进行读取,建议使用此方法 SQLiteDatabase database = getReadableDatabase(); Cursor cursor = database.rawQuery( "SELECT * FROM user WHERE id=?", new String[]{id.toString()}); if (cursor.moveToFirst()) { //读取数据,并返回 User user = new User(); user.setId(cursor.getInt(cursor.getColumnIndex("id"))); user.setName(cursor.getString(cursor.getColumnIndex("name"))); user.setAge(cursor.getInt(cursor.getColumnIndex("age"))); cursor.close(); return user; } else { //未读出数据,返回空数据 return null; } } }