Jetpack---Room數據庫

Room數據庫和GreenDao使用都差不多,定義的實體類都是用的注解方式。如果項目里面使用了GreenDao,沒有必要去遷移Room.好處就是支持同為Android Architecture Component的LiveData,實現數據的動態刷新和綁定組件生命周期功能。根據項目而定吧,性能方面也差不多。屬于jetpack,就順帶著學習一下。官網全是kotlin表達的。

設想一個場景,一個activity,加載一個recycleView,數據源每次初始化的時候,從服務器拿到都是一樣的數據,如果有個需求,后臺每次就給你11個工人的信息,信息包含了姓名,工牌,是否吃飯。我們要記錄他到底有沒有吃飯,這樣用sp就比較復雜了。只能是把他們一個個狀態保存在本地。這樣跟狀態欄搜索歷史很像,卸載了就沒有了,卸載了還有的話只能說這種是拉取得后臺,今天只講狀態保存在本地。

添加依賴
//Room數據庫
    def room_version = "2.2.5"
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"
實體Bean,代表工人的所有屬性

可以理解為數據源的bean類型

public class Person{
    public Person(String name, int id, boolean eatrice){
        this.name = name;
        this.id = id;
        this.eatrice = eatrice;
    }
    String name;
    int id;
    boolean eatrice;
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
    public int getId(){
        return id;
    }
    public void setId(int id){
        this.id = id;
    }
    public boolean isEatrice(){
        return eatrice;
    }
    public void setEatrice(boolean eatrice){
        this.eatrice = eatrice;
    }
    @Override
    public String toString(){
        return "Person{" + "name='" + name + '\'' + ", id=" + id + ", eatrice=" + eatrice + '}';
    }
}
新建AppDataBase

以后任何新建的其他表單只需要在這里里面配置一下就OK了,包括entities里面和方法那一塊

PersonStateDao personStateDao = AppDataBase.getInstance().getPersonStateDao();就是拿到PersionStateDao的表單,然后進一步進行操作,也就是說,如果有多個表單,都需要在這里配置,拿任何一個表單都需要AppDataBase.getInstance().xxxx

//需要用到哪些表單,一定要.class,否則加載不到
@Database(entities = {PersonStateBean.class}, version = 1)
public abstract class AppDataBase extends RoomDatabase{

    private static AppDataBase instance;
    private static final String DBName = "testRoom";

    //拿到對應的表單對象,這個表單內部的方法是供你條件查詢或者其他處理的,如果有其他的表,一樣要在這里添加
    public abstract PersonStateDao getPersonStateDao();
    public static AppDataBase getInstance() {
        if (instance == null) {
            synchronized (AppDataBase.class) {
                if (instance == null) {
                    instance = createDB();
                }
            }
        }
        return instance;
    }

    private static AppDataBase createDB(){
        return Room.databaseBuilder(ContextProvider.get().getContext(), AppDataBase.class, DBName  + ".db").addCallback(new Callback() {
            @Override
            public void onCreate(@NonNull SupportSQLiteDatabase db) {
                super.onCreate(db);
                Log.d("AppDataBase", "oncreat");
            }

            @Override
            public void onOpen(@NonNull SupportSQLiteDatabase db) {
                super.onOpen(db);
                Log.d("AppDataBase", "onOpen");
            }
        }).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_1).allowMainThreadQueries().build();
    }

    static Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("DROP TABLE IF EXISTS LessonVerBean");
            database.execSQL("CREATE TABLE IF NOT EXISTS LessonVerBean(" +
                    "id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
                    "lesson_id INTEGER NOT NULL" +
                    ",version INTEGER NOT NULL,type INTEGER NOT NULL)");
        }
    };

    static Migration MIGRATION_2_1 = new Migration(2, 1) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("DROP TABLE IF EXISTS LessonVerBean");
        }
    };
}
新建表格式屬性PersonStateBean

你想記錄工人的部分屬性,比如工號,是否吃飯的狀態,他們還有一個共同屬性是人(后期為了拿到所有工人表),注意這里不是數據源的屬性,這里的屬性由你定,根據業務,能快速查詢,比如根據id查對應的人,全部吃過飯的工人的數目,當然,這里也可以加個name屬性,但是這里的業務不需要。

@Entity
public class PersonStateBean{

    @PrimaryKey(autoGenerate = true)
    public int id;

    @ColumnInfo(name = "person_id")
    public int personId;

    @ColumnInfo(name = "is_eat")
    public boolean isEat;

    @ColumnInfo(name = "type")
    public int type;
}
新建表單PersonStateDao(這里面真正可以進行增刪改查的具體操作)
@Dao
public interface PersonStateDao extends BaseDao<PersonStateBean>{

    //根據id精確查找某一個persion
    @Query("select *from personstatebean where person_id=(:personId)")
    PersonStateBean queryPersonById(int personId);

    //把吃了飯的人全部找出來
    @Query("select * from personstatebean where is_eat=(:isEat)")
    PersonStateBean queryListPersonByEat(boolean isEat);

