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 更新版本 android room使用_ide


打开第一个文件anime_info,注意这里在构建RoomDatabase实例时没加后缀db,所以看到的文件也没有db后缀。可以看到数据库表正确地创建了,数据也有写入。

android room 更新版本 android room使用_room_02


最后,附上界面图和activity代码,写的很粗糙,多次点击会崩溃,因为有冲突发生时是以异常形式处理的,更深层次的应用有机会再写。

android room 更新版本 android room使用_room_03

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;
    }
}