GreenDao关系建表

关系

在greenDAO,实体涉及使用一对一或一对多的关系。例如,如果要模拟一个1:greenDAOñ关系,你将有一个一对一和一对多的关系。但是,请注意,一对一和一对多的关系不是相互连接,所以你必须同时更新。

//学生
@Entity
public class Student {

@Id
private Long id ;

private String name ;

private String number ;

private long PE_Id ;

@ToOne(joinProperty = "PE_Id")
private PEClazz peClazz;
}


//体育课
@Entity
public class PEClazz {

    @Id
    private Long id;

    private int credit;

    private String name;
}

建立一对一关系

@ToOne注释定义的关系向另一个实体(一个实体对象)

当 修改外键 时
Student student = studentDao.queryBuilder().where(StudentDao.Properties.Id.eq(1)).unique();
PEClazz peClazz = student.getPeClazz();
System.out.println("peClazz+id:"+peClazz.getId());
System.out.println("peClazz+name:"+peClazz.getName());

//修改体育课的ID
student.setPE_Id(2);

peClazz = student.getPeClazz();
System.out.println("peClazz+id:"+peClazz.getId());
System.out.println("peClazz+name:"+peClazz.getName());

运行结果(修改外键,外键对象受到改变)

peClazz+id:1

peClazz+name:篮球

peClazz+id:2

peClazz+name:足球

或者里(修改外键对象)

Student student = studentDao.queryBuilder().where(StudentDao.Properties.Id.eq(1)).unique();
            PEClazz peClazz = student.getPeClazz();
            System.out.println("peClazz+id:"+peClazz.getId());

			//设置新的体育课
            PEClazz newPeClazz = new PEClazz();
            newPeClazz.setId(2L);
            student.setPeClazz(newPeClazz);

            System.out.println("student.PE_ID:"+student.getPE_Id());

运行结果 (修改外键对象,外键受到改变)

peClazz+id:1

student.PE_ID:2

注意

在一对一关系中,当要第一次加载时,使用的是懒加载
后续调用将立即返回先前解析的对象。

如果外键属性(例如:PE_Id)受到了改变(或者外键对象受到改变(setPeClazz)),那么再次获取外键对象时(获取的外键)就会发生改变。
外键和外键对象具有关联.

建立一对多关系

//父亲类
@Entity
public class Father {
@Id
private Long id;

private String name;

@ToMany(referencedJoinProperty = "fatherID")
List<Son> sons ;
}	

//儿子类
@Entity
public class Son {

@Id
private Long id;

private String name;

private long fatherID ;
}

@ToMany限定了关系到一组其他实体的(多个实体对象)。

referencedJoinProperty参数:指定指向该实体的ID目标实体的“外键”属性的名称。

先创建几个数据:

			Son son1 = new Son();
            son1.setName("儿子1");
            Son son2 = new Son();
            son2.setName("儿子2");
            Son son3 = new Son();
            son3.setName("儿子3");
            Father father = new Father();
            father.setName("父亲");
            long fatherID = fatherDao.insertOrReplace(father);

            son1.setFatherID(fatherID);
            son2.setFatherID(fatherID);
            son3.setFatherID(fatherID);
            sonDao.insertOrReplace(son1);
            sonDao.insertOrReplace(son2);
            sonDao.insertOrReplace(son3);

更新操作注意

			Father father = fatherDao.queryBuilder().where(FatherDao.Properties.Id.eq(1)).unique();
            List<Son> sons = father.getSons();

			for (Son son: sons) {
                System.out.println("son:"+son.getName());
            }

			Son son = new Son();
            son.setFatherID(father.getId());
            son.setName("儿子4");

			//插入
            daoSession.insert(son);

			for (Son newSon:
                    sons) {
                System.out.println("newSon:"+newSon.getName());
            }
			
			//重新获取
			List<Son> sons1 = father.getSons();

			for (Son newSon1:
                    sons1) {
                System.out.println("newSon1:"+newSon1.getName());
            }

运行结果

son:儿子1

son:儿子2

son:儿子3

newSon:儿子1

newSon:儿子2

newSon:儿子3

newSon1:儿子1

newSon1:儿子2

newSon1:儿子3

注意

由上可知,虽然插入了一个新的,但是,getSons()获取的sons 并没有增加。

因为缓存在里面有列表对象,因此后续的关系get方法调用不查询数据库。

所以可以做以下操作。

//以下是getSons的代码
public List<Son> getSons() {
	//为空,则重新查询
    if (sons == null) { 
        final DaoSession daoSession = this.daoSession;
        if (daoSession == null) {
            throw new DaoException("Entity is detached from DAO context");
        }
        SonDao targetDao = daoSession.getSonDao();
        List<Son> sonsNew = targetDao._queryFather_Sons(id);
        synchronized (this) {
            if(sons == null) {
                sons = sonsNew;
            }
        }
    }

	//否则返回以前的缓存
    return sons;
}

要增加新的关联实体,需要手工将它们添加到源实体的一对多列表

			//插入
            daoSession.insert(son);

			//再插入以后,应该为列表手工添加son
			//手工添加
            sons.add(son);

			for (Son newSon:
                    sons) {
                System.out.println("newSon:"+newSon.getName());
            }
			
			//重新获取
			List<Son> sons1 = father.getSons();

			for (Son newSon1:
                    sons1) {
                System.out.println("newSon1:"+newSon1.getName());
            }

运行结果

son:儿子1

son:儿子2

son:儿子3

newSon:儿子1

newSon:儿子2

newSon:儿子3

newSon:儿子4

newSon1:儿子1

newSon1:儿子2

newSon1:儿子3

newSon1:儿子4

或者

			//插入
            daoSession.insert(son);

			//再插入以后
			/使用重置方法来清除缓存列表
            father.resetSons();

			for (Son newSon:
                    sons) {
                System.out.println("newSon:"+newSon.getName());
            }
			
			//重新获取
			List<Son> sons1 = father.getSons();

			for (Son newSon1:
                    sons1) {
                System.out.println("newSon1:"+newSon1.getName());
            }

运行结果

son:儿子1

son:儿子2

son:儿子3

newSon:儿子1

newSon:儿子2

newSon:儿子3

newSon1:儿子1

newSon1:儿子2

newSon1:儿子3

newSon1:儿子4

由上可知

sons列表中没有添加上去,但是重新getSons()后,发现新插入的son已经加入了进去.

father.resetSons();由源码可知:

public synchronized void resetSons() {
    sons = null;
}

sons为null了,所以当要getSons()时,因为son==null,所以会重新从数据库中重新查询数据。

当添加,更新或删除许多相关的实体可以使用重置方法来清除缓存列表。那么接下来get会重新查询相关实体:

posted @ 2016-12-27 16:04  吃枣的事  阅读(4311)  评论(0编辑  收藏  举报