SQLite数据库基本用法

在Android中,持久化存储的方式有三种:文件、SharedPreferences、数据库;前两种方式适用于保存一些简单的数据和键值对,当需要存储大量复杂的关系型数据的时候,这两种方式就很难应付了。这时候就需要使用到数据库存储了,在Android中使用的是SQLite数据库,这一篇文章,我们来记录下简单的操作:新建数据库、升级数据库,和增删改查操作。

  • 创建数据库

sqlite提供了一个抽象的帮助类:SQLiteOpenHelper;我们需要做的就是继承它,并实现两个抽象方法 onCreate(), onUpgrade():

scss 复制代码
class MySQLiteOpenHelper extend SQLiteOpenHelper {
    MySQLiteOpenHelper(Context context, String dbName, SQLiteDatabase.CursorFactory factory, int version) {
        super()
    }

    onCreate () { 
        //可进行创建表相关逻辑
    }
    onUpgrade(){
        //升级数据库
    }
    
    // 两个重要的实例方法,用于创建/打开 数据库(如果数据库已存在则直接打开,
    否则创建一个新的数据库),并返回一个可对数据库进行读写操作的对象
    SQLiteDatabase getReadableDatabase()
    
    SQLiteDatabase getWritableDatabase()
    
    //这两个方法的区别:
    **当数据库不可写入的时候(如磁盘空间已满),getReadableDatabase() 方法
    返回的对象将以只读的方式去打开数据库,而getWritableDatabase() 方法则将出现异常**。
}

所以,通过调用 SQLiteOpenHelper的实例对象的 getReadableDatabase() 或 getWritableDatabase() 方法就可以创建数据库,数据库文件会存放在 /data/data/包名/databases/ 目录下;此时重写的 onCreate() 方法也会得到执行,通常会在 onCreate() 中做一些创建表的逻辑。

  • 升级数据库

比如在创建数据库并新建BooK表以后,还想在继续增加一个 Category 表,我们只在 onCreate() 中写上建表方法是不行的,因为此时数据库已存在,执行getWritableDatabase() 后不会走到onCreate;

此时需要这么做:

1.在helper类 onCreate 中加上新表的执行; onUpgrade 中 执行onCreate()。(可根据具体情况选择是否使用此方式)

2.新建MySQLiteOpenHelper时,版本号升高

csharp 复制代码
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK); // sql 命令可设置为 "不存在才新建表"
        db.execSQL(CREATE_CATEGORY);// sql 命令可设置为 "不存在才新建表"
    }
    
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // db.execSQL("drop table if exists Book");// 一般不删表,根据业务来
        // db.execSQL("drop table if exists Category");// 一般不删表,根据业务来
        onCreate(db);
    }
    
    // 版本号升高,onUpgrade 才会执行
    dbHelper = MySQLiteOpenHelper(this, "BookStore.db", null, 2);// 升级版本号
    
  • 添加数据
sql 复制代码
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put("name", "zhangsan");
    values.put("author", "zhouguoping");
    values.put("pages", 100);
    values.put("price", 9.9);
    db.insert("Book", null, values);
    
    values.clear();
    
    values.put("name", "lisi");
    values.put("author", "zhouguoping");
    values.put("pages", 120);
    values.put("price", 9.98);
    db.insert("Book", null, values);
    
  • 更新数据
ini 复制代码
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put("price", 199.9);
    db.update("Book", values, "name = ?", new String[] {"zhangsan"}); //将name为zhangsan 的这本书 的价格更新为 199.9;

- 删除数据

arduino 复制代码
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    db.delete("Book", "page > ?", new String[] { "110" });//将页数超过110 的数据删除。

查询数据

query() 方法中各参数 描述 对应SQL部分
table 指定查询的表名 from table_name
columns 指定查询的列名 select column1, column2
selection 指定where 约束的条件 where column = value
selectionArgs 为where中的占位符提供具体的值
groupBy 需要指定group by 的列 group by column
having 对group by 后的结果进一步约束 having column = value
orderBy 指定查询结果的排序方式 order by column1, column2
ini 复制代码
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    Cursor cursor = db.query("Book", null, null, null, null, null, null);
    if (cursor.moveToFirst()) {
        do {
            String name = cursor.getString(cursor.getColumnIndex("name"));
            String author = cursor.getString(cursor.getColumnIndex("author"));
            int pages = cursor.getInt(cursor.getColumnIndex("pages"));
            double price = cursor.getDouble(cursor.getColumnIndex("price"));
        } while(cursor.moveToNext());
    }
    cursor.close();
    

关于group by 和 orderBy 的理解,可以参考这篇文章(blog.csdn.net/weixin_4410...

arduino 复制代码
示例
class MySQLiteOpenHelper extend SQLiteOpenHelper {
    
    public static final String CREATE_BOOK = "create table **if not exists** Book ("
    + "id integer primary key autoincrement,"
    + "name text,"
    + "author text,"
    + "price real,"
    + "pages integer)";
    
    public static final String CREATE_CATEGORY = "create table if not exists Category ("
    + "id integer primary key autoincrement,"
    + "category_name text,"
    + "category_code integer)";
    
    MySQLiteOpenHelper(Context context, String dbName, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, dbName, factory, version)
    }
    
    //如果数据文件已存在,在执行创建数据库方法(getWritableDatabase)时,不会再执行oncreate()
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
        db.execSQL(CREATE_CATEGORY);
    }
    
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //db.execSQL("drop table if exists Book");
        //db.execSQL("drop table if exists Category");
        onCreate(db);
    }
    
}
    
typescript 复制代码
class MainActivity {
    
    private MySQLiteOpenHelper dbHelper;
    
    onCreate() {
        dbHelper = MySQLiteOpenHelper(this, "BookStore.db", null, 1);
        btn.setOnclickListener(
            onClick() {
                dbHelper.getWritableDatabase();// 创建数据库
            }
        );
    }
}

最后:

adb查看数据库或表数据:

1.使用cd 命令进入/data/data/<包名>/databases/ 目录下,使用ls 命令查看目录下的文件;

2.使用sqlite命令打开数据库:sqlite3 BookStore.db

3.查看表中数据:select * from Book

相关推荐
Hrain-AI6 小时前
多 Agent 并行不打架:worktree 隔离与反馈回流落地(附脚本)
网络·数据库·人工智能·架构
净水深流6 小时前
中央厨房冷链技术实践:多温区改造、WMS落地与IoT温控架构
大数据·数据库·人工智能·冷库冷链
l1t7 小时前
测试DuckDB 2.1的match_recognize模式匹配语句
数据库·duckdb
IpdataCloud8 小时前
AI智能体调用工具怎么核验来源IP?归属地、网络类型与代理风险识别(含Python代码)
数据库·python·tcp/ip
曹牧8 小时前
Java:SQL 注入漏洞
数据库
程序员JerrySUN8 小时前
Jetson Edge AI 实战01:Nano、Xavier、Orin 怎么选?Jetson 硬件选型详解【视频讲解】
java·数据库·redis·安全·mybatis
oradh9 小时前
Oracle Undo问题总结(ORA-600 [4xxx] 系列错误)
数据库·oracle
达梦数据9 小时前
DMDRS辅助表生成规则与作用
数据库·oracle
‎ദ്ദിᵔ.˛.ᵔ₎9 小时前
MySQL 表约束
数据库·mysql
Doris__HE9 小时前
【元脑服务器NF5476G7-NF5476M7技术规格分享】
运维·服务器·网络·数据库·性能优化