当前位置:网站首页>Android原生数据库的基本使用和升级

Android原生数据库的基本使用和升级

2022-07-04 19:44:00 Just_Paranoid

android原生数据库使用
SQLiteOpenHelper:数据库的创建、更新的操作对象
SQLiteDatabase:执行数据的增删改查的操作对象
SQLiteStatement:SQL执行的操作对象

sqlite内部实现
插入:SQLiteStatement.executeInsert
更新、删除:SQLiteStatement.executeUpdateDelete
查询:SQLiteCursorDriver.query

性能优化
1、预编译SQL语句,重复的操作使用SQLiteStatement
2、使用事务,做数据更新操作时提高性能
3、及时关闭Cursor
4、耗时异步化

基本使用

//创建数据库:继承系统的SQLiteOpenHelper,在onCreate和onUpgrade中实现数据库的创建以及更新
public class MyDbHelper extends SQLiteOpenHelper {
    

    private static final String TAG = "MyDbHelper";
    private static final String DB_NAME = "my.db";
    private static final int DB_VERSION = 1;

    public MyDbHelper(@Nullable Context context) {
    
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    
        // 创建数据库
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
        // 更新数据库
    }
}

//2.数据库管理:对数据库的操作使用单例进行管理,用于获取一个可读可写的SQLiteDatabase
public class MyDbManage {
    

    private static MyDbManage myDbManage;
    private final MyDbHelper myDbHelper;

    private MyDbManage(Context context) {
    
        myDbHelper = new MyDbHelper(context);
    }

    public static MyDbManage getInstance(Context context) {
    
        if (myDbManage == null) {
    
            synchronized (MyDbManage.class) {
    
                if (myDbManage == null) {
    
                    myDbManage = new MyDbManage(context);
                }
            }
        }
        return myDbManage;
    }

    /** * 获取一个可写的数据库 * * @return SQLiteDatabase */
    public SQLiteDatabase getWritableDatabase() {
    
        return myDbHelper.getWritableDatabase();
    }
}

//3.数据库操作:针对每个实体,建议单独创建操作数据的DAO,更方便维护
public class MyDaoSample {
    
    public static final String TABLE_NAME = "user";// 表名
    public static final String USER_NAME = "username";
    public static final String AGE = "age";
    public static final String SEX = "sex";

    private static MyDaoSample myDaoSample;
    private final SQLiteDatabase mDb;

    private MyDaoSample() {
    
        MyDbManage dbManage = MyDbManage.getInstance(CoreApplication.mApp);
        mDb = dbManage.getWritableDatabase();
    }

    public static MyDaoSample getInstance() {
    
        if (myDaoSample == null) {
    
            synchronized (MyDaoSample.class) {
    
                if (myDaoSample == null) {
    
                    myDaoSample = new MyDaoSample();
                }
            }
        }
        return myDaoSample;
    }

    public void insert() {
    
        ContentValues values = new ContentValues();
        values.put(USER_NAME, "susu");
        values.put(AGE, 18);
        mDb.beginTransaction();
        mDb.insert(TABLE_NAME, null, values);
        mDb.setTransactionSuccessful();
        mDb.endTransaction();
    }
}

Android原生数据库的升级更新OnUpgrade

注意点:
1.修改数据库版本号
2.重写OnUpgrade方法

//DBOpenHelper数据库类
public class DBOpenHelper extends SQLiteOpenHelper

//数据库版本号
private static final int DB_VERSION = 2;

//初始化
private DBOpenHelper(Context context) {
    
        super(context, DB_NAME, null, DB_VERSION);
    }

