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)我的虾攻。