美文网首页
Jetpack---Room数据库

Jetpack---Room数据库

作者: 大苏打6815 | 来源:发表于2020-09-16 11:18 被阅读0次

    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问我的。

    相关文章

      网友评论

          本文标题:Jetpack---Room数据库

          本文链接:https://www.haomeiwen.com/subject/sxscyktx.html