    //把所有人找出來(他們的共有屬性,是自己定的type=1)
    @Query("select * from personstatebean where type=(:type)")
    List<PersonStateBean> queryListPersonByType(int type);
}
BaseDao是提供的公有父類,封裝了增加刪除功能,如果表對象有沖突直接替換的功能。
@Dao
public interface BaseDao<T> {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(T item);

    @Insert
    void insertItems(List<T> items);

    @Delete
    void delete(T item);

    @Delete
    void deleteItems(T items);
}
直接在Activity調用
public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private List<Person> list=new ArrayList<>();;
    private MyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = findViewById(R.id.recycleview);
        LinearLayoutManager linearLayoutManage = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
        recyclerView.setLayoutManager(linearLayoutManage);
        adapter = new MyAdapter(list, this);
        initData();
        recyclerView.setAdapter(adapter);
        initListener();

    }



    private void initListener(){
        adapter.setListener(new MyAdapter.AdapterListener(){
            @Override
            public void onclick(int position){
                boolean eatrice =list.get(position).isEatrice();
                eatrice = !eatrice;
                list.get(position).setEatrice(eatrice);
                adapter.notifyDataSetChanged();
                //改變數據庫
                Person person = list.get(position);
                int id = person.getId();
                PersonStateBean personStateBean = personStateDao.queryPersonById(id);
                if(null!=personStateBean){
                    personStateBean.isEat=eatrice;
                    personStateDao.insert(personStateBean);
                }
            }
        });
    }

    //查詢數據庫,數據庫有數據沿用數據庫,如果沒有代表第一次進入用初始化的數據
    PersonStateDao personStateDao = AppDataBase.getInstance().getPersonStateDao();
    private void initData(){
        getServerData();

        //這里所有person在表里面有的共有屬性都是1,區分是不是第一次進來
        List<PersonStateBean> listPersonStateBean = personStateDao.queryListPersonByType(1);
        if(null == listPersonStateBean||listPersonStateBean.size()==0){
            for(int i = 0; i < list.size(); i++){
                PersonStateBean personStateBean = new PersonStateBean();
                personStateBean.isEat = false;
                personStateBean.personId = list.get(i).getId();
                personStateBean.type = 1;
                personStateDao.insert(personStateBean);
            }
        }else{
            for(int i = 0; i < list.size(); i++){
                Person person = list.get(i);
                PersonStateBean personStateBean = personStateDao.queryPersonById(person.getId());
                if(personStateBean != null){
                    //殺掉程序后,沿用以數據庫當初存的為準,服務器不愿意改狀態
                    boolean isEat = personStateBean.isEat;
                    list.get(i).setEatrice(isEat);
                }
            }
        }

        adapter.notifyDataSetChanged();//數據庫取出來刷新
    }

    //第一次請求的時候,服務器使用就給你這些固定的數據,本地保存數據把,卸載之后就沒有,可以用做搜索歷史
    private void getServerData(){
        list.add(new Person("張三", 1, false));
        list.add(new Person("李四", 2, false));
        list.add(new Person("王五", 3, false));
        list.add(new Person("哈哈1", 4, false));
        list.add(new Person("哈哈2", 5, false));
        list.add(new Person("哈哈3", 6, false));
        list.add(new Person("哈哈4", 7, false));
        list.add(new Person("哈哈5", 8, false));
        list.add(new Person("哈哈6", 9, false));
        list.add(new Person("哈哈7", 10, false));
        list.add(new Person("哈哈8", 11, false));
    }
監聽器刷新
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{

    List<Person>list;
    Context context;

    public MyAdapter(List<Person> list, Context context){
        this.list = list;
        this.context = context;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
        View view= LayoutInflater.from(context).inflate(R.layout.item_persion,parent,false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, final int position){
        holder.tv_name.setText(list.get(position).getName());
        holder.tv_id.setText("工牌:"+list.get(position).getId());
        holder.tv_iseat.setText(list.get(position).isEatrice()?"吃飯了":"沒吃飯");

        holder.itemView.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                if(adapterListener!=null){
                    adapterListener.onclick(position);
                }
            }
        });
    }

    @Override
    public int getItemCount(){
        return list.size();
    }


    AdapterListener adapterListener;
    public void setListener(AdapterListener listener){
        adapterListener=listener;
    }

    public interface AdapterListener{
        void onclick(int position);

    }


    public class MyViewHolder extends RecyclerView.ViewHolder{

        TextView tv_name;
        TextView tv_id;
        TextView tv_iseat;
        public MyViewHolder(@NonNull View itemView){
            super(itemView);
            tv_name=itemView.findViewById(R.id.tv_name);
            tv_id=itemView.findViewById(R.id.tv_id);
            tv_iseat=itemView.findViewById(R.id.tv_iseat);
        }
    }
}

github地址:https://github.com/283006603/room 有什么問題可以QQ問我的。

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,224評論 6 529
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,916評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,014評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,466評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,245評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,795評論 1 320
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,869評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,010評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,524評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,487評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,634評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,173評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,884評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,282評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,541評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,236評論 3 388
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,623評論 2 370