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


    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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    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();
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    // 如果数据库文件不存在,只有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

  • 相关阅读:
    【贪心算法】 55. 跳跃游戏
    Python重试库 Tenacity 推荐
    引爆用户参与:消息重弹,让您的推送不再被忽略
    我更看好开源大模型的发展前景
    qt人员管理模块(模块化程序)功能块复制直接使用不冲突
    国家省、市、县、镇/街道地址
    原子核内的相互作用
    libusb系列-007-Qt下使用libusb1.0.26源码
    实现zotero星标功能且可以排序
    一文讲明 Spring 的使用 【全网超详细教程】
  • 原文地址:https://blog.csdn.net/weixin_44008788/article/details/125545742