GreenDao数据库1:1,1:N,N:N学习笔记

自从用上GreenDao框架之后,其他的ORM数据库框架都很少用了,因为GreenDao使用起来很方便,唯一的缺点就是数据库升级稍微麻烦了一点。具体的使用方式网上有很多教程,这里我只是记录一下数据库表单关联的笔记。

一,添加GreenDao的依赖以及初始化数据库

  1. 在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
    }
}
  1. 在Module的build.gradle中天下如下依赖:
apply plugin: 'org.greenrobot.greendao' // apply plugin
 
dependencies {
    implementation 'org.greenrobot:greendao:3.2.2' // add library
}
  1. 在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.这就是我们说额多表关联,其实根据具体的需求,我们还可能实现更复杂的关联关系,比如多层关联,但是都离不开这三种关联方式。以上就是自己工作之外整理的一个小知识,有不对的地方还请指出。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容