几乎所有app都会用到数据库,需要建立数据库,却又经常忘记一些细节的东西,还是自己记录下来,常看看吧,下面简单的实现一个数据库。
通常有新建和升级数据库的需求,先来新建数据。
android使用的SQL数据库,必须要使用SQLHelper来创建初始化数据库,生成的数据库文件在下面的目录 /data/data/<package_name>/databases;
1)使用SQLHelper建立数据库
继承SQLiteOpenHelper实现自定义的数据库,代码如下:
package database.qin.xue.com.databasedemo;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* Created by xue.qin on 2017/5/27.
*/
public class DemoDatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "DemoDatabaseHelper";
private static final int DATABASE_VERSION = 1; //版本号
private static final String DATABASE_NAME = "demo.db"; //数据库名称
static final String TABLE_NAME = "table_name"; //表的名称
private static final String DEFAULT_VALUES_1 = "(1, 'zhang3', 21, 0 );";
private static final String[] PROJECTION = {DemoContract.DemoColumns2._ID,
DemoContract.DemoColumns2.NAME,
DemoContract.DemoColumns2.AGE,
DemoContract.DemoColumns2.GENDER};
/**
* 参数3: CursorFactory 可以自定义返回Cursor ,例如加一些过滤条件
*/
public DemoDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
Log.i(TAG, "DemoDatabaseHelper()");
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.i(TAG, "onCreate()");
/*执行SQL语句创建数据库*/
db.execSQL("CREATE TABLE " + TABLE_NAME + " (" +
DemoContract.DemoColumns2._ID + " INTEGER PRIMARY KEY," +
DemoContract.DemoColumns2.NAME + " TEXT NOT NULL, " +
DemoContract.DemoColumns2.AGE + " INTEGER NOT NULL DEFAULT 0, " +
DemoContract.DemoColumns2.GENDER + " INTEGER NOT NULL DEFAULT 0 )");
/*插入一段初始数据,也可以不插入*/
String cs = ", "; //comma and space
String insertMe = "INSERT INTO " + TABLE_NAME + " (" +
DemoContract.DemoColumns2._ID + cs +
DemoContract.DemoColumns2.NAME + cs +
DemoContract.DemoColumns2.AGE + cs +
DemoContract.DemoColumns2.GENDER + ") VALUES ";
db.execSQL(insertMe + DEFAULT_VALUES_1);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "onUpgrade()");
}
public List<PersonStructure> getResult(int id, String name, int age, int gender) {
List<PersonStructure> personStructures = new ArrayList<PersonStructure>();
SQLiteDatabase db = getReadableDatabase(); //源码调用 getDatabaseLocked()-->mContext.openOrCreateDatabase() 打开或者创建数据库
Cursor cursor = db.query(TABLE_NAME, PROJECTION,
DemoContract.DemoColumns2._ID + " = ?", new String[]{String.valueOf(id)},
null, null, null);
if (cursor == null) return personStructures;
while (cursor.moveToNext()) {
personStructures.add(new PersonStructure(cursor));
}
return personStructures;
}
public List<PersonStructure> getResultAll() {
List<PersonStructure> personStructures = new ArrayList<PersonStructure>();
SQLiteDatabase db = getReadableDatabase(); //源码调用 getDatabaseLocked()-->mContext.openOrCreateDatabase() 打开或者创建数据库
Cursor cursor = db.query(TABLE_NAME, PROJECTION,
null, null,
null, null, null);
if (cursor == null) return personStructures;
while (cursor.moveToNext()) {
personStructures.add(new PersonStructure(cursor));
}
return personStructures;
}
public void inSertDB(PersonStructure p) {
SQLiteDatabase db = getReadableDatabase();
ContentValues values = new ContentValues();
values.put(DemoContract.DemoColumns2._ID, p.getId());
values.put(DemoContract.DemoColumns2.NAME, p.getName());
values.put(DemoContract.DemoColumns2.AGE, p.getAge());
values.put(DemoContract.DemoColumns2.GENDER, p.getGender());
db.insert(TABLE_NAME, null, values); //中间这个参数是否可以插入空行 null表示不可以
}
public void deleteDB(PersonStructure p) {
SQLiteDatabase db = getReadableDatabase();
db.delete(TABLE_NAME, DemoContract.DemoColumns2._ID + " = ?", new String[]{String.valueOf(p.getId())});
}
public void updateDB(PersonStructure p) {
SQLiteDatabase db = getReadableDatabase();
ContentValues values = new ContentValues();
values.put(DemoContract.DemoColumns2._ID, p.getId());
values.put(DemoContract.DemoColumns2.NAME, p.getName());
values.put(DemoContract.DemoColumns2.AGE, p.getAge());
values.put(DemoContract.DemoColumns2.GENDER, p.getGender());
db.update(TABLE_NAME, values, DemoContract.DemoColumns2._ID + " = ?", new String[]{String.valueOf(p.getId())});
}
public List<PersonStructure> queryDB(PersonStructure p) {
List<PersonStructure> personStructures = new ArrayList<PersonStructure>();
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, PROJECTION,
DemoContract.DemoColumns2.GENDER + " = ?", new String[]{String.valueOf(p.getGender())}, null, null, null);
if (cursor == null) return personStructures;
while (cursor.moveToNext()) {
personStructures.add(new PersonStructure(cursor));
}
return personStructures;
}
}
需要注意的是:构造函数,onCreate()和onUpgrade() 三个函数
public DemoDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
Log.i(TAG, "DemoDatabaseHelper()");
}
DATABASE_NAME:数据库的名字要以“.db”结束,例如我这里的声明:DATABASE_NAME = "demo.db"
DATABASE_VERSION:数据库的版本,从1开始,以后数据库升级依次递增。这里第一个版本就是1了。
onCreate()函数在第一次创建时执行,第一次使用getReadableDatabase(),getWritedableDatabase()时,之后不再执行,当用户清空数据之后的第一次使用也会触发,这时候使用SQL语句,需要创建表了。
db.execSQL("CREATE TABLE " + TABLE_NAME + " (" +
DemoContract.DemoColumns2._ID + " INTEGER PRIMARY KEY," +
DemoContract.DemoColumns2.NAME + " TEXT NOT NULL, " +
DemoContract.DemoColumns2.AGE + " INTEGER NOT NULL DEFAULT 0, " +
DemoContract.DemoColumns2.GENDER + " INTEGER NOT NULL DEFAULT 0 )");
TABLE_NAME:表的名字
DemoContract.DemoColumns2._ID:字段,(主键)
DemoContract.DemoColumns2.NAME:字段 “name”,剩下的分别是“age”和“gender“
这时候创建完了,也可以使用SQL语句插入一条数据,代码如下。
/*插入一段初始数据,也可以不插入*/
String cs = ", "; //comma and space
String insertMe = "INSERT INTO " + TABLE_NAME + " (" +
DemoContract.DemoColumns2._ID + cs +
DemoContract.DemoColumns2.NAME + cs +
DemoContract.DemoColumns2.AGE + cs +
DemoContract.DemoColumns2.GENDER + ") VALUES ";
db.execSQL(insertMe + DEFAULT_VALUES_1);
这就完了,好简单。之后需要在helper中写一些public方法来使用这个数据库就可以了,增删改查,需要啥就写啥,举个例子,查询所有的数据。如下代码
public List<PersonStructure> getResultAll() {
List<PersonStructure> personStructures = new ArrayList<PersonStructure>();
SQLiteDatabase db = getReadableDatabase(); //源码调用 getDatabaseLocked()-->mContext.openOrCreateDatabase() 打开或者创建数据库
Cursor cursor = db.query(TABLE_NAME, PROJECTION,
null, null,
null, null, null);
if (cursor == null) return personStructures;
while (cursor.moveToNext()) {
personStructures.add(new PersonStructure(cursor));
}
return personStructures;
}
获得数据库,执行查询动作,调用函数。
public Cursor query(String table, String[] columns, String selection,
String[] selectionArgs, String groupBy, String having,
String orderBy)
参数table :表名
参数columns:查询的字段,也就是最后输出的字段
参数selection:过滤的字段,
参数selectionArgs:过滤条件
参数 groupBy:结果按照什么字段分组
参数having :对应SQL语句HAVING后面的字符串
参数 orderBy:排序方式。
类似的将其他的需要操作数据库的方法提供出来,就可以使用此数据库了。
1)升级数据库
经常需要对数据库升级,增加字段之类的,首先修改Helper的构造函数,将版本增加1
public DemoDatabaseHelper(Context context) {
// super(context, DATABASE_NAME, null, DATABASE_VERSION);
super(context, DATABASE_NAME, null, DATABASE_VERSION_2);
Log.i(TAG, "DemoDatabaseHelper()");
}
将版本由1 变为2。这样下次getReadableDatabase()数据的时候就会调用onUpgrade(),就需要在这里进行升级操作。如下
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "onUpgrade() oldVersion = "+oldVersion+" newVersion = "+newVersion);
/*
如果当前版本是1,那么升级为2,添加1个字段
* */
if (oldVersion == DATABASE_VERSION) {
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN " + DemoContract.DemoColumns2.COUNTRY + " INTEGER NOT NULL DEFAULT 0");
}
}
容易错误的地方,如果用户是第一次安装,onUpgrade不执行,那也需要在onCreate()中创建表的时候将添加的字段添加。
db.execSQL("CREATE TABLE " + TABLE_NAME + " (" +
DemoContract.DemoColumns2._ID + " INTEGER PRIMARY KEY," +
DemoContract.DemoColumns2.NAME + " TEXT NOT NULL, " +
DemoContract.DemoColumns2.AGE + " INTEGER NOT NULL DEFAULT 0, " +
DemoContract.DemoColumns2.GENDER + " INTEGER NOT NULL DEFAULT 0, "+
DemoContract.DemoColumns2.COUNTRY + " INTEGER NOT NULL DEFAULT 0 )");
升级完了之后查询一下这个字段,看看是否成功添加,Log。
01-02 04:02:19.043 2793-2793/database.qin.xue.com.databasedemo I/DemoDatabaseHelper: getResultAll() Country = 0
实现了一个小demo,如下截图。
DEMO地址:点击打开链接