在app的gradle里面添加如下依赖
def room_version = "2.2.0"
implementation "androidx.room:room-runtime:$room_version"
// For Kotlin use kapt instead of annotationProcessor
annotationProcessor "androidx.room:room-compiler:$room_version"
// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
// optional - RxJava support for Room
implementation "androidx.room:room-rxjava2:$room_version"
// optional - Guava support for Room, including Optional and ListenableFuture
implementation "androidx.room:room-guava:$room_version"
// Test helpers
testImplementation "androidx.room:room-testing:$room_version"
数据库的三个要素:数据库和表的创建,数据的访问。我们就通过这三个要素来学习Room。
package com.example.jetpacktest;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
//要想生成一张表,要添加注释@Entity,表的名字默认是Student
// 如果想换表名,就要写成我这样的
@Entity(tableName = "AnHuiUniversityStudent")
public class Student {
@PrimaryKey(autoGenerate = true)
private int ID;//必须要有一个主键,自动增长设置为true
@ColumnInfo(name = "anhuiUniversityStudentName")
private String name;//修改字段的名字可以用@ColumnInfo
@ColumnInfo(name = "anhuiUniversityStudentPWD")
private String password;
private int addressID;
//必须要有构造方法,插入数据的时候使用
// 没有自动增长ID的构造方法
// 注意构造方法只能有一个
public Student(String name, String password, int addressID) {
this.name = name;
this.password = password;
this.addressID = addressID;
}
public int getID() {
return ID;
}
public void setID(int ID) {
this.ID = ID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAddressID() {
return addressID;
}
public void setAddressID(int addressID) {
this.addressID = addressID;
}
@NonNull
@Override
public String toString() {
return getID() + " " + getName() + " " + getPassword() + " " + getAddressID();
}
}
package com.example.jetpacktest;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
/**
* 这就是数据访问对象
* 用于操作数据的API
*/
@Dao//要添加这个注解
public interface StudentDao {
@Query("select * from AnHuiUniversityStudent")
List<Student> getAll();//执行这个方法就是执行注解中的SQL语句
@Insert//可以插入多个对象
void insert(Student... students);
@Delete
void delete(Student student);
@Update
void update(Student student);
}
package com.example.jetpacktest;
import androidx.room.Database;
import androidx.room.RoomDatabase;
/**
* 用来创建数据库的类,必须写成抽象类
*/
//注解entities表示哪些表属于该数据库
//注解version表示数据库的版本
@Database(entities = {Student.class}, version = 1)
public abstract class MyDataBase extends RoomDatabase {
public abstract StudentDao userDao();
}
package com.example.jetpacktest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.room.Database;
import androidx.room.Room;
import android.os.Bundle;
import android.util.Log;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseThread databaseThread = new DatabaseThread();
databaseThread.start();
}
//数据库,网络的操作都要在子线程
class DatabaseThread extends Thread {
@Override
public void run() {
super.run();
//在这里进行数据库的操作
MyDataBase zhang_xinDB = Room.databaseBuilder(getApplicationContext(),
MyDataBase.class
, "zhang_xinDB")//数据库的名字,可以自己定义
.build();
StudentDao dao = zhang_xinDB.userDao();
dao.insert(new Student("安静平","ajp",17));
List<Student> list = dao.getAll();
Log.i("zhang_xin",list.toString());
}
}
}
打印输出
[1 安静平 ajp 17]
以上只是小试牛刀,我们还有更加丰富的功能
一
@Entity(tableName = "AnHuiUniversityStudent")
public class Student {
@PrimaryKey(autoGenerate = true)
private int ID;
@ColumnInfo(name = "anhuiUniversityStudentName")
private String name;
@ColumnInfo(name = "anhuiUniversityStudentPWD")
private String password;
private int addressID;
//假设我们还有一个成员变量,但我们不想让它成为表的字段,我们可以这么些
@Ignore
private String peiOu;
……其余的略去
二
有条件查询
package com.example.jetpacktest;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
/**
* 这就是数据访问对象
* 用于操作数据的API
*/
@Dao//要添加这个注解
public interface StudentDao {
@Query("select * from AnHuiUniversityStudent")
List<Student> getAll();//执行这个方法就是执行注解中的SQL语句
@Insert//可以插入多个对象
void insert(Student... students);
@Delete
void delete(Student student);
@Update
void update(Student student);
//查询一条记录
@Query("select * from AnHuiUniversityStudent where addressID like :aid")
Student findByAddressID(int aid);
//查询一组数据,用户传进一组ID
@Query("select * from AnHuiUniversityStudent where ID in (:userIDs)")
List<Student> getAllByID(int[] userIDs );
}
看MainActivity
package com.example.jetpacktest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.room.Database;
import androidx.room.Room;
import android.os.Bundle;
import android.util.Log;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseThread databaseThread = new DatabaseThread();
databaseThread.start();
}
//数据库,网络的操作都要在子线程
class DatabaseThread extends Thread {
@Override
public void run() {
super.run();
//在这里进行数据库的操作
MyDataBase zhang_xinDB = Room.databaseBuilder(getApplicationContext(),
MyDataBase.class
, "zhang_xinDB")//数据库的名字,可以自己定义
.build();
StudentDao dao = zhang_xinDB.userDao();
dao.insert(new Student("安静平","ajp",17),new Student("王学岗","wxg",18));
List<Student> list = dao.getAll();
Log.i("zhang_xin",list.toString());
Log.i("zhang_xin",dao.findByAddressID(17)+"");
Log.i("zhang_xin",dao.getAllByID(new int[]{1,2})+"");
}
}
}
三 查询结果只有一部分
加入我们只查询name与password字段
新增加一个类
package com.example.jetpacktest;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
public class StudentTwo {
//与Student中的注解保持一致
@ColumnInfo(name = "anhuiUniversityStudentName")
private String name;
@ColumnInfo(name = "anhuiUniversityStudentPWD")
private String password;
public StudentTwo(String name, String password) {
this.name = name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@NonNull
@Override
public String toString() {
return this.name+" "+this.password;
}
}
StudentDao中添加
//查询结果只有一部分字段
@Query("select anhuiUniversityStudentName,anhuiUniversityStudentPWD from anhuiuniversitystudent")
List<StudentTwo> getTwoColumn();
MainActivity中调用
package com.example.jetpacktest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.room.Database;
import androidx.room.Room;
import android.os.Bundle;
import android.util.Log;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseThread databaseThread = new DatabaseThread();
databaseThread.start();
}
//数据库,网络的操作都要在子线程
class DatabaseThread extends Thread {
@Override
public void run() {
super.run();
//在这里进行数据库的操作
MyDataBase zhang_xinDB = Room.databaseBuilder(getApplicationContext(),
MyDataBase.class
, "zhang_xinDB")//数据库的名字,可以自己定义
.build();
StudentDao dao = zhang_xinDB.userDao();
dao.insert(new Student("安静平","ajp",17),new Student("王学岗","wxg",18));
Log.i("zhang_xin",dao.getTwoColumn().toString());
}
}
}
四表和表之间建立联系
创建一张表,使该表的主键作为Student的外键
package com.example.jetpacktest;
import androidx.annotation.NonNull;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.room.PrimaryKey;
@Entity(foreignKeys = @ForeignKey(entity = Students.class,parentColumns = "ID",childColumns = "addressID"))
public class Address {
@PrimaryKey(autoGenerate = true)//每一个类都需要一个主键
private int addressID;
private String addressName;
public Address(int addressID, String addressName) {
this.addressID = addressID;
this.addressName = addressName;
}
public int getAddressID() {
return addressID;
}
public void setAddressID(int addressID) {
this.addressID = addressID;
}
public String getAddressName() {
return addressName;
}
public void setAddressName(String addressName) {
this.addressName = addressName;
}
@NonNull
@Override
public String toString() {
return this.addressName+" "+this.addressID;
}
}
数据库的迁移
版本名字改为2
package com.example.jetpacktest;
import androidx.room.Database;
import androidx.room.RoomDatabase;
/**
* 用来创建数据库的类,必须写成抽象类
*/
//注解entities表示哪些表属于该数据库
//注解version表示数据库的版本
@Database(entities = {Students.class,Address.class}, version = 2)
public abstract class MyDataBase extends RoomDatabase {
public abstract StudentDao userDao();
}
//更新数据库,并迁移
final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
//升级的代码
Log.i("zhang_xin","数据库版本升级1");
}
};
final Migration MIGRATION_2_3 = new Migration(2, 3) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
//升级的代码
Log.i("zhang_xin","数据库版本升级12");
}
};
final Migration MIGRATION_3_4 = new Migration(3, 4) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
//升级的代码
Log.i("zhang_xin","数据库版本升级3");
}
};
MyDataBase myDataBase = Room.databaseBuilder(getApplicationContext(), MyDataBase.class, "myDB").addMigrations(MIGRATION_1_2).
fallbackToDestructiveMigration().build();
StudentDao dao= myDataBase.userDao();
dao.insert(new Students("c","a",12));
Log.i("zhang_xin", dao.getTwoColumn().toString());
内嵌对象
class Address {
public String street;
public String state;
public String city;
@ColumnInfo(name = "post_code")
public int postCode;
}
@Entity
class User {
@PrimaryKey
public int id;
public String firstName;
@Embedded
public Address address;
}
关联RxJava、LiveData和Cursor
//这里就可以在以后用观查者监听到获取的数据在数据表中对应数据的更
@Query("select name,pwd from Student")
public LiveData<List<StudentTuple>> getRecord2();
//支持RXjava
@Query("select name,pwd from Student")
public Flowable<List<StudentTuple>> getRecord3();
//支持Cursor
@Query("select name,pwd from Student")
public Cursor getRecord4();