当前位置:网站首页>Jetpack - basic use of room

Jetpack - basic use of room

2022-06-13 06:25:00 m0_ forty-seven million nine hundred and fourteen thousand one

  Android use SQLite Store as a database , Common in the open source community ORM(Object Relational Mappi
ng) Library has ORMLite,GreenDAO etc. .Room Like other libraries , Also in SQLite A layer of encapsulation is provided on the .

One .Room Use

1.Room Important concepts

Entity: Entity class , It corresponds to a table structure of the database , Using annotations @Entity Mark .
Dao: Contains access to a series of ways to access the database , Using annotations @Dao Mark .
Database: Database holder , As the main access point for the underlying connection of data related to application persistence . Use
annotation @Database Mark , In addition, the following conditions must be met : The defined class must be a class inherited from RoomDatab
ase The abstract class of , In the annotation, you need to define the list of entity classes associated with the database . Contains an extract with no parameters
Like a method and returns a Dao object .
 

2.Room application

First, add dependencies

    implementation "androidx.room:room-runtime:2.3.0"
    annotationProcessor "androidx.room:room-compiler:2.3.0"
// Table name 
@Entity(tableName = "student")
public class Student {
    // Self increasing 
    @PrimaryKey(autoGenerate = true)
    /**
     * name     Field names in the table 
     * typeAffinity   Field type 
     */
    @ColumnInfo(name="id",typeAffinity = ColumnInfo.INTEGER)
    public int id;

    @ColumnInfo(name ="name",typeAffinity = ColumnInfo.TEXT)
    public String name;

    @ColumnInfo(name = "age",typeAffinity = ColumnInfo.INTEGER)
    public int age;
                    
    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    @Ignore   //Room The database will not be initialized with this 
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Ignore   //Room The database will not be initialized with this 
    public Student(int id) {
        this.id=id;
    }

}
     
  

First write an entity class (Entity class ), This entity class is the table we will store in the database , Entity class fields are the same as the fields in the table A corresponding . 

@Dao
public interface StudentDao {
     // increase 
    @Insert
    void insertStudent(Student... Student);
    
    // Delete 
    @Delete
    void deleteStudent(Student... Student);

    // Change 
    @Update
    void UpdateStudent(Student... Student);

    // Full investigation 
    @Query("SELECT * FROM  student")
    List<Student> getAllStudent();

    // Condition check 
    @Query("SELECT * FROM student WHERE id=:id")
    List<Student> getAStudent(int id);

}

Defined here Dao class , Define several methods for adding, deleting, modifying, and querying operation tables .

/**
 * entities     Is an array to configure your entity class here 
 * version      Database version number 
 * exportSchema   A wrong file , This place is closed first 
 */
@Database(entities = {Student.class},version = 1, exportSchema = false)
public abstract class MyDataBase extends RoomDatabase {
    // Database name 
    private static final String DATABASE_NAME="my_db";
    private static MyDataBase sMyDataBase;
    // You cannot create your own constructor here 
     public static MyDataBase getMyDataBase(Context mContext){
        if (sMyDataBase==null)
            sMyDataBase = Room.databaseBuilder(mContext.getApplicationContext(), MyDataBase.class, DATABASE_NAME)
                    //.allowMainThreadQueries()    This method can be called to operate the database in the main thread 
                    .addMigrations()
                    .build();
    return sMyDataBase;
    }


    // obtain Student object 
    public abstract StudentDao getStudentDao();

}

In this Database Class Room database .

public class MainActivity extends AppCompatActivity {

    private StudentDao mStudentDao;
    private StudentRecyclerViewAdapter mStudentRecyclerViewAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RecyclerView recycleView = findViewById(R.id.recycleView);
        ArrayList<Student> students = new ArrayList<>();

        mStudentRecyclerViewAdapter = new StudentRecyclerViewAdapter(students);
        recycleView.setLayoutManager(new LinearLayoutManager(this));
        recycleView.setAdapter(mStudentRecyclerViewAdapter);

