数据库更新
如果是只是添加一个字段或几个,而不需要改变数据结构时, SQLite提供了ALTER TABLE命令,允许用户重命名或添加新的字段到已有表中,但是不能从表中删除字段。并且只能在表的末尾添加字段。
添加字段前,先往列表添加3条数据,当前版本号为1
之后加入更新代码
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.e(TAG, "-------> onUpgrade"+" oldVersion = "+oldVersion+" newVersion = "+newVersion);
if(oldVersion != newVersion)
{
switch (newVersion)
{
case 2:
//升级数据库,不改变表结构 注意空格
//添加列 addcol_goods2 , text 为字符串数据类型 ,person为表名
//alter table person add column addcol_goods2 text
//添加的列 添加优点 添加缺点
String addColGoods = "addcol_goods"+newVersion;
String addColBads = "addcol_bads"+newVersion;
//添加列的sql语句
String upgradeGoods = "alter table "+TABLE_NAME_PERSON + " add column "+ addColGoods+" text";
String upgradeBads = "alter table "+TABLE_NAME_PERSON+" add column "+addColBads+" text";
//执行sql语句 一次只能添加一个字段
db.execSQL(upgradeGoods);
db.execSQL(upgradeBads);
break;
}
}
}
把版本号改为2,运行,查看数据库,两个字段添加成功
~更新数据库改的地方改的地方还是挺多的,除了增加更新代码,还需要更改版本号,增删改查代码也都需要相应更改。
另外创建表的地方也需要进行修改,因为用户清除数据,数据库需要重新创建,但是创建时不会再走onUpgrade()方法的,所以也要将添加的字段放到创建的表语句里。
一般的做法也会在onUpgrade
方法中,判断数据库当前列是否存在,不存在则添加,会灵活很多,如下。
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 判断列addcol_goods2是否存在,不存在则创建该列
if (!checkColumnExists(db, TABLE_NAME_PERSON , "addcol_goods2")) {
db.execSQL("alter table " + TABLE_NAME_PERSON + " add column " + "addcol_goods2" + " text");
}
// 判断列addcol_bads2是否存在,不存在则创建该列
if (!checkColumnExists(db, TABLE_NAME_PERSON , "addcol_bads2")) {
db.execSQL("alter table " + TABLE_NAME_PERSON + " add column " + "addcol_bads2" + " text");
}
}
/**
* 方法:检查表中某列是否存在
* @param db
* @param tableName 表名
* @param columnName 列名
* @return
*/
private 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(TAG,"checkColumnExists..." + e.getMessage()) ;
}finally{
if(null != cursor && !cursor.isClosed()){
cursor.close() ;
}
}
return result ;
}
这里sqlite_master
是SQLite数据库中的一个内置表,更多了解请点击此处。
但是如果要改变数据结构,比如不要在末尾添加字段,而是在中间添加字段,比如要删除多个字段,添加多个字段。那就需要用到下面的方法。
四个步骤:
- 将要修改的表(person)重命名(为 temp_person)。
- 重新创建新(person)表。
- 将(temp_person)表的数据导入到(person)表。
- 将(temp_person)表删除。
public class MySqliteHelper extends SQLiteOpenHelper {
private String TAG = "MySqliteHelper";
/*表名*/
private final String TABLE_NAME_PERSON = "person";
/*临时表面*/
private final String TABLE_NAME_TEMP_PERSON = "temp_person";
/*id字段*/
private final String VALUE_ID = "_id";
private final String VALUE_NAME = "name";
private final String VALUE_ISBOY = "isboy";
private final String VALUE_AGE = "age";
private final String VALUE_ADDRESS = "address";
/*头像字段*/
private final String VALUE_PIC = "pic";
/*优点*/
private final String VALUE_GOODS = "goods";
/*创建表语句 语句对大小写不敏感 create table 表名(字段名 类型,字段名 类型,…)*/
private final String CREATE_PERSON = "create table " + TABLE_NAME_PERSON + "(" +
VALUE_ID + " integer primary key," +
VALUE_NAME + " text ," +
VALUE_ISBOY + " integer," +
VALUE_AGE + " ingeter," +
VALUE_ADDRESS + " text," +
VALUE_PIC + " blob" +
")";
//=====================更新语句==========================
//建立新的person表(加入了新字段 VALUE_GOODS )
private final String CREATE_NEW_TABLE = "create table " + TABLE_NAME_PERSON + "(" +
VALUE_ID + " integer primary key," +
VALUE_GOODS + " text ,"+
VALUE_NAME + " text ," +
VALUE_ISBOY + " integer," +
VALUE_AGE + " ingeter," +
VALUE_ADDRESS + " text," +
VALUE_PIC + " blob " +
")";
//重命名person表为temp_person表
private final String CREATE_TEMP_TABLE = "alter table "+TABLE_NAME_PERSON+" rename to "+TABLE_NAME_TEMP_PERSON;
//将temp_person表的数据导入新person表(优点是添加的默认数据)
//重点。格式不要错。删减字段都是这个样子。
private final String INSERT_DATA = "insert into "+TABLE_NAME_PERSON +" select "+ VALUE_ID +" , "+
" \" 优点\" "+" , "+
VALUE_NAME+" , "+
VALUE_ISBOY+" , "+
VALUE_AGE+" , "+
VALUE_ADDRESS+" , "+
VALUE_PIC+" "+
" from "+TABLE_NAME_TEMP_PERSON;
//删除temp_person表
private final String DROP_TEMP_TABLE = "drop table "+TABLE_NAME_TEMP_PERSON;
public MySqliteHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
Log.e(TAG, "-------> MySqliteHelper");
}
@Override
public void onCreate(SQLiteDatabase db) {
//创建表
db.execSQL(CREATE_PERSON);
Log.e(TAG, "-------> onCreate");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.e(TAG, "-------> onUpgrade"+" oldVersion = "+oldVersion+" newVersion = "+newVersion);
if(oldVersion != newVersion)
{
switch (newVersion)
{
case 2:
//四大步骤。
db.execSQL(CREATE_TEMP_TABLE);
db.execSQL(CREATE_NEW_TABLE);
db.execSQL(INSERT_DATA);
db.execSQL(DROP_TEMP_TABLE);
break;
}
}
}
}
效果如下:
当然啦这只是最简单步骤,比如现在程序最新数据库版本号为9,但是当前手机安装app为数据库版本号为2,那现在更新安装最新app该怎么办?,如果版本号为3呢?
还是上面的万变不离其中,把需要的数据导过来,不需要的数据删除,变成最新的数据格式,然后再具体逻辑具体分析。所以也可以看出,最开始设计数据库就要设计好,尽量少改动。
sqlite也无非就创建、增、删、改、查、更新。