关于Android数据持久层SQLite数据库中的GreenDao和ROOM的使用
Android系统是目前来说,最热门的系统之一,市场份额高达70%,也就是说,十个人中间,有七个人都在使用Android系统。而数据保存,在Android的开发中显得尤其重要,Android虽然提供了一个轻量级的数据库--SQLite,但是使用起来不是很方便,特别是对于不擅长SQL语句的同学,更是一场极大的考验,从而增加了学习成本。本文将介绍两种操作数据库的第三方组件(GreenDao和Room)
目录
GreenDao的使用
GreenDao是一个ORM框架,在room没有出来之前,一度是开发者心中最火的框架,从读取速度和其它方面来说,远胜于其它架构。详细请看greenDao官方文档
1.引入GreenDao依赖
目前的最新版本是3.3.0,小编也是比较喜欢最新的东西。
首先在project的build.gradle脚本文件添加greenDao插件
// GreenDao插件
classpath 'org.greenrobot:greendao-gradle-plugin:3.3.0'
再在app下的build.gradle脚本文件中注入依赖
apply plugin: 'org.greenrobot.greendao'
//GreenDao依赖添加
implementation 'org.greenrobot:greendao:3.3.0'
再在app下的build.gradle脚本文件中确定数据库版本以及dao路径
greendao {
schemaVersion 2 //当前数据库版本
daoPackage 'com.yang.daodemo.greenDao'//数据库全路径(自定义)
targetGenDir 'src/main/java'//存放位置
/* //设置为true以自动生成单元测试。
generateTests false*/
}
我们这样就完成了一个greendao的依赖
2.创建数据层
建立一个javabean相当于数据库中的表结构
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Keep;
@Entity
public class DataBean {
@Id(autoincrement = true)
Long rid;
String name;
@Keep
public DataBean( String name) {
// this.rid = rid;
this.name = name;
}
@Keep
public DataBean() {
}
@Keep
public DataBean(Long rid, String name) {
this.rid = rid;
this.name = name;
}
@Keep
public Long getRid() {
return this.rid;
}
@Keep
public void setRid(Long rid) {
this.rid = rid;
}
@Keep
public String getName() {
return this.name;
}
@Keep
public void setName(String name) {
this.name = name;
}
}
我们清晰的可以看到这个实体类是采用注入的方式来实现的,虽然kotlin语言比Java语言精简的多,但是@Entity注解并不支持kotlin,以后greendao可能会改进,这也是选择这个库最重要的因素之一,有人维护且开源。嘻嘻。接下来我们就要用kotlin编程了哟,小伙伴们请看。
3.创建业务逻辑层
import android.content.Context
import com.yang.daodemo.greenDao.DaoMaster
import com.yang.daodemo.greenDao.DaoSession
object DbManager {
private lateinit var mDaoMaster: DaoMaster
private lateinit var mDaoSession: DaoSession
fun initDb(context: Context) {
//创建数据库
val devOpenHelper = DaoMaster.DevOpenHelper(context, "test.db", null)
mDaoMaster = DaoMaster(devOpenHelper.writableDatabase)
//生成可操作数据库的对象
mDaoSession = mDaoMaster.newSession()
}
fun getDaoSession(): DaoSession {
return mDaoSession
}
fun getDataDao() = DataDao()
}
我们先创建一个管理器,用来初始化greendao,同时定义两个对外的接口,以便于后期我们的调用,减少代码的耦合度。
我们现在来实现具体的业务逻辑
import com.yang.daodemo.greenDao.data.DataBean
import java.lang.Exception
class DataDao {
fun add(data: DataBean): Boolean {
return try {
DbManager.getDaoSession().dataBeanDao.insertOrReplace(data)
true
} catch (e: Exception) {
false
}
}
fun queryAll(): List<DataBean> {
return DbManager.getDaoSession().dataBeanDao.loadAll()
}
fun update(data: DataBean):Boolean{
return try {
DbManager.getDaoSession().dataBeanDao.update(data)
true
}catch (e:Exception){
false
}
}
fun deleteById(id: Long): Boolean {
return try {
DbManager.getDaoSession().dataBeanDao.deleteByKey(id)
true
} catch (e: Exception) {
false
}
}
fun clear(): Boolean {
return try {
DbManager.getDaoSession().dataBeanDao.deleteAll()
true
} catch (e: Exception) {
false
}
}
}
4.增删改查
现在我们在activity中实现增删改查
import android.database.sqlite.SQLiteDatabase
import android.os.Bundle
import android.os.Message
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.yang.daodemo.R
import com.yang.daodemo.greenDao.data.DataBean
import com.yang.daodemo.greenDao.messager.DbManager
import com.yang.daodemo.roomDao.GlobalHandler
class GreenActivity : AppCompatActivity(),GlobalHandler.HandleMsgListener {
private lateinit var gr_display:TextView
private var i:Int=0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_green)
gr_display = findViewById(R.id.gr_display)
}
fun onClick(v: View){
when(v.id){
R.id.gr_add -> {
DbManager.getDataDao().add(DataBean("测试 ${i++}"))
}
R.id.gr_delete -> {
DbManager.getDataDao().clear()
}
R.id.gr_update -> {
val bean:DataBean=DataBean()
bean.rid=10
bean.name="修改了"
DbManager.getDataDao().update(bean)
}
R.id.gr_select -> {
GlobalHandler.sendShow(0,DbManager.getDataDao().queryAll(),this)
}
}
}
override fun handleMsg(msg: Message?) {
val list:List<DataBean> = msg?.obj as List<DataBean>
if (list!=null){
val sb:StringBuffer = StringBuffer()
for (t in list){
sb.append("${t.rid} ${t.name} \n")
}
gr_display.text = sb.toString()
}
}
}
xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".greenDao.GreenActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="greenActivity"
android:gravity="center"
android:textSize="20sp"
android:textColor="#fff"
android:background="#2196F3"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/gr_add"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="增加"
android:onClick="onClick"
/>
<Button
android:id="@+id/gr_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="删除"
android:onClick="onClick"
/>
<Button
android:id="@+id/gr_update"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="修改"
android:onClick="onClick"
/>
<Button
android:id="@+id/gr_select"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="查找"
android:onClick="onClick"
/>
</LinearLayout>
<TextView
android:id="@+id/gr_display"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
/>
</LinearLayout>
效果图
ROOM的使用
Room是谷歌官方给出的一个ORM框架,它隶属于jetpack组件中,专门用于解决持久层sqlite的问题。详情请看room官网
1.引入ROOM依赖
在app下的build.gradle脚本文件中引入依赖
apply plugin: 'kotlin-kapt'
//room(alpha代表测试版,最新版请看官网)
implementation 'androidx.room:room-runtime:2.3.0-alpha03'
kapt "androidx.room:room-compiler:2.3.0-alpha03"
2.创建数据层
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
data class RoomDate(var name:String, var age:Int, var sex:String) {
@PrimaryKey(autoGenerate = true) //设置为主键
var id:Long=0
}
其实和greendao的数据层有着异曲同工之意,这也相当于是数据库的一个表结构,@Entity(tableName = "tba")注释里面可以自定义数据表名,如果没有自定义,默认以类名当作表名。
3.创建业务逻辑层
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(version = 1, entities = [RoomDate::class])
abstract class DataBase : RoomDatabase() {
abstract fun roomDao(): RoomDao
companion object {
private var instance: DataBase? = null
@Synchronized
fun getDatabase(context: Context): DataBase {
instance?.let {
return it
}
//返回数据库实体,定义数据库名称为app(名称自定义)
return Room.databaseBuilder(context.applicationContext,DataBase::class.java,"app")
.build().apply { instance=this }
}
}
}
这相当于定义了一个数据库@Database(version = 1, entities = [RoomDate::class]),第一个参数代表数据库版本,第二个是所包含的表,以数组形式展现。这个类必须是抽象类。
业务逻辑层
import androidx.room.*
@Dao
interface RoomDao {
@Insert
fun insertR(roomDate: RoomDate):Long
@Update
fun updateR(roomDate: RoomDate):Int
@Delete
fun deleteR(roomDate: RoomDate):Int
@Query("delete from RoomDate where id=:id")
fun deleteR(id: Long):Int
@Query("select * from RoomDate")
fun queryR():List<RoomDate>
@Query("select * from RoomDate WHERE id=:id")
fun queryR(id: Long):RoomDate
}
room给我们了一个最大的好处是可以使用@Query()注解自己写sql语句,避免了greendao那样的黑箱操作。只有@Query可以写sql。
4.增删改查
在activity实现
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Message
import android.view.View
import android.widget.TextView
import com.yang.daodemo.R
import java.lang.StringBuilder
import kotlin.concurrent.thread
class RoomActivity : AppCompatActivity(), GlobalHandler.HandleMsgListener {
private lateinit var diaplay: TextView
private lateinit var dao: RoomDao
private var i:Int=1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_room)
diaplay = findViewById(R.id.rm_display)
dao = DataBase.getDatabase(this).roomDao()
}
fun onClick(v: View) {
val room1 = RoomDate("张三", 20, "男")
val room2 = RoomDate("乔碧萝殿下", 30, "女")
when (v.id) {
R.id.rm_add -> thread {
room1.id = dao.insertR(room1)
room2.id = dao.insertR(room2)
}
R.id.rm_delete -> thread {
val v1 = dao.deleteR(1)
}
R.id.rm_update -> thread {
val roomDate = RoomDate("===改变== $i",26+i,"不男不女")
roomDate.id=((++i).toLong())
val a = dao.updateR(roomDate)
}
R.id.rm_select -> thread {
val sb = StringBuilder()
for (str in dao.queryR()) {
sb.append("$str \n")
}
GlobalHandler.sendShow(0, sb, this)
}
R.id.rm_select_id-> thread {
val mroom=dao.queryR(2L)
GlobalHandler.sendShow(0, mroom, this)
}
}
}
override fun handleMsg(msg: Message?) {
diaplay.text = msg?.obj.toString()
}
}
xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".greenDao.GreenActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="roomActivity"
android:gravity="center"
android:textSize="20sp"
android:textColor="#fff"
android:background="#2196F3"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/rm_add"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="增加"
android:onClick="onClick"
/>
<Button
android:id="@+id/rm_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="删除"
android:onClick="onClick"
/>
<Button
android:id="@+id/rm_update"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="修改"
android:onClick="onClick"
/>
<Button
android:id="@+id/rm_select"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="查找"
android:onClick="onClick"
/>
<Button
android:id="@+id/rm_select_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="ID查找"
android:onClick="onClick"
/>
</LinearLayout>
<TextView
android:id="@+id/rm_display"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
/>
</LinearLayout>
效果图
其它类
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class GlobalHandler extends Handler{
private HandleMsgListener listener;
private String Tag = GlobalHandler.class.getSimpleName();
//使用单例模式创建GlobalHandler
private GlobalHandler(){
Log.e(Tag,"GlobalHandler创建");
}
private static class Holder{
private static final GlobalHandler HANDLER = new GlobalHandler();
}
public static GlobalHandler getInstance(){
return Holder.HANDLER;
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (getHandleMsgListener() != null){
getHandleMsgListener().handleMsg(msg);
}else {
Log.e(Tag,"请传入HandleMsgListener对象");
}
}
public interface HandleMsgListener{
void handleMsg(Message msg);
}
public void setHandleMsgListener(HandleMsgListener listener){
//getInstance();
this.listener = listener;
}
public HandleMsgListener getHandleMsgListener(){
return listener;
}
//将消息发送给消息队列
private static void send(int what,Object object,GlobalHandler mHandler){
Message message = Message.obtain();
message.what = what;
message.obj = object;
mHandler.sendMessage(message);
//mHandler.removeCallbacksAndMessages(null); //清空消息
}
public static void sendShow(int what, Object object, HandleMsgListener context){
GlobalHandler handler = GlobalHandler.getInstance();
handler.setHandleMsgListener(context);
send(what,object,handler);
handler.removeCallbacks(null); //用完就销毁
}
}
这是用于异步操作的一个工具类
import android.app.Application
import com.yang.daodemo.greenDao.messager.DbManager
import com.yang.daodemo.roomDao.GlobalHandler
class MyAPP:Application() {
override fun onCreate() {
super.onCreate()
GlobalHandler.getInstance()
DbManager.initDb(this)
}
}
这是用于初始化的一个类,需要在AndroidMainfest.xml中的application标签中注册
android:name=".MyAPP"
这样子你的程序就可以跑起来了,以上就是我的学习过程和总结,希望对你们能有所帮助。
更多推荐
所有评论(0)