greendao详解及多表联查

一、集成

1、在Project的build.gradle中配置classpath

dependencies {

classpath 'com.android.tools.build:gradle:3.0.0'

classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin

}

2、在mode中的build.gradle中配置

1、配置apply

apply plugin: 'com.android.application'

apply plugin: 'org.greenrobot.greendao' // apply plugin

2、添加依赖

compile 'org.greenrobot:greendao:3.2.2' // add library

3、配置数据库版本以及代码生成位置

android {

greendao {

schemaVersion 1 //数据库的版本

daoPackage 'com.example.administrator.greendaodemo_h1709b.dao' // 一般为app包名+生成文件的文件夹名 文件生成的具体目录

targetGenDir 'src/main/java' //生成文件路径

}

}

二、写实体类,实体类就是你数据库的表

添加id Long类型,long的包装类

 

@Entity:设置表名,默认类名为表名

@Id:设置主键 @Id(autoincrement = true)设置自增长

@Property(nameInDb = "name")设置成员变量对应表中字段的名称

@NotNull//不能为空

@Unique//唯一约束

@Transient//成员变量不生成表字段

@Convert:指定自定义类型(@link PropertyConverter) 如果成员变量是集合,可以使用这个

@Generated:实体类的构造方法上使用,不自己调用,会自动生成

