福建师范大学Android Room 技术浅谈
## 前提告知该文章是用作课程评分,本文内容虽为原创,但也有参考。
1.Room的背景简介
处理大量结构化数据的应用可极大地受益于在本地保留这些数据。最常见的使用场景是缓存相关的数据,这样一来,当设备无法访问网络时,用户仍然可以在离线状态下浏览该内容。
Room 持久性库在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够流畅地访问数据库。
2.Room的优点
- 使用编译时注解,能够对@Query和@Entity里面的SQL语句等进行验证;
- 与SQL语句的使用更加贴近,能够降低学习成本,提交开发效率,减少模板代码;
- @Embedded 能够减少表的创建;
- 对LiveData、Kotlin Coroutines的支持
3.Room三大组件
1.Database: 可以使用此组件创建数据库 holder,注释定义实体列表,和类的内容定义数据访问对象(DAO)数据库中的表。它也是基本连接的主要访问点。
2.Entity: 实体类对象模型,一般对应表结构。实体的每个字段在数据库中都是保存的,除非你用@Ignore 注解。
3.DAO:全称Database Access Object,定义了对数据库中数据的读写等操作,DAO中可以使用SQL语句来操作数据库。
4.android Room 依赖的配置
在build.gradle 文件的 dependencies添加一下代码:
implementation fileTree(dir:'libs',include:['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.room:room-common:2.3.0'
implementation 'androidx.room:room-runtime:2.3.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:esprsso-core:3.2.0'
implementation 'com.google.andrid.material:material:1.1.0'
implementation 'andrid.arch.presistence.room:runtime:1.1.1'
annotationProcessor 'andrid.arch.presistence.room:compiler:1.1.1'
annotationProcessor 'androidx.room:room-compiler:2.3.0'
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HvvSwCVZ-1670507203385)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
5.1Entity(创建表)
@Entity(tableName = "table_name")
public class MainData implements Serializable {
//创建ID列
@PrimaryKey(autoGenerate = true)
private int ID;
//创建下一列
@ColumnInfo(name = "text")
private String text;
//生成getter和setter
public int getID() {
return ID;
}
public void setID(int ID) {
this.ID = ID;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i7gB8tq1-1670507203387)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
5.2Dao
@Dao
public interface MainDao {
//插入语句
@Insert(onConflict = REPLACE)
void insert(MainData mainData);
//删除语句
@Delete
void delete(MainData mainData);
//删除全部的语句
@Delete
void reset(List<MainData> mainData);
//更新语句
@Query("UPDATE table_name SET text= :sText WHERE ID = :sID" )
void update(int sID,String sText);
//查询所有数据
@Query("select * from table_name")
List<MainData> getAll();
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AZrWnSFi-1670507203388)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
在这个里面定义了,对应数据库的操作。
@Insert、@Delete、@Update、@Query 代表我们常用的插入、删除、更新、查询数据库操作。
@Query非常的强大,你可以编写任意sql语句并得到你想要的结果。
5.3DataBase
// 添加数据库 实体
@Database(entities = {MainData.class}, version = 1,exportSchema = false)
public abstract class RoomDB extends RoomDatabase{
//创建 数据库 实例
private static RoomDB database;
//定义数据库的名字
private static String DATABSAE_NAME="database";
public synchronized static RoomDB getInstance(Context context){
//检测状态
if(database==null){
//数据库为空时就初始化数据库
database = Room.databaseBuilder(context.getApplicationContext(),
RoomDB.class,DATABSAE_NAME).allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build();
}
return database;
}
//创建Dao
public abstract MainDao mainDao();
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WmTccfjK-1670507203389)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
这里运用到数据库单例模式,下面会仔细讲讲为什么把数据库写成单例。
5.4单例模式简单介绍
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
单例模式有两种:饿汉式和懒汉式。
我使用的是懒汉式,这里先说一下饿汉式与懒汉式的区别:
饿汉式:类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了。
懒汉式:懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例。
在线程安全上:
饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题,
懒汉式本身是非线程安全的,为了实现线程安全有几种写法。
在资源加载和性能上:
饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内存,但是相应的,在第一次调用时速度也会更快,因为其资源已经初始化完成。
而懒汉式顾名思义,会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要做初始化,如果要做的工作比较多,性能上会有些延迟,之后就和饿汉式一样了。
可以发现,两者各有缺点和优点,因为我自己写的是一个小案例,涉及不到多线程,所以就用的懒汉式模式。
6.使用
1.注意事项:需要在工作线程中使用,否则耗时操作将会导致Application崩溃
2.获取数据库
//数据库变量赋值
database = RoomDB.getInstance(this);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PQW1FF4U-1670507203389)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
3.更新数据
String uText = editText.getText().toString().trim();
//更新数据库数据
database.mainDao().update(sID,uText);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pnbWX7mE-1670507203390)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
4.插入数据
MainData data = new MainData();
data.setText(sText);
database.mainDao().insert(data);
//清空 edit text
editText.setText("");
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JWIl2gDS-1670507203391)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]
7.效果展示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7TcTrO3B-1670507203392)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]编辑
8.源码
肖学良
t.setText(“”);
[外链图片转存中...(img-JWIl2gDS-1670507203391)]
## 7.效果展示
![img](https://img-blog.csdnimg.cn/9cad2a3538bf4b1c8d9ed3e00b46826b.gif)[外链图片转存中...(img-7TcTrO3B-1670507203392)]编辑
## 8.源码
肖学良
https://download.csdn.net/download/weixin_53445186/87218017