Room介紹
room是Google官方推薦的ORM數(shù)據(jù)庫框架,抽象出sqlite訪問的數(shù)據(jù)庫弧关。
包含三大組件:
- Entity 定義 表結(jié)構(gòu),每個(gè)entity類對(duì)一個(gè)表世囊,默認(rèn)會(huì)把entity類所有字段都創(chuàng)建為表字段
- Dao 定義entity類的CRUD(增刪查改)功能
- Database 數(shù)據(jù)庫的訪問入口窿祥,注解定義數(shù)據(jù)庫的實(shí)體表,數(shù)據(jù)庫版本控制晒衩,表結(jié)構(gòu)導(dǎo)出、表結(jié)構(gòu)修改等都在這里處理
步驟
1.添加依賴
def room_version = '2.3.0-alpha04'
implementation rootProject.ext.dependencies.room_runtime
annotationProcessor rootProject.ext.dependencies.room_compiler
androidTestImplementation rootProject.ext.dependencies.room_testing
2.定義Entity實(shí)體表
@Entity 注解并在@Database 注解中的 entities 屬性所引用听系,Room就會(huì)在數(shù)據(jù)庫中為這個(gè)被 @Entity 注解的類創(chuàng)建一張表
@PrimaryKey 每個(gè)entity至少要有一個(gè)主鍵(PrimaryKey),autoGenerate表示這個(gè)值自動(dòng)生成
@Entity(primaryKeys = {"xxx", "xxx"}) 如果是復(fù)合主鍵的話, 你需要使用注解@Entity的primaryKeys屬性
@Entity(primaryKeys = {"firstName", "lastName"})
public class User {
public String firstName;
public String lastName;
@Ignore
Bitmap picture;
}
@ColumnInfo(name = "xxx") 定義表字段,也可以不使用此注解弃秆,默認(rèn)為所有屬性生成表字段
@Ignore 如果Engity類中某個(gè)屬性不想保存到數(shù)據(jù)庫髓帽,可以使用@Ignore注解忽略
@Entity
public class User {
@PrimaryKey
public int id;
public String firstName;
public String lastName;
@Ignore
Bitmap picture;
}
@Entity(indices = {@Index("name"), @Index(value = {"last_name", "address"})}) 為了加速查詢速度. 要給實(shí)體添加索引
@Entity(indices = {@Index("name"),
@Index(value = {"last_name", "address"})})
public class User {
@PrimaryKey
public int id;
public String firstName;
public String address;
@ColumnInfo(name = "last_name")
public String lastName;
@Ignore
Bitmap picture;
}
@Entity(foreignKeys = @ForeignKey(entity = User.class,
parentColumns = "id",
childColumns = "user_id")) 設(shè)置外鍵
@Entity(foreignKeys = @ForeignKey(entity = User.class,
parentColumns = "id",
childColumns = "user_id"))
public class Book {
@PrimaryKey
public int bookId;
public String title;
@ColumnInfo(name = "user_id")
public int userId;
}
@Embedded注解來表示一個(gè)對(duì)象
public class Address {
public String street;
public String state;
public String city;
@ColumnInfo(name = "post_code")
public int postCode;
}
@Entity
public class User {
@PrimaryKey
public int id;
public String firstName;
@Embedded
public Address address;
}
demo:
package com.wrs.project.module.app.common.database.entity;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import androidx.annotation.NonNull;
@Entity(tableName = "Article")
public class Article {
@PrimaryKey(autoGenerate = true)
private int id;
private String author;
private String title;
private String content;
private String token;
private int comments;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public int getComments() {
return comments;
}
public void setComments(int comments) {
this.comments = comments;
}
}
3. 定義DAO
簡單查詢
@Dao
public interface MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List<User> friends);
}
嵌套查詢
@Dao
public interface MyDao {
@Query("SELECT * FROM book "
+ "INNER JOIN loan ON loan.book_id = book.id "
+ "INNER JOIN user ON user.id = loan.user_id "
+ "WHERE user.name LIKE :userName")
public List<Book> findBooksBorrowedByNameSync(String userName);
}
@Dao
public interface MyDao {
@Query("SELECT user.name AS userName, pet.name AS petName "
+ "FROM user, pet "
+ "WHERE user.id = pet.user_id")
public LiveData<List<UserPet>> loadUserAndPetNames();
// You can also define this class in a separate file, as long as you add the
// "public" access modifier.
static class UserPet {
public String userName;
public String petName;
}
}
demo
package com.wrs.project.module.app.common.database.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.Update;
import com.wrs.project.module.app.common.database.entity.Article;
import java.util.List;
@Dao
public interface ArticleDao {
/**
* 增
* @param entities
*/
@Insert
void insert(Article... entities);
/**
* 刪
* @param entities
*/
@Delete
void delete(Article... entities);
/**
* 查
* @param title
*/
@Query("SELECT * FROM Article WHERE title = :title")
List<Article> findByTitle(String title);
/**
* 查
* @param titles
*/
@Query("SELECT * FROM Article WHERE title IN (:titles)")
List<Article> findInTitles(List<String> titles);
/**
* 改
* @param entities
*/
@Update
void update(Article... entities);
@Insert(onConflict = OnConflictStrategy.REPLACE)
List<Long> insertAll(List<Article> entities);
@Delete
void delete(Article entity);
@Query("DELETE FROM Article")
void deleteAll();
@Delete
void deleteArticle(Article entity);
@Query("SELECT * FROM Article")
List<Article> findAll();
@Query("SELECT * FROM Article")
LiveData<List<Article>> loadSignList();
}
4. 定義Database
package com.wrs.project.module.app.common.database;
import android.content.Context;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.TypeConverters;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;
import com.wrs.project.module.app.common.database.conversion.ConversionFactory;
import com.wrs.project.module.app.common.database.dao.ArticleDao;
import com.wrs.project.module.app.common.database.entity.Article;
@androidx.room.Database(
entities = { Article.class}, // 聲明需要?jiǎng)?chuàng)建表的實(shí)體
version = 2, // 數(shù)據(jù)庫版本號(hào)
exportSchema = true // 表結(jié)構(gòu)是否需要導(dǎo)出
)
@TypeConverters({ConversionFactory.class}) // 屬性類型轉(zhuǎn)換衡查,這里值轉(zhuǎn)換了Date類
public abstract class Database extends RoomDatabase {
public abstract ArticleDao articleDao(); // 聲明每個(gè)entity的dao類
private static Database sInstance; // 創(chuàng)建訪問數(shù)據(jù)庫比較耗資源必盖,生成單例方便訪問
public static Database getInstance(final Context context) {
if (sInstance == null) {
synchronized (Database.class) {
if (sInstance == null) {
sInstance = create(context.getApplicationContext());
}
}
}
return sInstance;
}
private static Database create(final Context context) {
return Room.databaseBuilder(
context,
Database.class,
"phonesign_db")
.addMigrations(MIGRATION_1_2) // 構(gòu)建版本升級(jí)時(shí)表結(jié)構(gòu)的變化
.allowMainThreadQueries()
.build();
}
private static Migration MIGRATION_1_2 = new Migration(1,2) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE Article "
+ " ADD COLUMN token TEXT");
database.execSQL("ALTER TABLE Article "
+ " ADD COLUMN comments INTEGER NOT NULL DEFAULT 0");
}
};
}
5. 測試
package com.wrs.project.module.app.common;
import android.content.Context;
import android.util.Log;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import com.wrs.project.module.app.common.database.DBService;
import com.wrs.project.module.app.common.database.entity.Article;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static org.junit.Assert.assertEquals;
@RunWith(AndroidJUnit4.class)
public class DatabaseInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
AppMgr.context = appContext;
AppMgr.debug = true;
List<Article> list = new ArrayList<>();
for (int i = 0; i < 6; i++) {
Article entity = new Article();
entity.setTitle("title" + i);
entity.setDate(new Date());
list.add(entity);
}
DBService.insertAll(list);
List<Article> resultList = DBService.findAll();
if (null != resultList && resultList.size() > 0) {
for (int i = 0; i < resultList.size(); i++) {
Article entity = resultList.get(i);
Log.e("article", entity.getTitle());
}
}
List<Article> entityList = DBService.findByTitle("title5");
Log.e("article", entityList.toString());
}
}
如果覺得可以就點(diǎn)個(gè)??吧俱饿,歡迎粉絲收藏塌忽,土豪打賞,您的關(guān)注就是我們創(chuàng)作的動(dòng)力土居!
讀者有什么想看的相關(guān)技術(shù)篇章,歡迎評(píng)論留言擦耀!
QQ交流群:908058499
項(xiàng)目源碼:https://codechina.csdn.net/android1/projectbasic
上篇:無 目錄 下篇:android專題-藍(lán)牙掃描、連接分瘾、讀寫