Android--Jetpack--数据库Room详解二

本是青灯不归客,却因浊酒恋红尘

一,基本使用

关于Room数据库的基本使用,请参考文章Android--Jetpack--数据库Room详解一-CSDN博客

二,Room与ViewModle,LiveData的结合使用

LiveData与ViewModle的使用,请参考文章Android--Jetpack--LiveData-CSDN博客

我们通过结合Room与LiveData和ViewModle的使用,可以使当我们的数据库发生变化的时候,自动的去更新UI。

下面来看一个简单的使用案例:

1,还是 Android--Jetpack--数据库Room详解一-CSDN博客

中创建的数据库,表还是YuanZhen这张表, 我们把YuanZhenDao这个Dao类添加一个新的方法,使得可以查询到LiveData包装的集合:

@Dao
public interface YuanZhenDao {

    @Insert
    void insert(YuanZhen... yuanzhens);

    @Delete
    void delete(YuanZhen yuanZhen);

    @Update
    void update(YuanZhen yuanZhen);

    @Query("select * from YuanZhen")
    List getAll();

    @Query("select * from YuanZhen where name like :name")
    YuanZhen getByName(String name);

    @Query("select * from YuanZhen where age in(:ages)")
    List getByAges(int[] ages);

    @Query("select name,address from YuanZhen ")
    public List getNew();

   @Query("select * from YuanZhen")
    LiveData> getAllLiveDataYZ();
}

2,将数据库MyDatabase修改为单例模式:

@Database(entities = {YuanZhen.class},version = 1)
public abstract class MyDatabase extends RoomDatabase {

    private static MyDatabase instance;
    public static synchronized MyDatabase getInstance(Context context){
        if(instance==null){
            instance= Room.databaseBuilder(context.getApplicationContext(),MyDatabase.class
                            ,"YuanZhenDb")
                    .build();

        }
        return instance;
    }

    public abstract YuanZhenDao yuanZhenDao();

}

3,创建一个包装类,包装LiveData给ViewModel使用:

public class YuanZhenDecorate {

    private LiveData> liveDataAllYZ;

    private YuanZhenDao yuanZhenDao;

    public YuanZhenDecorate(Context context) {
        yuanZhenDao =MyDatabase.getInstance(context).yuanZhenDao();
        if(liveDataAllYZ==null){
            liveDataAllYZ=yuanZhenDao.getAllLiveDataYZ();
        }
    }
    void insert(YuanZhen... yuanZhens){
        yuanZhenDao.insert(yuanZhens);
    }
    void delete(YuanZhen yuanZhen){
        yuanZhenDao.delete(yuanZhen);
    }
    void update(YuanZhen yuanZhen){
        yuanZhenDao.update(yuanZhen);
    }
    List getAll(){
        return yuanZhenDao.getAll();
    }

    LiveData> getAllLiveDataYZ(){
        return yuanZhenDao.getAllLiveDataYZ();
    }

}

4,创建一个viewmodle:

public class YZViewModdel extends AndroidViewModel {

    private YuanZhenDecorate yuanZhenDecorate;

    public YZViewModdel(@NonNull Application application) {
        super(application);
        yuanZhenDecorate =new YuanZhenDecorate(application);
    }
    void insert(YuanZhen... yuanZhens){
        yuanZhenDecorate.insert(yuanZhens);
    }
    void delete(YuanZhen yuanZhen){
        yuanZhenDecorate.delete(yuanZhen);
    }
    void update(YuanZhen yuanZhen){
        yuanZhenDecorate.update(yuanZhen);
    }
    List getAll(){
        return yuanZhenDecorate.getAll();
    }

    LiveData> getAllLiveDataYZ(){
        return yuanZhenDecorate.getAllLiveDataYZ();
    }

}

5,创建一个recyclerview的adapter:

public class MyAdapter extends RecyclerView.Adapter {
    private LayoutInflater mLayoutInflater;

