Android原生数据库-SQLite
简介
最近维护的一个项目中,用到了Android的四大组件之一 ContentProvider,里面涉及到了Android原生数据库SQLite,顺便复习一下数据库的知识。
使用
Android为了我们方便使用数据库提供了一个帮助类SQLiteOpenHelper,继承这个类就可以实现数据库的创建、升级,onCreate()数据库创建数据库时执行的方法,在该方法中执行创建表的操作。onUpgrade()在数据库升级版本时,执行与数据库升级相关的操作。操作SQLite需要对SQL语句有一定的了解,SQlite教程
Andoid SQLite为我们提供执行SQL方法:
execSQL()可以执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句
rawQuery()用于执行select语句。
继承SQLiteOpenHelper
public class MyDBHelper extends SQLiteOpenHelper {
private final static String DB_TABLE = "person";
public MyDBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
//创建数据库表
createDbTable(db, DB_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//数据库升级操作
updateDatabase(db, oldVersion, newVersion, DB_TABLE);
}
private void updateDatabase(SQLiteDatabase db, int fromVersion, int toVersion, String tableName) {
Log.d("updateDatabase: ", " tableName: " + tableName + " fromVersion: " + fromVersion + " toVersion: " + toVersion);
if (fromVersion < toVersion) {
//往表中增加一列
db.execSQL("ALTER TABLE " + tableName + " ADD phone VARCHAR(12)");
}
}
/**
* 创建数据库表
*
* @param db 数据实例
* @param tableName 表名
*/
private void createDbTable(SQLiteDatabase db, String tableName) {
Log.d("createDatabase: ", "创建数据库表");
db.execSQL("CREATE TABLE " + tableName + "(_id INTEGER PRIMARY KEY AUTOINCREMENT" +
",NAME VARCHAR(10)" +
",AGE INTEGER" +
",SEX VARCHAR(2)" +
")");
}
}
在onCreate()中创建数据库表:
/**
* 创建数据库表
*
* @param db 数据实例
* @param tableName 表名
*/
private void createDbTable(SQLiteDatabase db, String tableName) {
Log.d("createDatabase: ", "创建数据库表");
db.execSQL("CREATE TABLE " + tableName + "(_id INTEGER PRIMARY KEY AUTOINCREMENT" +
",NAME VARCHAR(10)" +
",AGE INTEGER" +
",SEX VARCHAR(2)" +
")");
}
在onUpgrade()方法中升级数据库表:
private void updateDatabase(SQLiteDatabase db, int fromVersion, int toVersion, String tableName) {
Log.d("updateDatabase: ", " tableName: " + tableName + " fromVersion: " + fromVersion + " toVersion: " + toVersion);
if (fromVersion < toVersion) {
//往表中增加一列
db.execSQL("ALTER TABLE " + tableName + " ADD phone VARCHAR(11)");
}
}
创建数据库
创建数据库名字test.db,数据库版本1
MyDBHelper dbHelper = new MyDBHelper(this, "test.db", null, 1);
SQLiteDatabase writableDatabase = dbHelper.getWritableDatabase();
数据库位置
数据库添加数据(insert)
mWritableDatabase = mDbHelper.getWritableDatabase();
//第一种数据库插入方式
mWritableDatabase.execSQL("insert into person(name, age, sex) values('张三', 18,'男')");
//第二种数据库插入方式
mWritableDatabase.execSQL("insert into person(name, age, sex) values(?,?,?)",
new Object[]{"李四", "19", "女"});
//第三种数据库插入方式
ContentValues values = new ContentValues();
values.put("name", "王五");
values.put("age", "20");
values.put("sex", "女");
mWritableDatabase.insert("person", null, values);
//关闭数据库
mWritableDatabase.close();
添加数据
如果采用第一种方式,当用户输入的内容含有单引号时,组拼出来的SQL语句就会存在语法错误。要解决这个问题需要对单引号进行转义,也就是把单引号转换成两个单引号。有些时候用户往往还会输入像“ & ”这些特殊SQL符号,为保证组拼好的SQL语句语法正确,必须对SQL语句中的这些特殊SQL符号都进行转义,显然,对每条SQL语句都做这样的处理工作是比较烦琐的。也存在容易发生SQL注入攻击。所以在执行数据库插入操作时,一般采用第二种种和第三种方式进行数据库数据插入。
数据库删除数据(delete)
mWritableDatabase = mDbHelper.getWritableDatabase();
//第一种方式
mWritableDatabase.execSQL("delete from person where name = '" + "张三" + "';");
//第二种方式
mWritableDatabase.execSQL("delete from person where name = ? ;", new Object[]{"李四"});
//第三种方式
mWritableDatabase.delete("person", "name = ?", new String[]{"王五"});
//关闭数据库
mWritableDatabase.close();
删除表数据
数据库修改数据(update)
mWritableDatabase = mDbHelper.getWritableDatabase();
//第一种
mWritableDatabase.execSQL("update person set sex = '女' where name = '张三';");
//第二种
mWritableDatabase.execSQL("update person set sex = ? where name = ?;", new Object[]{"男", "李四"});
//第三种
ContentValues values = new ContentValues();
values.put("sex", "男");
mWritableDatabase.update("person", values, "name = ?", new String[]{"王五"});
//关闭数据库
mWritableDatabase.close();
数据库数据修改
数据库查询数据(query)
String result = "";
Cursor cursor = null;
SQLiteDatabase readableDatabase = mDbHelper.getReadableDatabase();
try {
cursor = readableDatabase.rawQuery("select * from person where age > ? order by age desc", new String[]{"18"});
// Cursor cursor = readableDatabase.query("person", null, null, null, null, null, null);
// Cursor cursor = readableDatabase.query(true, "person", new String[]{"_id", "name", "sex", "age"}, "age>?", new String[]{"18"}, null, null, "age desc", null);
//使用游标 获取游标中的数据
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex("NAME"));
String sex = cursor.getString(cursor.getColumnIndex("SEX"));
String age = cursor.getString(cursor.getColumnIndex("AGE"));
result = result + "\n" + "_id=" + id + " name=" + name + " sex=" + sex + " age=" + age;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭游标
if (cursor != null) {
cursor.close();
cursor = null;
}
//关闭数据库
readableDatabase.close();
//展示数据
mTextView.setText(result);
}
查询数据库person表数据
注意:
查询数据库完成之后,记得关闭游标,否则会造成内存泄漏;另外关闭数据库就看数据库是否使用频繁,使用频繁则可以在页面销毁、程序退出时关闭。
Cursor cursor = null;
try {
//TODO...
} catch (Exception e) {
e.printStackTrace();
} finally{
if(null != cursor){
cursor.close();
cursor = null;
}
}
数据库升级
将数据库版本将1改为2,这时onUpgrade()里面执行数据库升级操作。
MyDBHelper dbHelper = new MyDBHelper(this, "test.db", null, 2);
SQLiteDatabase writableDatabase = dbHelper.getWritableDatabase();
数据升级