简介
Android 2017 IO大会推出了官方数据库框架:Room。Room其实就只是对原生的SQLite API进行了一层封装。不得不说google其实早应该出SQLite的ORM了,因为Android的SQLite谁用谁知道,没有任何封装的字符输入。如果不对着Demo基本上会有记不起来的一两个关键字的时候,而且完全手敲容易输入错误。当然还有很多其他的Android ORM框架例如OrmLite、GreenDao 和 Sugar。但是本着Google爸爸的东西肯定有牛逼的地方,我们还是需要学习一下怎么使用。
这里解释一下什么是ORM,对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。其实更好的说明就是,对数据库指令的二次封装。使其使用更加简单、轻松、缓解记不住指令的尴尬。
导入工程
这里只说明Android studio的导入
1.首先在build.gradle里添加
allprojects {
repositories {
jcenter()
google()
}
}
2.然后在添加依赖
implementation 'android.arch.persistence.room:runtime:1.0.0'
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"
使用流程概况
因为创建步骤较多所以这里简单先给一个流程,给大家有一个简单的概念:
- 创建数据class,使用的注释是:@Entity
- 创建Dao 数据操作抽象class,使用的注释是:@Dao(负责提供操作数据的方法,比如基本的增加、更新、查找、删除。当然除了这些基本的,更复杂的我们将在后续深入学习)
- 创建应用程序数据库的抽象class,使用的注释是:@Database(负责创建应用数据库,组合“数据class”与“数据操作class”,还有数据库版本)
- 实例化使用数据库
一个简单的小Demo
在深入学习前,我们先来一个简单的小demo演示一下创建流程与使用。
1.首先是创建数据class,它使用关键注释是@Entity,这个class代表着一列的数据表(里面包含着主键id(这是是必需的)、内容1标题、内容2标题等等)
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity //重点!这个是关键.数据class必需使用@Entity注释
public class MyData {
@PrimaryKey //@PrimaryKey = 主键
@ColumnInfo(name = "id")
public int id;
@ColumnInfo(name = "name")//这个代表了这个数据标题名称
public String name;
public String content; //当然不写 @ColumnInfo(name = "content") 也是可以的,因为数据名称可以默认为变量名称。
}
2.创建Dao 数据操作抽象class,它使用关键注释是@Dao,这个class负责提供操作数据的方法(比如基本的增加、更新、查找、删除)
import java.util.List;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.Update;
@Dao //重点! 这个是关键,数据操作的class必需使用@Dao来注释
public abstract class MyDao { //另外注意它是一个抽象类
@Insert(onConflict = OnConflictStrategy.REPLACE)
//@Insert = 插入, onConflict = 如果冲突 OnConflictStrategy.REPLACE = 如果冲突就替换
public abstract void insert(MyData... data); //添加了插入注释后,这个方法就可以当做插入数据的方法使用
@Update
public abstract void update(MyData... data);// @Update = 更新
@Delete
public abstract void delete(MyData... data);// @Delete = 删除
@Query("select * from MyData")
//@Query = 查询 ,这里的注释括号里的内容代表这查询的关键词,可以用于筛查想要的数据。
abstract List<MyData> getAll();
}
3.创建应用程序数据库的抽象class,使用的注释是:@Database(负责创建应用数据库,组合数据class与数据操作class,还有数据库版本)
import androidx.room.Database;
import androidx.room.RoomDatabase;
//重点!这个是关键.应用数据库class必需使用Database注释
//entities 实体 = 我们的数据class MyData,注意它使用了{}包裹
//version = 1 数据库版本号
//exportSchema = false 导出模式
@Database(entities = {MyData.class},version = 1,exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
public abstract MyDao Dao(); //
}
4.在activity里实例化并且使用数据库。
import androidx.appcompat.app.AppCompatActivity;
import androidx.room.Room;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.example.user.demo.R;
import java.util.List;
public class RoomActivity extends AppCompatActivity {
private Button mBtnGetData;
private AppDatabase appDatabase;
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_room);
/**
* 实例化应用数据库
*/
appDatabase = Room.databaseBuilder(RoomActivity.this,AppDatabase.class,"user.db")
.allowMainThreadQueries()
.build();
MyDao dao = appDatabase.Dao();//得到实例化的数据操作class
MyData data = new MyData();//实例一个数据class
data.id = 101; //添加数据
data.name = "橘子";
data.content = "酸酸的";
dao.insert(data); //插入数据
MyData data2 = new MyData();
data2.id = 102;
data2.name = "苹果";
data2.content = "脆脆的";
dao.insert(data2);
mTextView = (TextView)findViewById(R.id.textView);
mBtnGetData = (Button)findViewById(R.id.btn_getdata);
mBtnGetData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MyDao dao = appDatabase.Dao();
StringBuffer sb = new StringBuffer();
sb.append("数据库内容是:"+"\n"+"-------------------------------\n");
List<MyData> datas = dao.getAll();//得到所有数据的List
for (MyData data : datas){
sb.append("id : "+String.valueOf(data.id)+"\n");
sb.append("name : "+data.name+"\n");
sb.append("content : "+data.content+"\n");
sb.append("-------------------------------\n");
mTextView.setText(sb.toString());
}
}
});
}
}
以上是添加数据和查询数据在activity里的操作。注意一点,我这个只是demo,其实不管是导入数据和查询数据最好都在子线程里操作,尽量不要在主线程里操作数据库。
效果图:
深入学习 Entity使用
@Entity 是用来创建表格与表格中一列的内容的。Room 会为实体类中定义的每个字段在数据库中创建“列”。
下面这个代码块展示了如何定义一个实体
@Entity
public class MyData {
@PrimaryKey //@PrimaryKey = 主键
@ColumnInfo(name = "id")
public int id;
@ColumnInfo(name = "name")
public String name;
public String content;
@Ignore //使用@Ignore的数据将不会在数据库创建此数据的一列
public Bitmap bitmap;
}
一份数据实体,必定包含一个主键变量(或者叫字段),然后可以根据你的需求添加若干你需要的数据变量。另外如果你有不需要数据库创建字段列,你可以使用@Ignore 进行注释。
为了能够保存某个字段,Room必须能够对它进行操作。你可以使用public修饰符,或者你可以提供getter和setter方法。如果你选择后者,记住Room是基于JavaBeans约定的。