Jetpack---Room數(shù)據(jù)庫(kù)

Room數(shù)據(jù)庫(kù)和GreenDao使用都差不多,定義的實(shí)體類(lèi)都是用的注解方式蚓曼。如果項(xiàng)目里面使用了GreenDao,沒(méi)有必要去遷移Room.好處就是支持同為Android Architecture Component的LiveData镶摘,實(shí)現(xiàn)數(shù)據(jù)的動(dòng)態(tài)刷新和綁定組件生命周期功能砾脑。根據(jù)項(xiàng)目而定吧,性能方面也差不多传透。屬于jetpack耘沼,就順帶著學(xué)習(xí)一下。官網(wǎng)全是kotlin表達(dá)的朱盐。

設(shè)想一個(gè)場(chǎng)景群嗤,一個(gè)activity,加載一個(gè)recycleView,數(shù)據(jù)源每次初始化的時(shí)候兵琳,從服務(wù)器拿到都是一樣的數(shù)據(jù)狂秘,如果有個(gè)需求骇径,后臺(tái)每次就給你11個(gè)工人的信息,信息包含了姓名者春,工牌破衔,是否吃飯。我們要記錄他到底有沒(méi)有吃飯钱烟,這樣用sp就比較復(fù)雜了晰筛。只能是把他們一個(gè)個(gè)狀態(tài)保存在本地。這樣跟狀態(tài)欄搜索歷史很像拴袭,卸載了就沒(méi)有了读第,卸載了還有的話只能說(shuō)這種是拉取得后臺(tái),今天只講狀態(tài)保存在本地拥刻。

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

可以理解為數(shù)據(jù)源的bean類(lèi)型

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的表單,然后進(jìn)一步進(jìn)行操作泰佳,也就是說(shuō)盼砍,如果有多個(gè)表單,都需要在這里配置逝她,拿任何一個(gè)表單都需要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";

    //拿到對(duì)應(yīng)的表單對(duì)象黔宛,這個(gè)表單內(nèi)部的方法是供你條件查詢或者其他處理的近刘,如果有其他的表,一樣要在這里添加
    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

你想記錄工人的部分屬性臀晃,比如工號(hào)觉渴,是否吃飯的狀態(tài),他們還有一個(gè)共同屬性是人(后期為了拿到所有工人表),注意這里不是數(shù)據(jù)源的屬性徽惋,這里的屬性由你定案淋,根據(jù)業(yè)務(wù),能快速查詢险绘,比如根據(jù)id查對(duì)應(yīng)的人踢京,全部吃過(guò)飯的工人的數(shù)目,當(dāng)然宦棺,這里也可以加個(gè)name屬性瓣距,但是這里的業(yè)務(wù)不需要。

@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(這里面真正可以進(jìn)行增刪改查的具體操作)
@Dao
public interface PersonStateDao extends BaseDao<PersonStateBean>{

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

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

    //把所有人找出來(lái)(他們的共有屬性代咸,是自己定的type=1)
    @Query("select * from personstatebean where type=(:type)")
    List<PersonStateBean> queryListPersonByType(int type);
}
BaseDao是提供的公有父類(lèi)蹈丸,封裝了增加刪除功能,如果表對(duì)象有沖突直接替換的功能。
@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調(diào)用
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();
                //改變數(shù)據(jù)庫(kù)
                Person person = list.get(position);
                int id = person.getId();
                PersonStateBean personStateBean = personStateDao.queryPersonById(id);
                if(null!=personStateBean){
                    personStateBean.isEat=eatrice;
                    personStateDao.insert(personStateBean);
                }
            }
        });
    }

    //查詢數(shù)據(jù)庫(kù)逻杖,數(shù)據(jù)庫(kù)有數(shù)據(jù)沿用數(shù)據(jù)庫(kù)慨默,如果沒(méi)有代表第一次進(jìn)入用初始化的數(shù)據(jù)
    PersonStateDao personStateDao = AppDataBase.getInstance().getPersonStateDao();
    private void initData(){
        getServerData();

        //這里所有person在表里面有的共有屬性都是1,區(qū)分是不是第一次進(jìn)來(lái)
        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){
                    //殺掉程序后,沿用以數(shù)據(jù)庫(kù)當(dāng)初存的為準(zhǔn)弧腥,服務(wù)器不愿意改狀態(tài)
                    boolean isEat = personStateBean.isEat;
                    list.get(i).setEatrice(isEat);
                }
            }
        }

        adapter.notifyDataSetChanged();//數(shù)據(jù)庫(kù)取出來(lái)刷新
    }

    //第一次請(qǐng)求的時(shí)候厦取,服務(wù)器使用就給你這些固定的數(shù)據(jù),本地保存數(shù)據(jù)把管搪,卸載之后就沒(méi)有,可以用做搜索歷史
    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));
    }
監(jiān)聽(tīng)器刷新
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()?"吃飯了":"沒(méi)吃飯");

        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 有什么問(wèn)題可以QQ問(wèn)我的虾攻。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市更鲁,隨后出現(xiàn)的幾起案子霎箍,更是在濱河造成了極大的恐慌,老刑警劉巖澡为,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漂坏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡媒至,警方通過(guò)查閱死者的電腦和手機(jī)顶别,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)拒啰,“玉大人驯绎,你說(shuō)我怎么就攤上這事∧钡” “怎么了剩失?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)册着。 經(jīng)常有香客問(wèn)我拴孤,道長(zhǎng),這世上最難降的妖魔是什么甲捏? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任演熟,我火速辦了婚禮,結(jié)果婚禮上摊鸡,老公的妹妹穿的比我還像新娘绽媒。我一直安慰自己蚕冬,他們只是感情好免猾,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著囤热,像睡著了一般猎提。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,328評(píng)論 1 310
  • 那天锨苏,我揣著相機(jī)與錄音疙教,去河邊找鬼。 笑死伞租,一個(gè)胖子當(dāng)著我的面吹牛贞谓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播葵诈,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼裸弦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了作喘?” 一聲冷哼從身側(cè)響起理疙,我...
    開(kāi)封第一講書(shū)人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泞坦,沒(méi)想到半個(gè)月后窖贤,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贰锁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年赃梧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片豌熄。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡槽奕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出房轿,到底是詐尸還是另有隱情粤攒,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布囱持,位于F島的核電站夯接,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏纷妆。R本人自食惡果不足惜盔几,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掩幢。 院中可真熱鬧逊拍,春花似錦、人聲如沸际邻。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)世曾。三九已至缨恒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背骗露。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工岭佳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人萧锉。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓珊随,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親柿隙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子玫恳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359