安卓中数据库的使用是很常见的,今天在介绍的基础上,去做一个简单的封装。
把数据库的表作为一个类,同时封装一个工具类,用来操作数据库的这个表。
实现基础的增删改查功能。
首先,我们先创建一个表的实体类,以及一个元素的实体类
表的实体类里面有创建表的方法,表名,以及表的字段列表
代码如下
public class TestTable {
/**
* 测试记录表
*/
//表的名字
public static final String NAME_TABLE_TEST = "table_text_list";
//以下为表的字段名字
public static final String NAME_COLUMN_TEST_ID = "id"; // 自增ID
public static final String NAME_COLUMN_TEST_NAME = "test_name";
public static final String NAME_COLUMN_TEST_AGE = "test_age";
public static final String NAME_COLUMN_TEST_SEX = "test_sex";
/**
* 创建表
*/
public static final String SQL_CREATE_TABLE_TEST = "create table IF NOT EXISTS " + NAME_TABLE_TEST + "("
+ NAME_COLUMN_TEST_ID + " integer primary key autoincrement, "
+ NAME_COLUMN_TEST_NAME + " varchar(50) not null, "
+ NAME_COLUMN_TEST_AGE + " long default 0, "
+ NAME_COLUMN_TEST_SEX + " integer default 0);";
}
表的实体类即把这些字段作为属性去生成一个实体类。
比如这里的name,age,和sex
public class TestEntity {
public String name;
public long age;
public int sex;
public TestEntity() {
}
public TestEntity(String name, long age, int sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getAge() {
return age;
}
public void setAge(long age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
@Override
public String toString() {
return "TestEntity{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
接下来便是核心代码。创建一个数据库操作的工具类
这边先把工具类的全部代码贴上,然后开始说明
public class TestTableSqlite {
private SQLiteDatabase mDb = null;
private DatabaseHelper mDbHelper;
private final Context ctx;
private static final String DATABASE_NAME = "mytest.db"; /* database name */
private static final int DATABASE_VERSION = 1; /* database version */
//初始化上下文
public TestTableSqlite(Context ctx) {
this.ctx = ctx;
}
private static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context ctx) {
//初始化数据库名称,版本号
super(ctx, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
//创建表
db.execSQL(TestTable.SQL_CREATE_TABLE_TEST);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
/**
* 打开数据库
*
* @return composition.db
* @throws SQLException
*/
public TestTableSqlite open() throws SQLException {
mDbHelper = new DatabaseHelper(ctx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
/* 关闭数据库 */
public void close() {
mDbHelper.close();
}
public void resetDbOpen() {
if (!mDb.isOpen()) {
open();
}
}
/**
* 删除指定的表
*/
public void clearTestRecord(String TabName) {
String sql = "delete from " + TabName;
mDb.execSQL(sql);
}
private static final String[] testColumns = new String[]{
TestTable.NAME_COLUMN_TEST_ID,
TestTable.NAME_COLUMN_TEST_NAME,
TestTable.NAME_COLUMN_TEST_AGE,
TestTable.NAME_COLUMN_TEST_SEX
};
/**
* 数据库插入一条记录
*
* @param entity
*/
public void insertTestRecord(TestEntity entity) {
ContentValues values = new ContentValues();
values.put(TestTable.NAME_COLUMN_TEST_NAME, entity.getName());
values.put(TestTable.NAME_COLUMN_TEST_AGE, entity.getAge());
values.put(TestTable.NAME_COLUMN_TEST_SEX, entity.getSex());
long insert = mDb.insert(TestTable.NAME_TABLE_TEST, null, values);
Log.d("print", "插入结果: " + insert);
}
/**
* 数据库根据性别删除一条数据
* 性别为0代表男的
* 性别为1代表女的
*/
public void deleteTestBySex(int sex) {
mDb.delete(TestTable.NAME_TABLE_TEST, TestTable.NAME_COLUMN_TEST_SEX + "=?",
new String[]{String.valueOf(sex)});
}
/**
* 数据库修改数据
* 修改指定的姓名的元素的性别
*
*/
public void updateTestBySex(String name,int sex) {
ContentValues values = new ContentValues();
values.put(TestTable.NAME_COLUMN_TEST_SEX, sex);
mDb.update(TestTable.NAME_TABLE_TEST,
values,
TestTable.NAME_COLUMN_TEST_NAME + "=?",
new String[]{name});
}
/**
* 根据性别查询
*
* @return
*/
public ArrayList<TestEntity> getAllMan(int sex) {
Cursor mCursor = mDb.query(TestTable.NAME_TABLE_TEST, testColumns, TestTable.NAME_COLUMN_TEST_SEX + "=\"" + sex + "\"", null, null, null, null);
ArrayList<TestEntity> list = new ArrayList<TestEntity>();
if (mCursor != null) {
while (mCursor.moveToNext()) {
TestEntity entity = new TestEntity();
entity.setName(mCursor.getString(mCursor.getColumnIndex(TestTable.NAME_COLUMN_TEST_NAME)));
entity.setAge(mCursor.getLong(mCursor.getColumnIndex(TestTable.NAME_COLUMN_TEST_AGE)));
entity.setSex(mCursor.getInt(mCursor.getColumnIndex(TestTable.NAME_COLUMN_TEST_SEX)));
list.add(entity);
}
}
mCursor.close();
System.gc();
return list;
}
/**
* 得到所有元素
*
* @return
*/
public ArrayList<TestEntity> getAllTest() {
Cursor mCursor = mDb.query(TestTable.NAME_TABLE_TEST, testColumns, null, null, null, null, null);
ArrayList<TestEntity> list = new ArrayList<TestEntity>();
if (mCursor != null) {
while (mCursor.moveToNext()) {
TestEntity entity = new TestEntity();
entity.setName(mCursor.getString(mCursor.getColumnIndex(TestTable.NAME_COLUMN_TEST_NAME)));
entity.setAge(mCursor.getLong(mCursor.getColumnIndex(TestTable.NAME_COLUMN_TEST_AGE)));
entity.setSex(mCursor.getInt(mCursor.getColumnIndex(TestTable.NAME_COLUMN_TEST_SEX)));
list.add(entity);
}
}
mCursor.close();
System.gc();
return list;
}
}
DatabaseHelper继承SQLiteOpenHelper类,去对数据库的名称,版本号做一个基本的设置
TestTableSqlite的onCreate方法里面就是去创建数据库里的表。
可以在这里创建多个你需要的数据表
这里不用担心多次调用时会重复创建的问题。
因为创建过的系统不会再创建了
核心方法是open,会返回一个TestTableSqlite的实体类,这个类就可以用来操作数据库的增删改查了
注意在页面关闭是调用close方法关闭数据库
还提供了了一个方法clearTestRecord
用来清除表的元素
注意,delete from tab_name不是删除表
是清空表里面的数据
drop table 表名
才是删除一个表
TestTableSqlite里面可以创建相应的方法
比如这里的insertTestRecord和getAllMan方法
就是一个插入数据,一个根据性别来查询数据
当然也可以相应的写好删除和修改数据的方法,
到时候直接调用即可
这边还要注意testColumns这个数组
里面放的就是数据表的所有字段
查询的时候需要用到
最后,说一下具体的用法
这里以Activity里使用举例
在需要使用的Activity的Oncreate方法进行初始化对象操作
然后调用open打开数据库
TestTableSqlite sqlite = new TestTableSqlite(this);
sqlite.open();
在onDestroy里面关闭数据库操作类
@Override
protected void onDestroy() {
super.onDestroy();
sqlite.close();
}
具体需要使用时,调用这个工具类里面的增删改查方法即可
以后需要进行新的增删改查操作,
就多增加这个工具类里面的方法即可
这样维护起来,也只需要在这个方法里面去做各种调试
不用在多个页面里面单独处理
说完了基本的使用
再来说一说数据库的升级
比如数据库一开始版本号DATABASE_VERSION为1
现在新增了表,字段等等
就需要把版本号提升
比如DATABASE_VERSION改为2
之后再安装新的apk
就会自动调用数据库的升级方法
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
具体升级适配就在这个方法里
下面是示例代码
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
for (int i = oldVersion; i < newVersion; i++) {
switch (i) {
case 2:
upgradeToVersion01(db);
break;
case 3:
upgradeToVersion02(db);
break;
default:
break;
}
}
}
可以看到,这里从老版本号到新版本号不断地遍历升级
每更新一个版本号,升级的适配就在对应的升级方法里
下面以upgradeToVersion01()方法里的代码为例
说明具体升级的操作
private void upgradeToVersion01(SQLiteDatabase db) {
//更新列
if(!checkColumnExists(db, 表名, 列名)) {
// 判断列是否存在,不存在则创建该列
db.execSQL("alter table " + 表名 + " add column " + 列名 + " integer default 0");
}
//更新表
String sql = "create table IF NOT EXISTS " + NAME_TABLE_TEST_TWO + "("
+ NAME_COLUMN_TEST_ID + " integer primary key autoincrement, "
+ NAME_COLUMN_TEST_NAME + " varchar(50) not null, "
+ NAME_COLUMN_TEST_AGE + " long default 0, "
+ NAME_COLUMN_TEST_SEX + " integer default 0);";
db.execSQL(sql);
}
可以看到,如果只是需要更新列,就执行更新列的内容
如果这次升级添加了新的表,那么表也要重新在里面创建
这里要用到一个方法checkColumnExists()
用来检查表中某列是否存在
不存在的话就说明需要在新的版本里添加该列
具体代码如下
/**
* 方法:检查表中某列是否存在
*
* @param db
* @param tableName 表名
* @param columnName 列名
* @return
*/
public static boolean checkColumnExists(SQLiteDatabase db, String tableName, String columnName) {
boolean result = false;
Cursor cursor = null;
try {
cursor = db.rawQuery("select * from sqlite_master where name = ? and sql like ?", new String[]{tableName, "%" + columnName + "%"});
result = (null != cursor && cursor.moveToFirst());
} catch (Exception e) {
Log.e("print", "checkColumnExists exception: " + e.getMessage());
} finally {
if (null != cursor && !cursor.isClosed()) {
cursor.close();
}
}
return result;
}
这样,数据库的升级就完成了。