        MyDataBase myDataBase = MyDataBase.getMyDataBase(this);
        mStudentDao = myDataBase.getStudentDao();

    }

    public void mInsert(View view) {
        Student[] m={new Student("Jack",20),new Student("xiaohua",20)};
        new InsertStudentTask(mStudentDao).execute(m);
    }

    class InsertStudentTask extends AsyncTask<Student,Void,Void>{
        private StudentDao mStudentDao;

        public InsertStudentTask(StudentDao pStudentDao) {
            mStudentDao = pStudentDao;
        }

        @Override
        protected Void doInBackground(Student... pStudents) {

            mStudentDao.insertStudent(pStudents);
            return null;
        }
    }


    public void mDelete(View view) {
        new DeleterStudentTask(mStudentDao).execute(new Student(2));
    }

    public void mUpdate(View view) {
        new UpdateStudentTask(mStudentDao).execute(new Student(4,"xiaogang",21));

    }

    class DeleterStudentTask  extends AsyncTask<Student,Void,Void>{
        private StudentDao mStudentDao;

        public DeleterStudentTask(StudentDao pStudentDao) {
            mStudentDao = pStudentDao;
        }

        @Override
        protected Void doInBackground(Student... pStudents) {

            mStudentDao.deleteStudent(pStudents);
            return null;
        }
    }


    class UpdateStudentTask  extends AsyncTask<Student,Void,Void>{
        private StudentDao mStudentDao;

        public UpdateStudentTask(StudentDao pStudentDao) {
            mStudentDao = pStudentDao;
        }

        @Override
        protected Void doInBackground(Student... pStudents) {

            mStudentDao.UpdateStudent(pStudents);
            return null;
        }
    }


    public void mQuery(View view) {
        new GetAllStudentTask(mStudentDao).execute();
    }
    class GetAllStudentTask  extends AsyncTask<Void,Void,Void>{
        private StudentDao mStudentDao;

        public GetAllStudentTask(StudentDao pStudentDao) {
            mStudentDao = pStudentDao;
        }

        @Override
        protected Void doInBackground(Void... pStudents) {

            List<Student> allStudent = mStudentDao.getAllStudent();
            mStudentRecyclerViewAdapter.setStudents(allStudent);
            return null;
        }

        @Override
        protected void onPostExecute(Void pVoid) {
            super.onPostExecute(pVoid);
            mStudentRecyclerViewAdapter.notifyDataSetChanged();
        }
    }
}

stay Activity Use in AsyncTask Reference addition, deletion, modification and query functions , Operating the database .

Demonstration effect :

        

2.Room+ViewModel+LiveData

// Table name 
@Entity(tableName = "student")
public class Student {
    // Self increasing 
    @PrimaryKey(autoGenerate = true)
    /**
     * name     Field names in the table 
     * typeAffinity   Field type 
     */
    @ColumnInfo(name="id",typeAffinity = ColumnInfo.INTEGER)
    public int id;

    @ColumnInfo(name ="name",typeAffinity = ColumnInfo.TEXT)
    public String name;

    @ColumnInfo(name = "age",typeAffinity = ColumnInfo.INTEGER)
    public int age;

/*    @ColumnInfo(name = "sex",typeAffinity = ColumnInfo.TEXT)
    public String sex;

    @ColumnInfo(name = "aa",typeAffinity = ColumnInfo.INTEGER)
    public int aa;*/

                    
    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    @Ignore   //Room The database will not be initialized with this 
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Ignore   //Room The database will not be initialized with this 
    public Student(int id) {
        this.id=id;
    }


}
@Dao
public interface StudentDao {
    // insert 
    @Insert
    void insertStudent(Student... Student);

    // Delete 
    @Delete
    void deleteStudent(Student... Student);
    // Delete all 
    @Query("DELETE  FROM student")
    void deleteAllStudent();
    // Change 
    @Update
    void UpdateStudent(Student... Student);
    
    // Full investigation 
    @Query("SELECT * FROM  student")
    LiveData<List<Student>> getAllStudent();

    // Condition check 
    @Query("SELECT * FROM student WHERE id=:id")
    List<Student> getAStudent(int id);

}
/**
 * entities     Is an array to configure your entity class here 
 * version      Database version number 
 * exportSchema   A wrong file , This place is closed first 
 */
                                                //Schema Files can be checked for errors 
@Database(entities = {Student.class},version = 1, exportSchema = false)
public abstract class MyDataBase extends RoomDatabase {
    private static final String DATABASE_NAME= "my.db";
    private static MyDataBase sMyDataBase;
    // You cannot create your own constructor here 
     public static MyDataBase getMyDataBase(Context mContext){
        if (sMyDataBase==null)
            sMyDataBase = Room.databaseBuilder(mContext.getApplicationContext(),                     
          MyDataBase.class, DATABASE_NAME)
                    .build();
    return sMyDataBase;
    }


