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

Room數(shù)據(jù)庫(kù)和GreenDao使用都差不多,定義的實(shí)體類都是用的注解方式。如果項(xiàng)目里面使用了GreenDao,沒有必要去遷移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è)工人的信息,信息包含了姓名,工牌,是否吃飯。我們要記錄他到底有沒有吃飯,這樣用sp就比較復(fù)雜了。只能是把他們一個(gè)個(gè)狀態(tài)保存在本地。這樣跟狀態(tà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類型

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是提供的公有父類,封裝了增加刪除功能,如果表對(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ù),如果沒有代表第一次進(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ù)把,卸載之后就沒有,可以用做搜索歷史
    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)聽器刷新
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 有什么問(wèn)題可以QQ問(wèn)我的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容