数据存储--数据库

数据库语言:
创建新表:

create table tablename(
    column1 type [not null] [primary key] autoincrement,
    column2 type [not null],
....)

数据库创建:

通过SQLiteOpenHelper抽象类来生成,需要建一个类来继承SQLiteOpenHelper,实现他的构造方法和抽象方法

public class MyDatabaseHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME  = "PeopleData.db";

    private static MyDatabaseHelper sSingleton;

    public static synchronized MyDatabaseHelper getInstance(Context context) {
        if (sSingleton == null){
            sSingleton = new MyDatabaseHelper(context, DATABASE_NAME, null, 1 );
        }
        return sSingleton;
    }

    public static final String CREATE_PEOPLE = "create table if not exists People ("
            + " id integer primary key autoincrement, "
            + " name text, "
            + " sex text, "
            + " age integer) " ;

    public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL(CREATE_PEOPLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    }
}

SQLiteOpenHelper的构造方法:
public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) ;
第一参数为context;第二个参数为数据库名;第三个参数允许我们在出巡数据返回一个自定义的Cursor,一般传入null;第四个参数为数据库版本号;
需要实现的两个抽象方法:
onCreate:创建表语句可以在这里面写
onUpgrade:更新数据库使用,前提是已经存在了一个相同的数据库,需要新加表,或者原来的表字段要修改啥的,就在这里面写。
两个重要的实例方法:
getReadableDatabase、getWriteableDatabase:都可以创建或者打开一个数据库,如果数据库已存在则直接打开
获取SQLiteOpenHelper实例的方法:
getInstance方法为直接获取一个SQLiteOpenHelper实例,使用单例模式可防止重复创建SQLiteOpenHelper实例

数据库升、降级:

SQLite数据库的数据升级与降级的问题主要是要关注SQLiteOpenHelper这一个抽象的类,主要的三个方法:

  1. onCreate()该方法是在你没有安装过(第一次运行)的时候执行,这时可以在这个函数中完成初始数据表的创建
  2. onUpgrade()该方法是在你安装过的情况下,对数据继续更新的时候执行,这时可以在这个函数完成数据库版本升级带来的旧版本的兼容问题,以及数据迁移问题。
  3. onDowngrade()该方法是在现逆向降级(如应用由版本号4降级安装版本号为3的包)时必须重写的方法,如果应用降级覆盖安装时没有重写该方法则会崩溃。

数据库升级版本2.0:

public class MyDatabaseHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME  = "PeopleData.db";

    private static MyDatabaseHelper sSingleton;

    public static synchronized MyDatabaseHelper getInstance(Context context) {
        if (sSingleton == null){
            sSingleton = new MyDatabaseHelper(context, DATABASE_NAME, null, 1 );
        }
        return sSingleton;
    }

    public static final String CREATE_PEOPLE = "create table if not exists People ("
            + " id integer primary key autoincrement, "
            + " name text, "
            + " sex text, "
            + " age integer) " ;

   public static final String CREATE_CATEGORY = "create table if not exists Category ("
            + " id integer primary key autoincrement, "
            + " category_name text, "
            + " category_code text) " ;

    public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL(CREATE_PEOPLE);
        sqLiteDatabase.execSQL(CREATE_CATEGORY);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        sqLiteDatabase.execSQL("drop table if exists People");
        sqLiteDatabase.execSQL("drop table if exists Category");
        onCreate(sqLiteDatabase);
    }
}

数据库版本降级1.0:
大概步骤就是:

  1. 备份当前版本数据库表  主要是为了后面的copy
  2. 修改当前数据库表名   主要是为了降级的表名称
  3. 创建降级版本数据库表,并将当前数据copy到降级表中    主要是为了提高用户黏度
  4. 删除备份表       主要是为了下次降级不会建表冲突

然后就是一个很重要的操作了,那就是,如果当你降级不成功怎么办?
我们的解决方案也很简单,那就是加一个try/catch() 来捕获这个异常,然后创建对应表的数据结构

public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        try {
            //第一、先把t_message 未来的表,改名
            String rename_sql = "alter table t_message rename to t_message_bak";
            db.execSQL(rename_sql);
            Log.i("down", "1.改名成功");
            //第二、建立1.0的表结构
            String sql_message = "create table t_message (id int primary key,userName varchar(50),lastMessage varchar(50),datetime  varchar(50))";
            db.execSQL(sql_message);
            Log.i("down", "2.建立1.0表结构成功");
            //第三、把备份的数据,copy到 新建的1.0的表
            String sql_copy = "insert into t_message select id,userName,lastMessage,datetime from t_message_bak";
            db.execSQL(sql_copy);
            Log.i("down", "3.copy到用户数据到 1.0的表");
            //第四、把备份表drop掉
            String drop_sql = "drop table if exists t_message_bak";
            db.execSQL(drop_sql);
            Log.i("down", "4.把备份表drop掉");
            
        } catch (Exception e) {
            //失败
            Log.i("Log", "降级失败,重新创建");
            String sql_drop_old_table = "drop table if exists t_message";
            String sql_message = "create table t_message (id int primary key,userName varchar(50),lastMessage varchar(50),datetime  varchar(50))";
            String sql_init_1 = "insert into t_message values (1,'小明','内容1','昨天')";
            String sql_init_2 = "insert into t_message values (2,'小红','内容2','今天')";
            db.execSQL(sql_drop_old_table);
            db.execSQL(sql_message);
            db.execSQL(sql_init_1);
            db.execSQL(sql_init_2);
        }
    }

数据库增删检查:(数据库的增删改查是耗时操作,所以必须写在子线程中)

增:

ContentValues values = new ContentValues();
values.put("name", name);
values.put("sex", sex);
values.put("age", age);
SQLiteDatabase db = mDbHelper.getWritableDatabase();
db.insert("People", null, values);

删:

db.insert(TABLE_NAME_PEOPLE, "age > ", new String[]{"500"});

改:

ContentValues values = new ContentValues();
values.put("age", 65);
db.update("People", values, "name =  ", new String[]{"David"});   //修改David的年龄

查:

Cursor cursor = db.query(“People”, null, null, null, null, null, null);
String name = cursor.getString(cursor.getColumnIndex(“name”));
cursor.close();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值