    public abstract StudentDao getStudentDao();

}
public class StudentRepository {
        private   StudentDao mStudentDao;
    public StudentRepository(Context pContext) {
            if (mStudentDao==null){
                MyDataBase myDataBase = MyDataBase.getMyDataBase(pContext);
                mStudentDao= myDataBase.getStudentDao();
            }
    }


    // increase 
    public void InsertStudent(Student... pStudents) {

        new InsertStudentTask(mStudentDao).execute(pStudents);
    }


    class InsertStudentTask extends AsyncTask<Student,Void,Void> {
        private StudentDao mStudentDao;

        public InsertStudentTask(StudentDao pStudentDao) {
            mStudentDao = pStudentDao;
        }

        @Override
        protected Void doInBackground(Student... pStudents) {

            mStudentDao.insertStudent(pStudents);
            return null;
        }
    }
    
    // Delete 
    public void DeleterStudent(int  id) {
        new DeleterStudentTask(mStudentDao).execute(new Student(id));
    }
    
    // Delete all 
    public void DeleterAllStudent() {
        new DeleterAllStudentTask(mStudentDao).execute();
    }

    // Change 
    public void UpdateStudentTask(Student pStudents) {

        new UpdateStudentTask(mStudentDao).execute(new Student(pStudents.id,pStudents.name,pStudents.age));
    }
    // Check here for LiveData
    public LiveData<List<Student>> selectStudent(Student... pStudents) {
      return mStudentDao.getAllStudent();
    }



    class DeleterStudentTask  extends AsyncTask<Student,Void,Void>{
        private StudentDao mStudentDao;

        public DeleterStudentTask(StudentDao pStudentDao) {
            mStudentDao = pStudentDao;
        }

        @Override
        protected Void doInBackground(Student... pStudents) {

            mStudentDao.deleteStudent(pStudents);
            return null;
        }
    }

    class DeleterAllStudentTask  extends AsyncTask<Student,Void,Void>{
        private StudentDao mStudentDao;

        public DeleterAllStudentTask(StudentDao pStudentDao) {
            mStudentDao = pStudentDao;
        }

        @Override
        protected Void doInBackground(Student... pStudents) {
            mStudentDao.deleteAllStudent();
            return null;
        }
    }

    
    class UpdateStudentTask  extends AsyncTask<Student,Void,Void>{
        private StudentDao mStudentDao;

        public UpdateStudentTask(StudentDao pStudentDao) {
            mStudentDao = pStudentDao;
        }

        @Override
        protected Void doInBackground(Student... pStudents) {

            mStudentDao.UpdateStudent(pStudents);
            return null;
        }
    }
}

In this class, the thread switching operation of adding, deleting, changing and querying functions of the operation database

public class MyViewModel extends AndroidViewModel {

    private final StudentRepository mStudentRepository;

    public MyViewModel(@NonNull Application application) {
        super(application);
        mStudentRepository = new StudentRepository(application);

    }


    public void InsertStudent(Student... pStudents) {
        mStudentRepository.InsertStudent(pStudents);

    }



    public void DeleterStudent(int  id) {
          mStudentRepository.DeleterStudent(id);
    }

    public void DeleterAllStudent() {
        mStudentRepository.DeleterAllStudent();
    }

    public void UpdateStudentTask(Student pStudents) {

        mStudentRepository.UpdateStudentTask(new Student(pStudents.id,pStudents.name,pStudents.age));
    }

    public LiveData<List<Student>> selectStudent() {
        return mStudentRepository.selectStudent();
    }

}

ViewModel As an intermediate transition layer .

public class MainActivity extends AppCompatActivity {

    private StudentDao mStudentDao;
    private StudentRecyclerViewAdapter mStudentRecyclerViewAdapter;
    private MyViewModel mViewModel;
    private int p=1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RecyclerView recycleView = findViewById(R.id.recycleView);
        ArrayList<Student> students = new ArrayList<>();

        mStudentRecyclerViewAdapter = new StudentRecyclerViewAdapter(students);
        recycleView.setLayoutManager(new LinearLayoutManager(this));
        recycleView.setAdapter(mStudentRecyclerViewAdapter);