    private List mList;

    public MyAdapter(Context context,List mList) {
        mLayoutInflater =LayoutInflater.from(context);
        this.mList =mList;
    }

    public void setData(List mList) {
        this.mList = mList;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new ViewHolder(mLayoutInflater.inflate(R.layout.item, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        ((ViewHolder)holder).mTxt.setText(mList.get(position).getName());
    }

    @Override
    public int getItemCount() {
        if(mList!=null){
            return mList.size();
        }
        return 0;
    }

    class ViewHolder extends RecyclerView.ViewHolder {

        TextView mTxt;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            mTxt = (TextView) itemView.findViewById(R.id.txt);
        }
    }


}

 6,activity的xml布局:




    

7,item的xml布局:



    


 8,使用:

public class MainActivity extends AppCompatActivity {

    StudentViewModel studentViewModel;
    ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = findViewById(R.id.listView);

        studentViewModel = ViewModelProviders.of(this).get(StudentViewModel.class);
        studentViewModel.getAllLiveDataStudent().observe(this, new Observer>() {
            @Override
            public void onChanged(List students) {
                listView.setAdapter(new GoodsAdapter(MainActivity.this, students));
            }
        });

        for (int i = 0; i < 50; i++) {
            studentViewModel.insert(new Student("jett", "123", 1));
        }

        new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 50; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    studentViewModel.update(new Student(6, "jett" + i, "123", 1));
                }
            }
        }.start();

    }
}

 9,运行:

 

三,数据库的升级

1,强制升级,执行之后数据库的结构会发生变化,但是数据库的数据会丢失。

这种情况比较适合toB开发,数据库版本高降到低的情况,紧急发一版新的程序给现场升级。

使用 :fallbackToDestructiveMigration()

@Database(entities = {YuanZhen.class},version = 2)
public abstract class MyDatabase extends RoomDatabase {

    private static MyDatabase instance;
    public static synchronized MyDatabase getInstance(Context context){
        if(instance==null){
            instance= Room.databaseBuilder(context.getApplicationContext(),MyDatabase.class
                            ,"YuanZhenDb")
                    //强制升级
                    .fallbackToDestructiveMigration()
                    .build();

        }
        return instance;
    }

    public abstract YuanZhenDao yuanZhenDao();

}

 2,一般的升级方式

假如我们要增加一个字段price:

@Entity
public class YuanZhen {

    @PrimaryKey(autoGenerate = true)
    private int id;

    @ColumnInfo(name ="name")
    private String name;

    @ColumnInfo(name ="age")
    private int age;

    @ColumnInfo(name ="address")
    private String address;

    @ColumnInfo(name = "price")
    private int price;

    @Ignore
    private String sex;

    public YuanZhen(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getAddress() {
        return address;
    }

    @Override
    public String toString() {
        return "YuanZhen{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}

在MyDatabase中增加升级功能:

@Database(entities = {YuanZhen.class},version = 2,exportSchema = false)
public abstract class MyDatabase extends RoomDatabase {

    private static MyDatabase instance;
    public static synchronized MyDatabase getInstance(Context context){
        if(instance==null){
            instance= Room.databaseBuilder(context.getApplicationContext(),MyDatabase.class
                            ,"YuanZhenDb")
                    //强制升级
                   // .fallbackToDestructiveMigration()
                    .addMigrations(MIGRATION_1_2)
                    .build();

        }
        return instance;
    }

    public abstract YuanZhenDao yuanZhenDao();

    static final Migration MIGRATION_1_2=new Migration(1,2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            //在这里用sql脚本完成数据变化
            database.execSQL("alter table yuanzhen add column price integer not null default 1");
        }
    };

}

这里和greendao最大的不同就是,这里需要自己去写升级脚本,虽然增加了工作量,但是也更加灵活了。

你可能感兴趣的:(android-jetpack,android,android,jetpack,room,mvvm,livedata)