天天看點

Android room 簡單入門實戰1.關于room2.導入room3.實作資料庫操作的步驟4.操作資料庫進行增删改查5.異常報錯6.檢視資料庫

1.關于room

room是google官方開發的對象關系映射(ORM)庫架構,采用注解的方式,讓你通路資料庫更加穩健,提升資料庫性能。

  • 官網說明
  • 中文翻譯指南
  • 官方案例

2.導入room

implementation "android.arch.persistence.room:runtime:1.1.1"
annotationProcessor "android.arch.persistence.room:compiler:1.1.1" 
           

3.實作資料庫操作的步驟

1. 必須先建立一個需要映射的實體類,用@Entity進行注解

@Entity
public class Anime {
    /**
     * 動漫名
     * 如果是字元串做主鍵,記得加@NonNull,不然會報錯
     */
    @NonNull
    @PrimaryKey
    private String name;
    /**
     * 動漫類型
     */
    private String type;
    /**
     * 放送時間
     */
    private String playDate;
    /**
     * 集數
     */
    private int episode;

    getter、setter省略...
}
           

2. 建立一個操作實體類的dao接口,用@Dao進行注解

@Dao
public interface AnimeDao {

    @Query("SELECT * FROM  anime")
    List<Anime> getAllAnime(); //加載所有動漫資料

    @Query("SELECT * FROM anime WHERE name = :name")
    Anime loadAnimeByName(String name); //根據名字加載動漫

    @Insert
    void insertOneAnime(Anime anime); //插入一條動漫資訊

    @Insert
    void insertMultiAnimes(Anime... animes); //插入多條動漫資訊

    @Update(onConflict = OnConflictStrategy.REPLACE)
    int updateUsers(Anime... animes); //更新動漫資訊,當有沖突時則進行替代

    @Delete
    void deleteAnime(Anime anime);
}
           

3. 建立一個抽象類,添加@Database注解

@Database(entities = {Anime.class},version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract AnimeDao animeDao();
}

           

4. 建立RoomDatabase執行個體,在application中初始化,建議是單例

public class MyApp extends Application {

    private static  MyApp mInstance;
    private AppDatabase appDB;
    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
        appDB = Room.databaseBuilder(this,AppDatabase.class,"anime_info")
                .addMigrations()
                .build();
    }

    public static MyApp getInstance(){
        return mInstance;
    }
    
    public AppDatabase getAppDB(){
        return appDB;
    }

}
           

4.操作資料庫進行增删改查

animeDao.insertOneAnime(createOneAnime());
           

animeDao.deleteAnime(queryOneRecord());
           

Anime anime = queryOneRecord();
        anime.setEpisode(100);
        animeDao.updateUsers(anime);
           

private Anime queryOneRecord() {
        Anime anime = animeDao.loadAnimeByName("青春豬頭少年不會夢到兔女郎學姐");
        tvResult.setText(anime.toString());
        return anime;
    }
           

5.異常報錯

  • 實體類定義中沒有加NonNull,因為它是字元串主鍵,為避免其為空,是以必須加上此限制
You must annotate primary keys with @NonNull. "name" is nullable. SQLite considers this a bug and Room does not allow it. See SQLite docs for details:
           
  • 不允許在主線程中操作資料庫,可在建構RoomDatabase執行個體對象中,加入

    allowMainThreadQueries()

    ,這是預設不許在主線程中連接配接資料庫。
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
           

變成這樣即可

appDB = Room.databaseBuilder(this,AppDatabase.class,"anime_info")
                .addMigrations()
                .allowMainThreadQueries()
                .build();
           

6.檢視資料庫

用SQLite Expert Personal 3打開剛建立并進行操作過的資料庫,看是否正常。

Android room 簡單入門實戰1.關于room2.導入room3.實作資料庫操作的步驟4.操作資料庫進行增删改查5.異常報錯6.檢視資料庫

打開第一個檔案anime_info,注意這裡在建構RoomDatabase執行個體時沒加字尾db,是以看到的檔案也沒有db字尾。