        mViewModel = new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(MyViewModel.class);
        mViewModel.selectStudent().observe(this, new Observer<List<Student>>() {
            @Override
            public void onChanged(List<Student> pStudents) {
                mStudentRecyclerViewAdapter.setStudents(pStudents);
                mStudentRecyclerViewAdapter.notifyDataSetChanged();
            }
        });

    }

    public void mInsert(View view) {
        Student[] m={new Student("Jack",20),new Student("xiaohua",20)};
        mViewModel.InsertStudent(m);
    }

    public void mDelete(View view) {
       // new DeleterStudentTask(mStudentDao).execute(new Student(2));
        mViewModel.DeleterStudent(p++);
    }

    public void mUpdate(View view) {
        mViewModel.UpdateStudentTask(new Student(4,"xiaogang",21));
    }

    public void mQuery(View view) {
        mViewModel.DeleterAllStudent();

    }
}

This use liveData Once the database is modified, it will immediately start to callback and update UI

Demonstration effect :

3.Room Database upgrade

Room1 l 2 edition .

/**
 * entities     Is an array to configure your entity class here 
 * version      Database version number , Add... When upgrading 1
 * exportSchema   A wrong file , This place is closed first 
 */
                                                //Schema Files can be checked for errors 
@Database(entities = {Student.class},version = 2, exportSchema = false)
public abstract class MyDataBase extends RoomDatabase {
    private static final String DATABASE_NAME= "my.db";
    private static MyDataBase sMyDataBase;
    // You cannot create your own constructor here 
     public static MyDataBase getMyDataBase(Context mContext){
        if (sMyDataBase==null)
            sMyDataBase = Room.databaseBuilder(mContext.getApplicationContext(), MyDataBase.class, DATABASE_NAME)
                    //.allowMainThreadQueries()    This method can be called to operate the database in the main thread 
                    .addMigrations(MIGRATION_1_2)
                    .build();
    return sMyDataBase;
    }
        //ROOM Database upgrade method    When you want to upgrade across levels (1 To 4, He will do it in sequence 1 To 4 How to upgrade )   He will also execute the upgrade method in sequence 
    static final Migration  MIGRATION_1_2=new Migration(1,2){

        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE student ADD COLUMN sex INTEGER NOT NULL DEFAULT 1");
        }
    };




    public abstract StudentDao getStudentDao();

}

Here we are 1 l 2 When , use Sql Statement adds a field , So the entity class has to be changed .

// Table name 
@Entity(tableName = "student")
public class Student {
    // Self increasing 
    @PrimaryKey(autoGenerate = true)
    /**
     * name     Field names in the table 
     * typeAffinity   Field type 
     */
    @ColumnInfo(name="id",typeAffinity = ColumnInfo.INTEGER)
    public int id;

    @ColumnInfo(name ="name",typeAffinity = ColumnInfo.TEXT)
    public String name;

    @ColumnInfo(name = "age",typeAffinity = ColumnInfo.INTEGER)
    public int age;
    // Upgraded version 2 New fields added after 
    @ColumnInfo(name = "sex",typeAffinity = ColumnInfo.INTEGER)
    public int sex;

  /*  @ColumnInfo(name = "aa",typeAffinity = ColumnInfo.INTEGER)
    public int aa;*/

                    // Parameter and property names must have the same name 
    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    @Ignore   //Room The database will not be initialized with this 
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Ignore   //Room The database will not be initialized with this 
    public Student(int id) {
        this.id=id;
    }


}

Let's go back to 2 l 3, Other methods are the same as this .

/**
 * entities     Is an array to configure your entity class here 
 * version      Database version number , Add... When upgrading 1
 * exportSchema   A wrong file , This place is closed first 
 */
                                                //Schema Files can be checked for errors 
