SQLite

前言

之前介绍过Android中保存数据的两种方式:SharedPreferences和File,这篇介绍另一种存储数据的方式——数据库。

想必大家对数据库都不陌生,想当年上数据库课的时候,被那些命令整得不要不要的。

扯远了...

进入正题,在Android开发的过程中,保存数据是难免的。如果数据量较小的时候可用SharedPreferences或File来保存,当数据量较大且关系复杂的时候就要用到Android中的数据库SQLite——轻量级数据库系统。

用法

举一个保存用户信息的栗子:

创建一个数据库mySQLite,在该数据库中创建一个user表,用来保存用户信息,用户属性name(姓名:String类型)、age(年龄:int类型)。

创建一个用户类(方便后面的操作)

/**
* 用户
* 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;
}
}
创建一个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)属性。
操作数据库
操作数据库,增删查改是免不了的。下面的方法都是在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 readAllUser() {
SQLiteDatabase database = getReadableDatabase();
Cursor cursor = database.rawQuery("SELECT * FROM user", new String[]{});
List list = new ArrayList();
//使用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()
改(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指令,至于复杂的自己去查吧

使用

辅助类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 readAllUser() {
SQLiteDatabase database = getReadableDatabase();
Cursor cursor = database.rawQuery("SELECT * FROM user", new String[]{});
List list = new ArrayList();
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;
}
}
}