GreenDao資料庫一對一,一對多,多對多學習筆記
自從用上GreenDao框架之後,其他的ORM資料庫框架都很少用了,因為GreenDao使用起來很方便,唯一的缺點就是資料庫升級稍微麻煩了一點。具體的使用方式網上有很多教程,這裡我只是記錄一下資料庫表單關聯的筆記。
一,新增GreenDao的依賴以及初始化資料庫
- 在project的build.gradle中天下如下依賴:
buildscript { repositories { jcenter() mavenCentral() // add repository } dependencies { classpath 'com.android.tools.build:gradle:3.1.1' classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin } }
- 在Module的build.gradle中天下如下依賴:
apply plugin: 'org.greenrobot.greendao' // apply plugin dependencies { implementation 'org.greenrobot:greendao:3.2.2' // add library }
- 在Module的build.gradle中對Greendao進行配置:
//greendao配置 greendao { //版本號,升級時可配置 schemaVersion 1 daoPackage 'com.example.testgreendao.entity' targetGenDir 'src/main/java' }
以上全部配置好了之後,我們需要對資料庫進行初始化:
public class GreendaoUtil { private static DaoMaster.DevOpenHelper mHelper; private static SQLiteDatabase mDb; private static DaoMaster mDaomaster; private static DaoSession mDaoSession; private static GreendaoUtil mInstance; public static GreendaoUtil getmInstance() { if (mInstance == null) { synchronized (GreendaoUtil.class) { if (mInstance == null) { mInstance = new GreendaoUtil(); } } } return mInstance; } public static void initDataBase(Context context){ mHelper=new DaoMaster.DevOpenHelper(context,"school.db",null); mDb=mHelper.getWritableDatabase(); mDaomaster=new DaoMaster(mDb); mDaoSession=mDaomaster.newSession(); } public static DaoSession getDaoSession(){ return mDaoSession; } }
資料庫的初始化工作最好放在自定義的Application中執行,這樣我們就可以很方便的對各資料庫進行增刪改查操作了。
以上就是我們全部的準備工作了,下面先看一下資料庫一對一的操作:
一,資料庫1:1關聯
一對一關聯我們用到了@ToOne註解
@Entity(nameInDb = "db_student") public class Student { @Id private Long id; @Unique private String name; @Unique private Integer age; private Long bagId; @ToOne(joinProperty = "bagId") Bag bag;
其中最主要的就是bagId這個欄位,他是Bag類的外主鍵,就是通過這個欄位與Bag類進行一一對應。下面是具體的實現:
public class MainActivity extends AppCompatActivity { private static StudentDao mStudentDao; private static BagDao mBagDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initDao(); testToOne(); } /** * 初始化所需的Dao類 */ private void initDao() { mStudentDao=GreendaoUtil.getmInstance().getDaoSession().getStudentDao(); mBagDao=GreendaoUtil.getmInstance().getDaoSession().getBagDao(); } /** * GreenDao一對一關聯 */ private void testToOne() { Bag bag=new Bag(); bag.setColor("黑色"); mBagDao.save(bag); Student student=new Student(); student.setName("棟樑"); student.setAge(18); student.setBagId(bag.getId()); mStudentDao.save(student); } }
這樣就將Bag與Student對應起來了,後面該Bag更新後,Studen中的Bag也會自動更新。
二,資料庫1:N關聯
我們用以下情景舉個例,一個學生是可以有很多書本的,這裡我們需要@ToMany註解。
@Entity(nameInDb = "db_book") public class Book { @Id private Long id; @Property(nameInDb = "book_name") private String bookName; private Long studentId;
@Entity(nameInDb = "db_student") public class Student { @Id private Long id; @Unique private String name; @Unique private Integer age; private Long bagId; @ToOne(joinProperty = "bagId") Bag bag; @ToMany(referencedJoinProperty = "studentId") List<Book>bookList;
編譯後我們發現沒有setBookList的方法,這裡需要我們手動新增上去
public void setBookList(List<Book>bookList){ this.bookList=bookList; }
其中,studentId是作為Student的外主鍵與BooK進行關聯,下面是具體的使用:
private void testOneToMany() { List<Book>books=new ArrayList<>(); Student student=new Student(); Book bookA=new Book(); bookA.setBookName("英語"); bookA.setStudentId(student.getId()); mBookDao.save(bookA); Book bookB=new Book(); bookB.setBookName("數學"); bookB.setStudentId(student.getId()); mBookDao.save(bookB); Book bookC=new Book(); bookC.setBookName("語文"); bookC.setStudentId(student.getId()); mBookDao.save(bookC); books.add(bookA); books.add(bookB); books.add(bookC); student.setAge(20); student.setName("花朵"); student.setBookList(books); mStudentDao.save(student); }
這樣,名叫"花朵"的Student就與後面的三本書關聯起來了,當其中的書進行修改或者刪除操作時,也會影響到資料庫中的Student。
三,資料庫N:N關聯
GreenDao是預設不支援直接進行多對多關聯的,我們需要藉助中間表進行關聯。
我們接著上面的情景,一名同學可以擁有多本書籍,同樣的,擁有同種書籍的也可以是多名同學。這裡我們使用到了@ToMany,@JoinEntity這兩個註解。
@Entity(nameInDb = "db_student_b") public class StudentB { @Id private Long id; @Unique private String name; @Unique private Integer age; @ToMany() @JoinEntity(entity = StudentBook.class, sourceProperty = "studentId", targetProperty = "bookId") private List<BookB> bookBList;
@Entity(nameInDb = "db_book_b") public class BookB { @Id private Long id; @Property(nameInDb = "book_name") private String bookName; @ToMany @JoinEntity(entity = StudentBook.class, sourceProperty = "bookId", targetProperty = "studentId") private List<StudentB>studentList;
@Entity(nameInDb = "db_student_book") public class StudentBook { @Id private Long id; private Long studentId; private Long bookId;
這樣,我們的資料庫就建好了,其中,StudentBook表是作為中間表關聯其他的兩張表。蝦米那是我們具體的實現:
private void testManyToMany(){ StudentB student1=new StudentB(); student1.setName("張三"); student1.setAge(22); mStudentBDao.save(student1); StudentB student2=new StudentB(); student2.setName("李四"); student2.setAge(25); mStudentBDao.save(student2); BookB book1=new BookB(); book1.setBookName("吶喊"); mBookBDao.save(book1); BookB book2=new BookB(); book2.setBookName("活著"); mBookBDao.save(book2); StudentBook studentBookA=new StudentBook(); studentBookA.setStudentId(student1.getId()); studentBookA.setBookId(book1.getId()); mStudentBookDao.save(studentBookA); StudentBook studentBookB=new StudentBook(); studentBookB.setStudentId(student1.getId()); studentBookB.setBookId(book2.getId()); mStudentBookDao.save(studentBookB); StudentBook studentBookC=new StudentBook(); studentBookC.setStudentId(student2.getId()); studentBookC.setBookId(book2.getId()); mStudentBookDao.save(studentBookC); }
這樣,我們就做到了student1中有book1和book2,book1中又有student1和student2.這就是我們說額多表關聯,其實根據具體的需求,我們還可能實現更復雜的關聯關係,比如多層關聯,但是都離不開這三種關聯方式。以上就是自己工作之外整理的一個小知識,有不對的地方還請指出。