@Database(entities = {Student.class},version = 3, exportSchema = false)
public abstract class MyDataBase extends RoomDatabase {
    private static final String DATABASE_NAME= "my.db";
    private static MyDataBase sMyDataBase;
    // You cannot create your own constructor here 
     public static MyDataBase getMyDataBase(Context mContext){
        if (sMyDataBase==null)
            sMyDataBase = Room.databaseBuilder(mContext.getApplicationContext(), MyDataBase.class, DATABASE_NAME)
                    //.allowMainThreadQueries()    This method can be called to operate the database in the main thread 
                    .addMigrations(MIGRATION_1_2,MIGRATION_2_3)
                    .build();
    return sMyDataBase;
    }
        //ROOM Database upgrade method    When you want to upgrade across levels (1 To 4, He will do it in sequence 1 To 4 How to upgrade )   He will also execute the upgrade method in sequence 
    static final Migration  MIGRATION_1_2=new Migration(1,2){

        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE student ADD COLUMN sex INTEGER NOT NULL DEFAULT 1");
        }
    };


 static final Migration  MIGRATION_2_3=new Migration(2,3){

        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE student ADD COLUMN interest INTEGER NOT NULL DEFAULT 1");
        }
    };

    public abstract StudentDao getStudentDao();

}

Then change the entity class .

// Table name 
@Entity(tableName = "student")
public class Student {
    // Self increasing 
    @PrimaryKey(autoGenerate = true)
    /**
     * name     Field names in the table 
     * typeAffinity   Field type 
     */
    @ColumnInfo(name="id",typeAffinity = ColumnInfo.INTEGER)
    public int id;

    @ColumnInfo(name ="name",typeAffinity = ColumnInfo.TEXT)
    public String name;

    @ColumnInfo(name = "age",typeAffinity = ColumnInfo.INTEGER)
    public int age;

    @ColumnInfo(name = "sex",typeAffinity = ColumnInfo.INTEGER)
    public int sex;

    @ColumnInfo(name = "interest",typeAffinity = ColumnInfo.INTEGER)
    public int interest;

                    // Parameter and property names must have the same name 
    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    @Ignore   //Room The database will not be initialized with this 
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Ignore   //Room The database will not be initialized with this 
    public Student(int id) {
        this.id=id;
    }


}

In this way, the database version will be upgraded to 3 了 , Cross version upgrade is the same as what I wrote in my notes , Will be executed in ascending order 2 Upgrade function to the latest version .

4.Room abnormal

@Database(entities = {Student.class},version = 4, exportSchema = true)
public abstract class MyDataBase extends RoomDatabase {
    private static final String DATABASE_NAME= "my.db";
    private static MyDataBase sMyDataBase;
    // You cannot create your own constructor here 
     public static MyDataBase getMyDataBase(Context mContext){
        if (sMyDataBase==null)
            sMyDataBase = Room.databaseBuilder(mContext.getApplicationContext(), MyDataBase.class, DATABASE_NAME)
                    //.allowMainThreadQueries()    This method can be called to operate the database in the main thread 
                    .addMigrations(MIGRATION_1_2,MIGRATION_2_3/*,MIGRATION_3_4*/)
                    .fallbackToDestructiveMigration()  // This method reports an error when upgrading the database ( It's not because of changing the table structure )  Calling this method can forcibly upgrade data, but the original saved data will be lost 
                    .build();
    return sMyDataBase;
    }
        //ROOM Database upgrade method    When you want to upgrade across levels (1 To 4, He will do it in sequence 1 To 4 How to upgrade )   He will also execute the upgrade method in sequence 
    static final Migration  MIGRATION_1_2=new Migration(1,2){

        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE student ADD COLUMN sex INTEGER NOT NULL DEFAULT 1");
        }
    };

    static final Migration  MIGRATION_2_3=new Migration(2,3){

        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE student ADD COLUMN interest INTEGER NOT NULL DEFAULT 1");
        }
    };
   

    public abstract StudentDao getStudentDao();

}

Now I write the version number in the code as 4, But it didn't write 4 How to upgrade , This call fallbackToDestructiveMigraion function , You can avoid reporting errors , But the data will be cleared

5.Schema file

Room During each database upgrade , Will export a Schema file , This is a json File format , It contains the basic information of the database , With the document , The developer can know the previous changes of the database , It is very convenient for developers to troubleshoot problems .

   defaultConfig {

        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]// Specify database schema Export location 
            }
        }
    }

Now? gradle Configure this paragraph .

                                                    //Schema Files can be checked for errors 
@Database(entities = {Student.class},version = 4, exportSchema = true)
public abstract class MyDataBase extends RoomDatabase {
    private static final String DATABASE_NAME= "my.db";
    private static MyDataBase sMyDataBase;
    // You cannot create your own constructor here 
     public static MyDataBase getMyDataBase(Context mContext){
        if (sMyDataBase==null)
            sMyDataBase = Room.databaseBuilder(mContext.getApplicationContext(), MyDataBase.class, DATABASE_NAME)
                    //.allowMainThreadQueries()    This method can be called to operate the database in the main thread 
                    .build();
    return sMyDataBase;
  }
       