//升级数据库
@Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
        if (oldVersion == 1) {
    
            db.beginTransaction();
            try {
    
                // upgrade note table column
                db.execSQL("ALTER TABLE " + NOTE_TABLE_NAME + " ADD COLUMN " + NOTE_IS_TOP_ID + " int;");
                db.execSQL("ALTER TABLE " + NOTE_TABLE_NAME + " ADD COLUMN " + NOTE_TOP_DATE_ID + " long;");
                db.execSQL("ALTER TABLE " + NOTE_TABLE_NAME + " ADD COLUMN " + NOTE_IS_CONTAIN_VOICE_ID + " int;");
                db.execSQL("ALTER TABLE " + NOTE_TABLE_NAME + " ADD COLUMN " + NOTE_PIC_PATH_ID + " text;");

                // upgrade folder table column
                db.execSQL("ALTER TABLE " + FOLDER_TABLE_NAME + " ADD COLUMN " + FOLDER_IS_TODO + " int;");
               
                //insert default values 
                String travel = mContext.getString(R.string.folder_travel);
        String life = mContext.getString(R.string.folder_life);
        String work = mContext.getString(R.string.folder_work);
        db.execSQL("INSERT INTO "
                + FOLDER_TABLE_NAME
                + " VALUES ('1','"+travel+"', '0', '0','0');");
        db.execSQL("INSERT INTO "
                + FOLDER_TABLE_NAME
                + " VALUES ('2','"+life+"', '0', '0','0');");
        db.execSQL("INSERT INTO "
                + FOLDER_TABLE_NAME
                + " VALUES ('3','"+work+"', '0', '0','0');");

                // create todo table
                db.execSQL(" CREATE TABLE IF NOT EXISTS " + TODO_TABLE_NAME + " ( "
                        + ID + " integer primary key autoincrement , "
                        + TODO_CONTENT + " text , "
                        + TODO_IS_IMPORTANT + " int , "
                        + TODO_TIME + " long , "
                        + TODO_REPEAT + " int , "
                        + TODO_IS_COMPLETE + " int , "
                        + TODO_IS_DELAY + " int , "
                        + TODO_IS_DELETED + " int , "
                        + TODO_PARENT_FOLDER_ID + " int , "
                        + TODO_DATE + " long);");

                db.setVersion(DB_VERSION);
                db.setTransactionSuccessful();
            } finally {
    
                db.endTransaction();
            }
        }
    }

// 如果数据库文件不存在,只有onCreate()被调用(该方法在创建数据库时被调用一次)
public abstract void onCreate(SQLiteDatabase db);
// 如果数据库文件存在,会调用onUpgrade()方法升级数据库,并更新版本号。
public abstract void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion);

OnCreate : 如果数据库文件不存在,SQLiteOpenHelper在创建数据库文件,打开数据库这个数据库后,调用onCreate()方法,在该方法中一般需要创建表、视图等组件。在创建前数据库一般是空的,因此不需要先删除数据库中相关的组件。

OnUpgrade : 当系统在构造SQLiteOpenHelper类的对象时,如果发现版本号不一样,就会自动调用onUpgrade函数,让你在这里对数据库进行升级。

新版本号和老版本号都会作为onUpgrade函数的参数传进来,便于开发者知道数据库应该从哪个版本升级到哪个版本。升级完成后,数据库会自动存储最新的版本号为当前数据库版本号。

需要对SQLite数据库的结构进行升级:
SQLite提供了ALTER TABLE命令,允许用户重命名或添加新的字段到已有表中,但是不能从表中删除字段。
并且只能在表的末尾添加字段,比如,为 Student添加两个字段:
1 ALTER TABLE Student ADD COLUMN UserPhone VARCHAR;
2 ALTER TABLE Student ADD COLUMN UserNickName VARCHAR;

如果遇到复杂的修改操作,比如在修改的同时,需要进行数据的转移,那么可以采取在一个事务中执行如下语句来实现修改表的需求。

  1. 将表名改为临时表
    ALTER TABLE Student RENAME TO __temp__Student;

  2. 创建新表
    CREATE TABLE Student (UserId VARCHAR(32) PRIMARY KEY ,UserName VARCHAR(32) NOT NULL ,UserAddress VARCHAR(16) NOT NULL);

  3. 导入数据  
    INSERT INTO Student SELECT UserId, “”, UserAddress FROM __temp__Student;
    或者  
    INSERT INTO Student() SELECT UserId, “”, UserAddress FROM __temp__Student;

  • 注意 双引号”” 是用来补充原来不存在的数据的
  1. 删除临时表  
    DROP TABLE __temp__Student;

通过以上四个步骤,就可以完成旧数据库结构向新数据库结构的迁移,并且其中还可以保证数据不会应为升级而流失。
  当然,如果遇到减少字段的情况,也可以通过创建临时表的方式来实现。

相关参考
https://blog.csdn.net/linglingchenchen/article/details/123632277

原网站

版权声明
本文为[Just_Paranoid]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_44008788/article/details/125545742