@Index:使用@Index作为一个属性来创建一个索引;定义多列索引(@link Entity#indexes()) //TODO 如何使用

@JoinEntity:定义表连接关系

@JoinProperty:定义名称和引用名称属性关系

@Keep:注解的代码段在GreenDao下次运行时保持不变

 

//创建对象

DaoSession daoSession = DaoMaster.newDevSession(getContext(), UserDao.TABLENAME);

UserDao userDao = daoSession.getUserDao();

 

// 数据删除相关

void delete(T entity):从数据库中删除给定的实体

void deleteAll() :删除数据库中全部数据

void deleteByKey(K key):从数据库中删除给定Key所对应的实体

 

// 数据插入相关

long insert(T entity):将给定的实体插入数据库

 

// 数据修改相关

 

update() 修改,根据id来查询

// 数据查询相关

根据name字段来查询,还可以返回集合

userDao.queryBuilder().where(UserDao.Properties.Title.eq(name)).build()

 

loadAll() 查询全部,返回一个集合

 

相关知识

1.如果想再创建表的话,再创建一个实体类即可,如果想创建内容相同的表,直接创建对象,重新给一个表名即可

2.greendao数据库实现序列化,在类的第一行 public static final long serialVersionUID = 536871008; 添加上这个(后面的值是你的id,build的时候会告诉你id是多少)

 

多表联查

ToOne 

一对一的关系映射。看个例子:

 

@Entity 

public class Score { 

@Id 

private String id; 

private int score; 

@Entity 

public class Student { 

@Id 

private String id; 

private String name; 

private int age; 

private String scoreId; 

@ToOne(joinProperty = "scoreId") 

private Score score; 

//先向数据库中插入两条数据 

Score score = new Score("1101", 80); 

Student magicer = new Student("110","Magicer",12,"1101"); 

scoreDao.insertOrReplace(score); 

studentDao.insertOrReplace(magicer); 

//之后查找我们插入的数据,就可以查询出来我们想要的带有成绩的学生实体。 

QueryBuilder queryBuilder = studentDao.queryBuilder().where(StudentDao.Properties.Name.eq("Magicer")); 

for (Student student : queryBuilder.list()) { 

Log.i(TAG, "onCreate: "+student.toString()); 

 

在上面的例子中,我们设定每个学生有一门成绩,这个时候就是个ToOne

一对一的关系。我们通过joinProperty

来设置外键。我们就可以很方便的查询出某个学生的成绩了。

 

public @interface ToOne { 

/** 

* Name of the property inside the current entity which holds the key of related entity. 

* If this parameter is absent(缺少的), then an additional column is automatically created to hold the key. 

*/ 

String joinProperty() default ""; 

ToMany 

 

但是一般一个学生会有多个成绩,这个时候我们就需要使用ToMany

一对多的关系了。先看下例子:

 

@Entity 

public class Student { 

@Id 

private String id; 

private String name; 

private int age; 

@ToMany(referencedJoinProperty = "studentId") 

private List scores; 

@Entity 

public class Score { 

@Id 

private String id; 

private int score; 

private String type; 

private String studentId; 

Score math = new Score("1101", 87, "Math", "110"); 

Score english = new Score("1102", 99, "English", "110"); 

Score chinese = new Score("1103", 120, "Chinese", "110"); 

scoreDao.insertOrReplaceInTx(math,english,chinese);//使用事务插入或替换数据 

Student magicer = new Student("110", "Magicer", 23); 

studentDao.insertOrReplace(magicer); 

Query query = studentDao.queryBuilder().where(StudentDao.Properties.Name.eq("Magicer")).build(); 

for (Student student : query.list()) { 

Log.i(TAG, "onCreate: "+student); 

//I/MainActivity: onCreate: Student{id='110', name='Magicer', age=23, score=[Score{id='1101', score=87, type='Math', studentId='110'}, Score{id='1102', score=99, type='English', studentId='110'}, Score{id='1103', score=120, type='Chinese', studentId='110'}]} 

 

这个时候,一个学生就有Math

Enghlish

Chinese

三个的成绩。这个时候,我们使用referencedJoinProperty

将成绩跟学生建立了关联关系。

 

public @interface ToMany { 

/** 

* Name of the property inside the target entity which holds id of the source (current) entity 

* Required unless no {@link JoinProperty} or {@link JoinEntity} is specified 

*/ 

String referencedJoinProperty() default ""; 

/** 

* Array of matching source -> target properties 

* Required unless {@link #referencedJoinProperty()} or {@link JoinEntity} is specified 

*/ 

JoinProperty[] joinProperties() default {}; 

JoinEntity 

 

有时我们还要创建多对多的关联关系N:M

。在greenDao

中就使用JoinEntity

注解;先来看下他的定义:

 

public @interface JoinEntity { 

/** Reference to join-entity class, which holds the source and the target properties */ 

Class entity(); 

/** Name of the property inside the join entity which holds id of the source (current) entity */ 

String sourceProperty(); 

/** Name of the property inside the join entity which holds id of the target entity */ 

String targetProperty(); 

 

配置多对多关系的时候我们需要使用到ToMany

和JoinEntity

通过JoinEntity

注解来配置关联的建。如下:

 

@Entity 

public class Student { 

@Id 

private String id; 

private String name; 

private int age; 

@ToMany 

@JoinEntity( 

entity = Join.class, 

sourceProperty = "studentId", 

targetProperty = "scoreId" 

private List scores; 

@Entity 

public class Join { 

@Id 

private String id; 

private String studentId; 

private String scoreId; 

@Entity 

public class Score { 

@Id 

private String id; 

private int score; 

private String type; 

private String studentId; 

遇到的问题 

 

当插入到数据库中的数据是网络请求得到的时候会有些注意事项。由于greenDao

会帮助我们生成一些get和set方法。这个是时候就要注意了。来看下生成的代码:

 

@Entity 

public class Point { 

@Id 

private Long id; 

private Long strokeId; 

private int x; 

private int y; 

@Entity 

public class Stroke { 

@Id 

private Long id; 

private String name; 

@ToMany(referencedJoinProperty = "strokeId") 

private List points; 

 

如上面,我们现在有每个笔画Stroke会有很多的Point。编译下之后会生成很多get和set方法。

 

 

我们看下Stroke的一个get

方法我们会看到下面这些代码。就由于这个代码。可能就会导致。我们解析到了Stroke

后调用getPoints()

方法想要获取点的集合是出现问题,这时候就可能会报错。这个时候我们可以在单独写另外的一个get

方法,来支持直接获取points

对象。

 

@Generated(hash = 404164872) 

public List getPoints() { 

if (points == null) { 

final DaoSession daoSession = this.daoSession; 

if (daoSession == null) { 

throw new DaoException("Entity is detached from DAO context"); 

PointDao targetDao = daoSession.getPointDao(); 

List pointsNew = targetDao._queryStroke_Points(id); 

synchronized (this) { 

if(points == null) { 

points = pointsNew; 

return points; 

介绍greendao多表联查:https://www.aliyun.com/jiaocheng/17699.html

介绍greendao多表联查:https://blog.csdn.net/lidiwo/article/details/78625142

 

greendao数据库升级

首先在 entity中添加你所想添加的新增字段。rebuild一下项目。

 

1.在app下的build.gradle文件的repositories内添加红色部分下面代码:

 

buildscript {

    repositories {

        mavenCentral()

        maven { url "https://jitpack.io" }

    }

    dependencies {

        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.0'

    }

}

2.添加依赖

dependencies {

    compile 'org.greenrobot:greendao:3.2.0'

    compile 'com.github.yuweiguocn:GreenDaoUpgradeHelper:v1.1.0'

}

3.自定义MySQLiteOpenHelper 类,并且继承DaoMaster.OpenHelper ,然后重写onUpgrade方法,注意:onUpgrade有2个方法,

我们重写

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)

第一个参数为SQLiteDatabase 的方法,而不是Database。

代码如下:

public class MySQLiteOpenHelper extends DaoMaster.OpenHelper {

    public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {

        super(context, name, factory);

    }

    @Override

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        MigrationHelper.migrate(db,LocationDao.class,RegistrationFormDao.class);

    }

}

其中:MigrationHelper.migrate(db,LocationDao.class,RegistrationFormDao.class); 里面参数为SQLiteDatabase db,

后面紧接着的参数为你所有的Dao类。

4.找到DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(MyApplication.getContext(),"testdb",null);

修改为

MySQLiteOpenHelper devOpenHelper = new MySQLiteOpenHelper(MyApplication.getContext(),"testdb",null);

 

5。修改数据库版本号,+1。

你可能感兴趣的:(android)