• SQLite数据库


    本文所有代码均存放于
    https://github.com/MADMAX110/Starbuzz

    Android世界里,通常可以把数据安全地存放在SQLite数据库中。
    回到之前创建地Starbuzz应用,这个应用允许用户通过一系列屏幕导航查看Starbuzz提供的饮料。接下来让它从SQLite数据库获取数据。

    一、Android使用SQLite数据库持久存储数据

    所有应用都需要存储数据,Android世界中存储数据的主要方法就是使用SQLite数据库。
    1、SQLite是轻量级的。 大多数数据库系统都需要一个特殊的数据库服务器进程才能工作。SQLite并不需要这样一个服务器进程,SQLite数据库实际上就是一个文件。如果没有用到数据库,它不会占用任何处理器时间,这对于移动设备尤其重要。
    2、针对单个用户优化。 只是这个应用要与数据库交互,所以不必使用用户名和口令来识别我们的身份。
    3、它很稳定而且速度很快。 SQLite数据库极其稳定,可以处理数据库事务,这说明你在更新多个数据,突然出现故障,SQLite可以回滚数据。另外读写数据的代码时用优化的C语言编写的,所以不仅速度很快,而且还能减少所需要的处理器功耗。

    Android会自动为各个应用创建一个文件夹来存储应用的数据库。为Starbuzz应用创建数据库时,它会把数据库存储在设备上的以下文件夹中:

    /data/data/com.hfad.starbuzz/databases
    
    • 1

    应用可以在这个文件夹中存储多个数据库,每个数据由两个文件组成。
    第一个文件是数据库文件,与数据库同名,例如这个文件就名为starbuzz。这是SQLite数据库文件。所有数据都存放在这个文件中。
    第二个是journal文件,它也是与数据库同名,另外有一个-journal后缀。它包含对数据库的所有修改。

    Android提供了一些SQLite类
    Android使用了一组类,可以利用这些类管理SQLite数据库,这个工作主要由3类对象来完成。
    1、SQLite帮助器。利用SQLite帮助器可以创建和管理数据库,要扩展SQLiteOpenHelper类来创建SQLite帮助器。
    2、SQLite数据库。 可以利用SQLiteDatabases类访问数据库。这就像JDBC中的SQLConnection。
    3、游标。可以利用Cursor读写数据库。这就像JDBC中的ResultSet。

    二、修改应用来使用数据库

    这里将使用一个SQLite帮助器创建将在Startbuzz应用中使用的SQLite数据库。下面要把Drink Java类替换为一个数据库,所以这个SQLite帮助器要完成下面的工作:
    1、创建数据库
    首先要让SQLite帮助器创建Starbuzz数据库的第一个版本。
    2、创建Drink表,并填充饮料信息
    有了数据库后,可以在这个数据库中创建一个表。表结构要反映当前Drink类的属性,所以这个表应当能存储各个饮料的名字、描述和图像资源ID。然后再在这个表中增加3个饮料。

    SQLite帮助器管理数据库
    SQLiteOpenHelper类可以帮助你创建和维护SQLite数据库。可以把它想成一个个人助理,专门负责处理日常的数据库维护工作。它可以
    1、创建数据库
    第一次安装一个应用时,数据库文件并不存在,SQLite帮助器会确保正确地创建这个数据库文件,要有正确地文件名,而且要安装正确地表结构。
    2、访问数据库
    我们的应用不需要了解数据库文件位置的详细信息,所以SQLite帮助器会提供一个易于使用的数据库对象,这样我们就库在需要利用这个数据库对象访问数据库。
    3、保持数据库井然有序
    数据库结构可能会随时间改变,可以依赖SQLite帮助器将一个老版本的数据库转换为一个闪亮的新版本,包含它需要的所有最新的数据库结构。

    创建SQLite帮助器
    可以写一个类扩展SQLiteOpenHelper类来创建SQLite帮助器。为此必须覆盖onCreate和onUpgrade方法,这两个方法时必不可少的。
    第一次在设备上创建数据库时会调用onCreate方法。这个方法应当包含为应用创建数据库表所需要的代码。
    数据库需要升级时会调用onUpgrade方法,举例来说,如果需要在发布数据库之后对数据库中的表做一些修改,就要在这个方法中完成。
    在com.hfad.starbuzz包中新建一个名为StarbuzzDatabaseHelper的Java类。

    指定数据库
    要创建数据库,SQLite帮助器需要两个信息。
    首先,我们需要为数据库指定一个名字。通过为数据库指定一个名字,可以确保数据库关闭时它还保存在设备上。如果没有指定数据库名,就只会在内存中创建这个数据库,所以一旦数据库关闭,它就会消失。
    需要提供的第二个信息是数据库版本。数据库版本必须是一个整数值,从1开始。SQLite帮助器使用这个版本号来确定数据库是否需要升级。
    指定数据库名和版本时,要把它们传递到SQLiteOpenHelper超类的构造方法。我们指定这个数据库名为starbuzz,因为这是这个数据库的第一个版本,所以版本号为1。

    SQLite的存储形式和查询方式几乎与SQL相同
    创建数据库时会调用onCreate方法,SQLite帮助器负责创建SQLite数据库。第一次需要使用数据库时,会在设备上创建一个空的数据库,然后调用SQLite帮助器的onCreate方法。
    onCreate方法有一个参数,这是一个SQLiteDatabse对象,表示所创建的数据库。
    可以使用SQLiteDatabase execSQL方法在这个数据库上执行SQL命令。这个方法有一个参数,就是你想要执行的SQL命令。

    db.execSQL("CREATE TABLE DRINK (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
           + "NAME TEXT, "
           + "DESCRIPTION TEXT, "
           + "IMAGE_RESOURCE_ID INTEGER)");
    
    • 1
    • 2
    • 3
    • 4

    使用insert方法插入数据
    要在SQLite数据库中的一个表中插入数据,先要指定想在这个表中插入什么值。为此首先创建一个ContentValues对象。ContentValues对象描述一个数据集。通常要为想要创建的每个数据行创建一个新的ContentValues对象。可以使用put方法为其增加数据。这个方法需要数据的名/值对。

        public static void insertDrink(SQLiteDatabase db, String name, String description, int resourceID){
            ContentValues drinkValues = new ContentValues();
            drinkValues.put("NAME", name);
            drinkValues.put("DESCRIPTION", description);
            drinkValues.put("IMAGE_RESOURCE_ID", resourceID);
            db.insert("DRINK", null, drinkValues);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    完整的StarbuzzDatabaseHelper代码:

    package com.hfad.starbuzz;
    
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    
    import androidx.annotation.Nullable;
    
    public class StarbuzzDatabaseHelper extends SQLiteOpenHelper {
    
        private static final String DB_NAME = "starbuzz";
        private static final int DB_VERSION = 1;
    
        public StarbuzzDatabaseHelper(@Nullable Context context) {
            super(context, DB_NAME, null, DB_VERSION);
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE DRINK (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
                    + "NAME TEXT, "
                    + "DESCRIPTION TEXT, "
                    + "IMAGE_RESOURCE_ID INTEGER)");
            insertDrink(db, "Latte", "Espresso and steamed milk", R.drawable.latte);
            insertDrink(db, "Cappuccino", "Espresso, hot milk and steamed-milk foam", R.drawable.cappuccino);
            insertDrink(db, "Filter", "Our best drip coffee", R.drawable.filter);
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    
        }
    
        public static void insertDrink(SQLiteDatabase db, String name, String description, int resourceID){
            ContentValues drinkValues = new ContentValues();
            drinkValues.put("NAME", name);
            drinkValues.put("DESCRIPTION", description);
            drinkValues.put("IMAGE_RESOURCE_ID", resourceID);
            db.insert("DRINK", null, drinkValues);
        }
    }
    
    
    • 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

    三、升级数据库

    SQLite帮助器通过查看版本号来区分这个SQLite数据库是否需要更新,通过在SQLiteOpenHelper超类构造方法中传入版本号,可以在SQLite帮助器中指定数据库的版本。
    使用onUpgrade升级数据库,使用onDowngrade降级数据库。
    假设需要升级数据库,为DRINK表增加一个新列。由于我们希望所有用户都能得到这个修改,所以要确保onCreate和onUpgrade方法都包含这个修改。
    onCreate方法会确保所有新用户得到这个新列,onUpgrade方法会确保所有现有的用户也能得到这个新列。

    package com.hfad.starbuzz;
    
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    
    import androidx.annotation.Nullable;
    
    public class StarbuzzDatabaseHelper extends SQLiteOpenHelper {
    
        private static final String DB_NAME = "starbuzz";
        private static final int DB_VERSION = 2;
    
        public StarbuzzDatabaseHelper(@Nullable Context context) {
            super(context, DB_NAME, null, DB_VERSION);
        }
    
        @Override
        //第一次创建数据库时会调用onCreate
        public void onCreate(SQLiteDatabase db) {
            updateMyDatabase(db, 0, DB_VERSION);
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            updateMyDatabase(db, oldVersion, newVersion);
        }
    
        public static void insertDrink(SQLiteDatabase db, String name, String description, int resourceID){
            ContentValues drinkValues = new ContentValues();
            drinkValues.put("NAME", name);
            drinkValues.put("DESCRIPTION", description);
            drinkValues.put("IMAGE_RESOURCE_ID", resourceID);
            db.insert("DRINK", null, drinkValues);
        }
    
        private void updateMyDatabase(SQLiteDatabase db, int oldVersion, int newVersion){
            if (oldVersion < 1){
                db.execSQL("CREATE TABLE DRINK (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
                        + "NAME TEXT, "
                        + "DESCRIPTION TEXT, "
                        + "IMAGE_RESOURCE_ID INTEGER)");
                insertDrink(db, "Latte", "Espresso and steamed milk", R.drawable.latte);
                insertDrink(db, "Cappuccino", "Espresso, hot milk and steamed-milk foam", R.drawable.cappuccino);
                insertDrink(db, "Filter", "Our best drip coffee", R.drawable.filter);
            }
            if (oldVersion < 2){
                db.execSQL("ALTER TABLE DRINK ADD COLUMN FAVORITE NUMERIC;");
            }
        }
    }
    
    
    • 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
  • 相关阅读:
    Netty系列(一):Springboot整合Netty,自定义协议实现
    记一次 .NET某游戏后端API服务 CPU爆高分析
    Golang学习笔记
    【力扣】从零开始的动态规划
    【JavaEE初阶】线程安全问题
    公链之Sui(前脸书/Meta员工成立的新公链项目)
    js实现一个数据结构——栈
    Zabbix“专家坐诊”第203期问答汇总
    力扣--三数之和
    苹果手机ip地址怎么关闭
  • 原文地址:https://blog.csdn.net/weixin_44014982/article/details/133526788