可以看到資料庫表正确地建立了,資料也有寫入。

Android room 簡單入門實戰1.關于room2.導入room3.實作資料庫操作的步驟4.操作資料庫進行增删改查5.異常報錯6.檢視資料庫

最後,附上界面圖和activity代碼,寫的很粗糙,多次點選會崩潰,因為有沖突發生時是以異常形式處理的,更深層次的應用有機會再寫。

Android room 簡單入門實戰1.關于room2.導入room3.實作資料庫操作的步驟4.操作資料庫進行增删改查5.異常報錯6.檢視資料庫
package cn.pigdreams.blogdemo.roomdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.List;

import cn.pigdreams.blogdemo.MyApp;
import cn.pigdreams.blogdemo.R;

public class RoomDemoActivity extends AppCompatActivity implements View.OnClickListener {

    private Button button;
    private Button button2;
    private Button button3;
    private Button button4;
    private Button button5;
    private Button button6;
    private TextView tvResult;
    private AnimeDao animeDao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_room_demo);
        button = findViewById(R.id.button);
        button2 = findViewById(R.id.button2);
        button3 = findViewById(R.id.button3);
        button4 = findViewById(R.id.button4);
        button5 = findViewById(R.id.button5);
        button6 = findViewById(R.id.button6);
        tvResult = findViewById(R.id.tv_result);
        button.setOnClickListener(this);
        button2.setOnClickListener(this);
        button3.setOnClickListener(this);
        button4.setOnClickListener(this);
        button5.setOnClickListener(this);
        button6.setOnClickListener(this);
        //拿到資料庫操作對象
        animeDao = MyApp.getInstance().getAppDB().animeDao();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                //增加一條動漫記錄
                animeDao.insertOneAnime(createOneAnime());
                break;
            case R.id.button2:
                //删除一條記錄
                animeDao.deleteAnime(queryOneRecord());
                queryAllRecord();
                break;
            case R.id.button3:
                //更新一條記錄
                updateRecord();
                break;
            case R.id.button4:
                //查詢所有記錄
                queryAllRecord();
                break;
            case R.id.button5:
                //增加多條動漫記錄
                animeDao.insertMultiAnimes(createMutilAnime());
                break;
            case R.id.button6:
                //查詢一條記錄
                queryOneRecord();
                break;
        }
    }

    private void updateRecord() {
        Anime anime = queryOneRecord();
        anime.setEpisode(100);
        animeDao.updateUsers(anime);
        queryAllRecord();
    }

    private Anime queryOneRecord() {
        Anime anime = animeDao.loadAnimeByName("青春豬頭少年不會夢到兔女郎學姐");
        tvResult.setText(anime.toString());
        return anime;
    }

    private void queryAllRecord() {
        List<Anime> animeList = animeDao.getAllAnime();
        tvResult.setText(animeList.toString());
    }

    private Anime createOneAnime(){
        Anime anime = new Anime();
        anime.setName("青春豬頭少年不會夢到兔女郎學姐");
        anime.setType("奇幻&戀愛");
        anime.setPlayDate("2018-10");
        anime.setEpisode(13);
        return anime;
    }

    private Anime[] createMutilAnime(){
        Anime[] animes = new Anime[3];
        Anime anime = new Anime();
        anime.setName("超能力女兒");
        anime.setType("魔幻日常");
        anime.setPlayDate("2018-4");
        anime.setEpisode(12);
        Anime anime1 = new Anime();
        anime1.setName("衛宮家今天的飯");
        anime1.setType("美食");
        anime1.setPlayDate("2018-1");
        anime1.setEpisode(13);
        Anime anime2 = new Anime();
        anime2.setName("終将成為你");
        anime2.setType("百合");
        anime2.setPlayDate("2018-10");
        anime2.setEpisode(13);
        animes[0] = anime;
        animes[1] = anime1;
        animes[2] = anime2;
        return animes;
    }
}