    public abstract StudentDao getStudentDao();
}

When creating a database, put exportSchema Property set to true, That's all right.

  The file will be here .

6. by Room Save as default

First, build a database and insert several pieces of data in it , The field name and type should be the same as Room The database should correspond to .

Then copy the database file to assets Under the folder .

And then there is the definition Room Just reference the database .

                                                    //Schema Files can be checked for errors 
@Database(entities = {Student.class},version = 4, exportSchema = true)
public abstract class MyDataBase extends RoomDatabase {
    private static final String DATABASE_NAME= "my.db";
    private static MyDataBase sMyDataBase;
    // You cannot create your own constructor here 
     public static MyDataBase getMyDataBase(Context mContext){
        if (sMyDataBase==null)
            sMyDataBase = Room.databaseBuilder(mContext.getApplicationContext(), MyDataBase.class, DATABASE_NAME)
                    //.allowMainThreadQueries()    This method can be called to operate the database in the main thread 
                    .createFromAsset("prestudent.db")      // Initial value of Fu   Copy the values of other tables into this table 
                   
                    .build();
    return sMyDataBase;
    }
}

Demonstration effect

7.TypeConverters

 A lot of times , Our entity class will have a layer of arrays , Then embed a data class similar to the following Json strand :
{
    "data": [
        {
            "category": " Source code ",
            "icon": "",
            "id": 22,
            "link": "https://www.androidos.net.cn/sourcecode",
            "name": "androidos",
            "order": 11,
            "visible": 1
        },
        {
            "category": " Source code ",
            "icon": "",
            "id": 41,
            "link": "http://androidxref.com/",
            "name": "androidxref",
            "order": 12,
            "visible": 1
        }  
    ],
    "errorCode": 0,
    "errorMsg": ""
}

At this time, we will use our TypeConverters 了 .

public class Department {
    @ColumnInfo(name = "departmentId")
    public int id;
    @ColumnInfo(name = "departmentName")
    public String name;

    public Department() {
    }

    @Ignore
    public Department(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

Here are the nested classes in our inner layer , No table name is set .

public class BaseListConvert<T> {
    @TypeConverter
    public List<T> revert(String jsonString) {
        //  Use Gson Method to json Format string Turn into List
        try {

            Type type = new TypeToken<ArrayList<T>>(){}.getType();
            List<T> list = new Gson().fromJson(jsonString,type);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @TypeConverter
    public String converter(List<T> list) {
        //  Use Gson Method to List Turn into json Format string, It's easy for us to parse 
        return new Gson().toJson(list);
    }

}

This is a tool class , There is no need to make any changes .

// Direct integration from BaseListConvert, Just pass in the type 
public class DepartmentListConvert extends BaseListConvert<Department> {

}

Which generic on the right here , Your nested data classes when needed .

@Entity(tableName = "user")  // Entity class creation needs to add @Entity annotation 
// Here we will refer to the previously defined tool class 
@TypeConverters({DepartmentListConvert.class})
public class User {

    @PrimaryKey(autoGenerate = true)
    @NonNull
    public int id;
    @ColumnInfo(name = "user_name")
    public String userName;
    @ColumnInfo(name = "user_age")
    public int userAge;
    @ColumnInfo(name = "user_mobile")
    public String userMobile;

        /**
         *  Single object only , No List/set
         *  Direct use @Embedded  Embedded in user In the table , namely user The columns in the table will be based on Department Attribute increase of 
         */
//    @Embedded
//    public Department department;

        public List<Department> departments;

    public User(/*int pId,*/ String userName, int userAge, String userMobile, List<Department> departments) {
 /*       id = pId;*/
        this.userName = userName;
        this.userAge = userAge;
        this.userMobile = userMobile;
        this.departments = departments;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                ", userAge=" + userAge +
                ", userMobile='" + userMobile + '\'' +
                ", departments=" + departments +
                '}';
    }
}

So it's done .

demo Address :RoomTest

原网站

版权声明
本文为[m0_ forty-seven million nine hundred and fourteen thousand one ]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202270555277108.html