1. SQLite数据库资料学习
2. 基本概念
- SQLite是什么?
SQLite是一个轻量级的关系型数据库,运算速度快,占用资源少,很适合在移动设备上使用, 不仅支持标准SQL语法,还遵循ACID(数据库事务)原则,无需账号,使用起来非常方便!
- 为什么要用SQLite?
在Android实际开发中,数据的存储是必不可少的一个环节。当我们存储数据少量,或一些简单的数据时(如:记住密码),可以使用
SharedPreference
来实现,但当我们存储一些复杂的数量类型时(如:购物车,订单等),这时使用SharedPreference
就无法满足业务的需求了,所以SQLite数据库的出现,就解决了这个问题
- SQLite有什么特点?
SQLite是一个轻量级的关系型数据库,运算速度快,占用资源少。适合存储比较复杂的数据类型
3. 重要的几个相关类
- SQLiteOpenHelper:抽象类,我们通过继承该类,然后重写数据库创建以及更新的方法, 我们还可以通过该类的对象获得数据库实例,或者关闭数据库!
- SQLiteDatabase:数据库访问类:我们可以通过该类的对象来对数据库做一些增删改查的操作
- Cursor:游标,有点类似于JDBC里的resultset,结果集!可以简单理解为指向数据库中某 一个记录的指针!
4. 代码示例实现增,删,改,查
- 创建用户表
- 使用SQLite数据库,必须继承SQLiteOpenHelper
- 编写类名为UserDbHelper 继承SQLiteOpenHelper
class UserDbHelper(
context: Context?, name: String?, factory: SQLiteDatabase.CursorFactory?, version: Int
) : SQLiteOpenHelper(context, name, factory, version) {
override fun onCreate(db: SQLiteDatabase?) {
//创建表
db?.execSQL(
"create table user_table(_id integer primary key autoincrement, " +
"username text," + //用户名
"password text," + //密码
"gender text," + //性别
"likes text" + //爱好
")"
)
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
}
//创建单例,防止重复创建,给予外部调用
companion object {
private var sUserDbHelper: UserDbHelper? = null
//数据库名
private const val DB_NAME = "user.db"
//版本号
private const val VERSION = 1
//null,表示使用默认的游标工厂
private val FACTORY = null
@Synchronized
fun getInstance(context: Context): UserDbHelper {
if (null == sUserDbHelper) {
sUserDbHelper = UserDbHelper(context, DB_NAME, FACTORY, VERSION)
}
return sUserDbHelper!!
}
}
//ToDO 这里可以添加增删改查的方法
}
- 定义UserInfo数据模型(也叫实体类)
温馨提示: 建表中定义了什么样的字段,那么实体对象就应该定义有什么样的属性字段(保持一一对应的关系)
data class UserInfo (
val user_id: Int, //用户id
val username: String, //用户名
val password: String, //密码
val gender: String, //性别
val likes: String, //爱好
)
这里注意,建表的主键为
_id
,这里用户表用的user_id
,在后续编写sql语句的时候,_id
的值会赋值给user_id
- 编写增,删,改,查的方法
- 注册
实际逻辑就是新增
/**
* 注册 (就是新增的意思)
*/
fun registerUser(username: String, password: String, gender: String, likes: String): Int {
//获取可写数据库
val db = this.writableDatabase
val values = ContentValues()
//插入数据
values.put("username", username)
values.put("password", password)
values.put("gender", gender)
values.put("likes", likes)
val insert = db.insert("user_table", null, values).toInt()
//关闭数据库
db.close()
return insert
}
- 登录
实际逻辑就是根据用户名查询
/**
* 登录 (就是根据用户名查询的意思)
*/
@SuppressLint("Range")
fun loginUser(username: String): UserInfo? {
val db = this.writableDatabase
val cursor = db.query(
"user_table",
arrayOf("_id", "username", "password", "gender", "likes"),
"username=?",
arrayOf(username),
null,
null,
null
)
var userInfo: UserInfo? = null
if (cursor.moveToNext()) {
val _id = cursor.getInt(cursor.getColumnIndex("_id"))
val username = cursor.getString(cursor.getColumnIndex("username"))
val password = cursor.getString(cursor.getColumnIndex("password"))
val gender = cursor.getString(cursor.getColumnIndex("gender"))
val likes = cursor.getString(cursor.getColumnIndex("likes"))
userInfo = UserInfo(_id, username, password, gender, likes)
}
//关闭游标
cursor.close()
//关闭数据库
db.close()
return userInfo
}
- 获取所有注册用户
实际逻辑就是查寻用户表的所有数据
,跟登录逻辑差不多,登录是根据用户名查询当前用户数据,返回的是一个UserInfo对象,获取注册用户,查询的是所有用户数据,返回的是一个UserInfo对象集合
/**
* 查询所有用户
*/
@SuppressLint("Range")
fun getAllUsers(): List<UserInfo> {
val db = this.writableDatabase
val cursor = db.query(
"user_table",
arrayOf("_id", "username", "password", "gender", "likes"),
null,
null,
null,
null,
null
)
val userList = mutableListOf<UserInfo>()
while (cursor.moveToNext()) {
val _id = cursor.getInt(cursor.getColumnIndex("_id"))
val username = cursor.getString(cursor.getColumnIndex("username"))
val password = cursor.getString(cursor.getColumnIndex("password"))
val gender = cursor.getString(cursor.getColumnIndex("gender"))
val likes = cursor.getString(cursor.getColumnIndex("likes"))
userList.add(UserInfo(_id, username, password, gender, likes))
}
//关闭游标
cursor.close()
//关闭数据库
db.close()
return userList
}
- 修改
注意:修改应该根据唯一主键_id(对应用户的user_id)来修改,确保修改的唯一性
,如果根据用户名修改,有可能出错,因为用户名可能存在同名的情况
/**
* 更新用户信息
*/
fun updateUser(
user_id: Int,
username: String,
password: String,
gender: String,
likes: String
): Int {
//获取可写数据库
val db = this.writableDatabase
val values = ContentValues()
values.put("username", username)
values.put("password", password)
values.put("gender", gender)
values.put("likes", likes)
val update = db.update("user_table", values, "_id=?", arrayOf(user_id.toString()))
//关闭数据库
db.close()
return update
}
- 删除
注意:删除应该根据唯一主键_id(对应用户的user_id)来删除,确保删除的唯一性
,如果根据用户名删除,有可能出错,因为用户名可能存在同名的情况
/**
* 删除用户
*/
fun deleteUser(user_id: Int): Int {
val db = this.writableDatabase
val delete = db.delete("user_table", "_id=?", arrayOf(user_id.toString()))
//关闭数据库
db.close()
return delete
}
5. 如实调用?
在UserDbHelper 类里面,提供了一个获取数据库实例的方法,叫getInstance()方法,这个方法的作用就是获取当前类的对象,从而调用该类里面定义的增,删,改,查的方法
- 如调用新增(注册)
//注册
findViewById<Button>(R.id.btn_register).setOnClickListener {
val row = UserDbHelper.getInstance(this)
.registerUser("John", "123456", "男", "篮球,足球,游泳")
if (row > 0) {
Toast.makeText(this, "注册成功", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "注册失败", Toast.LENGTH_SHORT).show()
}
}
//登录
findViewById<Button>(R.id.btn_login).setOnClickListener {
val user = UserDbHelper.getInstance(this).loginUser("John")
Toast.makeText(this, user.toString(), Toast.LENGTH_SHORT).show()
}
//更新
findViewById<Button>(R.id.btn_update).setOnClickListener {
val row = UserDbHelper.getInstance(this).updateUser(1, "zsan", "12345678", "女", "篮球")
if (row > 0) {
Toast.makeText(this, "更新成功", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "更新失败", Toast.LENGTH_SHORT).show()
}
}
//删除
findViewById<Button>(R.id.btn_delete).setOnClickListener {
val row = UserDbHelper.getInstance(this).deleteUser(1)
if (row > 0) {
Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "删除失败", Toast.LENGTH_SHORT).show()
}
}
//查询所有
findViewById<Button>(R.id.btn_getAll).setOnClickListener {
val userList = UserDbHelper.getInstance(this).getAllUsers()
}
row 代表插入数据是否成功的状态,返回类型为Int类型。只要这个值大于0,就表示该条数据添加(插入)成功,否者就是失败