Android SQLite 数据库


概述

SQLite 是一款轻量级的关系型数据库,它的运算速度非常快,占用资源非常少,因此特别适合在移动设备使用。SQLite 不仅支持标准的 SQL 语法,还遵循数据库的 ACID 事务。而 SQLite 又比一般的数据库要简单许多,甚至不需要设置用户名和密码就可以使用


创建数据库

Android 提供了一个 SQLiteOpenHelper 帮助类,用以对数据库进行创建和升级。

SQLiteOpenHelper 是一个抽象类,有两个抽象方法:onCreate()onUpgrade(),我们需要重写这两个方法,然后分别在这两个方法中实现创建和升级数据库的逻辑

class MyDatabaseHelper(context: Context?, name: String?, version: Int) : SQLiteOpenHelper(context, name, null, version) {
    
    private val createBook = "create table Book (" + 
            "id integer primary key autoincrement," +
            "author text," + 
            "price real," + 
            "pages integer," + 
            "name text)"

    override fun onCreate(db: SQLiteDatabase) {
        db.execSQL(createBook)
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        
    }
}

可以看到,我们把建表语句定义成一个字符串变量,然后在 onCreate() 方法中调用 SQLiteDatabaseexecSQL() 方法去执行这条建表语句

我们在创建一个按钮,并为其添加点击事件

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val dbHelper = MyDatabaseHelper(this, "Book.db", 1)
        createDatabase.setOnClickListener {
            dbHelper.writableDatabase
        }
    }
}

onCreate() 方法中构建一个 MyDatabaseHelper 对象,并通过构造函数将数据库名指定为 Book.db,版本号指定为 1,然后在按钮点击事件里调用 getWritableDatabase() 方法。当第一次点击时,会检查当前程序中并没有 Book.db 这个数据库,于是就会调用 MyDatabaseHelperonCreate() 方法创建表。再次点击,因为数据库已经存在,就不会重复创建


升级数据库

目前我们的数据库里有一张 Book 表,如果我们想再添加一张 Category 表的话,不能像创建数据库一样直接执行 onCreate() 方法,因为数据库已经存在了。这时候就必须借助 onUpgrade() 方法

class MyDatabaseHelper(context: Context?, name: String?, version: Int) : SQLiteOpenHelper(context, name, null, version) {

    private val createBook = "create table Book (" +
            "id integer primary key autoincrement," +
            "author text," +
            "price real," +
            "pages integer," +
            "name text)"

    private val createCategory = "create table Category (" +
            "id integer primary key autoincrement," +
            "category_name text," +
            "category_code integer)"

    override fun onCreate(db: SQLiteDatabase) {
        db.execSQL(createBook)
        db.execSQL(createCategory)
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        db.execSQL("drop table if exists Book")
        db.execSQL("drop table if exists Category")
        onCreate(db)
    }
}

我们在 onUpgrade() 方法执行了两条 DROP 语句,然后再调用 onCreate() 方法重新创建。为了让 onUpgrade() 方法执行,我们需要传入比当前版本大的数,之前传的是 1,现在传入 2,就能执行了

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val dbHelper = MyDatabaseHelper(this, "Book.db", 2)
        createDatabase.setOnClickListener {
            dbHelper.writableDatabase
        }
    }
}

增删改查

Android 提供了一系列辅助方法,让你不用编写 SQL 也能完成 CRUD 操作

1. 添加数据
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val dbHelper = MyDatabaseHelper(this, "Book.db", 2)
    ...
    addData.setOnClickListener {
        val db = dbHelper.writableDatabase
        val values = ContentValues().apply {
            // 组装数据
            put("name", "The Da Vinci Code")
            put("author", "Dan Brown")
            put("pages", 454)
            put("price", 16.96)
        }
        // 参数说明:
        // 1. 表名
        // 2. 用于在未指定添加数据的情况下给某些可为空的列自动赋值 NULL
        // 3. ContentValues 对象
        db.insert("Book", null, values)
    }
}
2. 更新数据
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val dbHelper = MyDatabaseHelper(this, "Book.db", 2)
    ...
    updateData.setOnClickListener {
        val db = dbHelper.writableDatabase
        val values = ContentValues()
        values.put("price", 16.96)
        // 参数说明:
        // 1. 表名
        // 2. ContentValues 对象,把更新数据组装进去
        // 3、4. 用于约束更新某一行或某几行的数据,不指定默认更新所有行
        db.update("Book", values"name = ?", arrayOf("The da Vinci Code"))
    }
}
3. 删除数据
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val dbHelper = MyDatabaseHelper(this, "Book.db", 2)
    ...
    deleteData.setOnClickListener {
        val db = dbHelper.writableDatabase
        // 参数说明:
        // 1. 表名
        // 2、3. 用于约束删除某一行或某几行的数据,不指定默认删除所有行
        db.delete("Book","pages > ?", arrayOf("500"))
    }
}
4. 查询数据
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val dbHelper = MyDatabaseHelper(this, "Book.db", 2)
    ...
    queryData.setOnClickListener {
        val db = dbHelper.writableDatabase
        // 参数说明
        // 1. 指定查询的表名
        // 2. 指定查询的列名
        // 3. 指定 where 约束条件
        // 4. 为 where 中占位符提供具体的值
        // 5. 指定需要 group by 的列
        // 6. 对 group by 的结果进一步约束
        // 7. 指定查询结果的排序方式
        val cursor = db.query("Book", null, null, null, null, null, null)
        if (cursor.moveToFirst()) {
            do {
                // 遍历 Cursor 对象,取出数据并打印
                val name = cursor.getString(cursor.getColumnIndex("name"))
                val author = cursor.getString(cursor.getColumnIndex("author"))
                val pages = cursor.getString(cursor.getColumnIndex("pages"))
                val price = cursor.getString(cursor.getColumnIndex("price"))
                Log.d("MainActivity", "book name is $name")
                Log.d("MainActivity", "book author is $author")
                Log.d("MainActivity", "book pages is $pages")
                Log.d("MainActivity", "book price is $price")
            } while (cursor.moveToNext())
        }
        cursor.close()
    }
}

除了使用 Android 提供的 API,我们也可以自己编写 SQL 语句去执行

// 参数处写 SQL 语句
db.execSQL("......")

使用事务

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val dbHelper = MyDatabaseHelper(this, "Book.db", 2)
    ...
    replaceData.setOnClickListener {
        val db = dbHelper.writableDatabase
        // 开启事务
        db.beginTransaction()
        try {
            db.delete("Book", null, null)
            if (true) {
                // 手动抛出异常,让事务失败
                throw NullPointerException()
            }
            val values = ContentValues().apply {
                put("name", "Game of Thrones")
                put("author", "George Martin")
                put("pages", 720)
                put("price", 20.85)
            }
            db.insert("Book", null, values)
            // 事务已经成功执行
            db.setTransactionSuccessful()
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            // 结束事务
            db.endTransaction()
        }
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值