android sqlite
Android开发过程中可以用sqlite储存结构化数据,如联系人信息之类的。
由于SQLite的操作API是相当底层的,因此开发者需要花费很多时间去手动处理SQL查询语句,一旦数据结构改变就得相应的更新SQL语句,这个过程非常耗时,也容易出现错误。
同时,开发者不得不写很多样板代码来转换SQL语句与数据对象。
现在Google比较推荐的做法就是用Room作为一个访问你数据中信息的抽象层,当然也可以使用一些ORM框架来帮组你处理数据库。
用数据库存储的步骤一般如下:
定义一个Schema和Contract
Schema是一个数据库如何组织的一个正式声明,在你创建数据库的SQL语句中可以反映出来。
一个Contract类是一个定义了URIs,tables和columns等常量的容器。
Contract类允许在同一个包中的所有其他类中使用相同的常量,也就是说你在任何一个位置修改column(列名),它都会在整个代码中传播。
在组织Contract类的时候,可以将那些对整个数据库可见的定义放在类的root 层,然后为每一个table创建一个内部类,每一个内部类列举了table中相应的列名column。
object UserInfoContract {
//实现BaseColumns接口可以继承一个_ID的主键,有利于Android Framework进行处理
object UserInfoEntity : BaseColumns {
const val TABLE_NAME = "user_info"
const val TABLE_NAME_USERNAME = "username"
const val TABLE_NAME_PASSword = "password"
const val TABLE_NAME_LOGIN_TIME_LATEST = "login_time_latest"
}
}
写创建数据库和删除数据库的SQL语句
const val SQL_CREATE_TABLE_USERINFO =
"""
CREATE TABLE ${UserInfoEntity.TABLE_NAME} (
${BaseColumns._ID} integer PRIMARY KEY,
${UserInfoEntity.TABLE_NAME_USERNAME} TEXT,
${UserInfoEntity.TABLE_NAME_PASSWORD} TEXT,
${UserInfoEntity.TABLE_NAME_LOGIN_TIME_LATEST} TEXT
)
"""
const val SQL_DELETE_TABLE_USERINFO =
"""
DROP TABLE IF exists ${UserInfoEntity.TABLE_NAME}
"""
继承SQLiteOpenHelper,自定义数据库创建,更新逻辑
这里会用到上一个步骤写好的SQL语句来创建,删除数据库
class UserInfoDbHelper(context: Context) : SQLiteOpenHelper(context, DB_NAME,null, DB_VERSION){
companion object {
val DB_NAME = "user-info"
val DB_VERSION = 1
}
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(UserInfoContract.SQL_CREATE_TABLE_USERINFO)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL(UserInfoContract.SQL_DELETE_TABLE_USERINFO)
onCreate(db)
}
}
根据实际业务进行增删查检的操作
这里就一个登陆,注册的场景来写一下数据库的操作,主要就是注册和登陆的时候查询是否存在相关账户,如果注册的时候不存在则插入数据库,如果登陆的时候不存在则提示注册,如果登陆的时候查询到用户名与密码不能匹配上,则提示错误。
class LoginDbActivity : APPCompatActivity() {
private lateinit var dbHelper: UserInfoDbHelper
private val projection = arrayOf(
BaseColumns._ID,
UserInfoContract.UserInfoEntity.TABLE_NAME_USERNAME,
UserInfoContract.UserInfoEntity.TABLE_NAME_PASSWORD,
UserInfoContract.UserInfoEntity.TABLE_NAME_LOGIN_TIME_LATEST
)
private val sortOder = "${UserInfoContract.UserInfoEntity.TABLE_NAME_USERNAME} DESC"
override fun onCreate(savedinstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setcontentView(R.layout.activity_login_db)
title = "SQLite Demo"
dbHelper = UserInfoDbHelper(this)
handleClick()
}
private fun handleLogic(present: ((cursor: Cursor) -> Unit), absent: (() -> Unit)) {
if (TextUtils.isempty(et_username.text) || TextUtils.isEmpty(et_password.text)) {
toast("用户名或密码不能为空").show()
return
}
val db = dbHelper.writableDatabase
val selection = "${UserInfoContract.UserInfoEntity.TABLE_NAME_USERNAME} = ?"
val selectionArgs = arrayOf(et_username.text.toString())
doAsync {
val cursor = db.query(
UserInfoContract.UserInfoEntity.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOder
)
if (cursor == null || cursor.count == 0) {
absent()
} else {
present(cursor)
}
}
}
private fun handleClick() {
btn_login_db.onClick {
handleLogic(
present = {
with(it) {
while (moveToNext()) {
val pwd = getString(getColumnIndexOrthrow(UserInfoContract.UserInfoEntity.TABLE_NAME_PASSWORD))
runOnUiThread {
if (et_password.text.toString() == pwd) {
toast("登录成功").show()
finish()
} else {
toast("密码错误").show()
}
}
}
}
},
absent = {
runOnUiThread {
toast("您的账号还没有注册,请先进行注册").show()
}
}
)
}
btn_register_db.onClick {
handleLogic(
present = {
runOnUiThread {
toast("您的账户已经存在,请直接登录").show()
}
},
absent = {
insertDb(dbHelper.readableDatabase)
}
)
}
}
private fun insertDb(db: SQLiteDatabase) {
val values = ContentValues().apply {
put(UserInfoContract.UserInfoEntity.TABLE_NAME_USERNAME, et_username.text.toString())
put(UserInfoContract.UserInfoEntity.TABLE_NAME_PASSWORD, et_password.text.toString())
put(UserInfoContract.UserInfoEntity.TABLE_NAME_LOGIN_TIME_LATEST, system.currenttimemillis().toString())
}
db.insert(
UserInfoContract.UserInfoEntity.TABLE_NAME,
null,
values
)
runOnUiThread {
toast("注册成功").show()
}
}
}
从上面的操作可以知道,其实直接使用SQLite API操作数据库还是比较麻烦的,特别是当需要要更改数据库的Schema的时候,因此如果项目中右大量操作数据库的需求,建议使用稳定的框架。
源码及UI效果
源码
https://github.com/jiangkang/KTools
相关阅读
Sqlite 管理工具 SQLiteDeveloper及破解
Sqlite 管理工具 SQLiteDeveloper及破解 功能特点 表结构设计,数据维护,ddl生成,加密数据库支持,sqlite2,3支持唯一缺憾,收费,有试用
介绍 SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立
SQLite–轻量级数据库 一般常见于安卓客户端。用于存储一些重要数据,因其操作容易、使用简单的好处博得一大批迷妹。今天就来说一
1.下载sqlite3相关文件sqlite3.dll、sqlite3.h(可从http://download.csdn.net/detail/mingxia_sui/5249070下载),添加到工程的根目