greenDao多表關聯

http://blog.magicer.xyz/2017/...java

以前咱們看到了greenDao的簡單使用,可是就這些是遠遠不夠的,有時候咱們須要存儲的數據較爲複雜,這個時候咱們可能須要使用到多表關聯的操做。數據庫

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<Student> queryBuilder = studentDao.queryBuilder().where(StudentDao.Properties.Name.eq("Magicer"));
        for (Student student : queryBuilder.list()) {
            Log.i(TAG, "onCreate: "+student.toString());
        }

在上面的例子中,咱們設定每一個學生有一門成績,這個時候就是個ToOne一對一的關係。咱們經過joinProperty來設置外鍵。咱們就能夠很方便的查詢出某個學生的成績了。less

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一對多的關係了。先看下例子:ide

@Entity
public class Student {
    @Id
    private String id;
    private String name;
    private int age;
    @ToMany(referencedJoinProperty = "studentId")
    private List<Score> 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<Student> 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 將成績跟學生創建了關聯關係。ui

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註解;先來看下他的定義:this

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();
}

配置多對多關係的時候咱們須要使用到ToManyJoinEntity經過JoinEntity註解來配置關聯的建。以下:code

@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<Score> 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會幫助咱們生成一些getset方法。這個是時候就要注意了。來看下生成的代碼:對象

@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<Point> points;
}

如上面,咱們如今有每一個筆畫Stroke會有不少的Point。編譯下以後會生成不少getset方法。
咱們看下Stroke的一個get方法咱們會看到下面這些代碼。就因爲這個代碼。可能就會致使。咱們解析到了Stroke後調用getPoints()方法想要獲取點的集合是出現問題,這時候就可能會報錯。這個時候咱們能夠在單獨寫另外的一個get方法,來支持直接獲取points對象。blog

@Generated(hash = 404164872)
    public List<Point> 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<Point> pointsNew = targetDao._queryStroke_Points(id);
            synchronized (this) {
                if(points == null) {
                    points = pointsNew;
                }
            }
        }
        return points;
    }
相關文章
相關標籤/搜索