use of org.nutz.dao.util.meta.SystemJob in project nutz by nutzam.
the class DaoUpTest method test_links.
// 3种关联关系的操作
@Test
public void test_links() {
// 首先,得到Dao实例
Dao dao = DaoUp.me().dao();
// 3个Pojo的关系如下
// SystemUser -----(1对1)---> SystemTeam
// SystemUser -----(1对多)---> SystemJob
// SystemTeam -----(多对多)---> SystemJob
/*
* 场景如下:
* 有3个用户, 2个team, 25个任务
* A用户属于Team A, 有10个任务
* B用户属于Team B, 有10个任务
* C用户属于Team B, 有5个任务
*/
// 强制建表
dao.create(SystemUser.class, true);
dao.create(SystemTeam.class, true);
dao.create(SystemJob.class, true);
// 先塞点内容进去
// 3个用户, wendal, zozoh, pangwu86
SystemUser userA = new SystemUser();
userA.setName("wendal");
SystemUser userB = new SystemUser();
userB.setName("zozoh");
SystemUser userC = new SystemUser();
userC.setName("pangwu86");
// 2个组, sysadmin和root
SystemTeam teamA = new SystemTeam();
teamA.setName("sysadmin");
SystemTeam teamB = new SystemTeam();
teamB.setName("root");
// 关联用户到不同的组
userA.setTeam(teamA);
userB.setTeam(teamB);
userC.setTeam(teamB);
List<SystemJob> jobsA = new ArrayList<SystemJob>();
List<SystemJob> jobsB = new ArrayList<SystemJob>();
List<SystemJob> jobsC = new ArrayList<SystemJob>();
for (int i = 0; i < 10; i++) {
SystemJob job = new SystemJob();
jobsA.add(job);
job = new SystemJob();
jobsB.add(job);
if (i < 5) {
job = new SystemJob();
jobsC.add(job);
}
}
userA.setJobs(jobsA);
userB.setJobs(jobsB);
userC.setJobs(jobsC);
dao.insertWith(userA, null);
dao.insertWith(userB, null);
// 因为下一句中team不会插入,所以需要自行把关联字段设置一下
userC.setTeamId(teamB.getId());
// 注意, team是已经插入过了,跟userB同一个team哦,所以只需要也只能插入jobs了
dao.insertWith(userC, "jobs");
// 判断一下已经插入的数据, 因为id是自增的,插入后关联对象也理应有值
assertTrue(userA.getTeam().getId() > 0);
assertTrue(userB.getTeam().getId() > 0);
for (SystemJob job : userA.getJobs()) {
assertTrue(job.getId() > 0);
}
for (SystemJob job : userB.getJobs()) {
assertTrue(job.getId() > 0);
}
// 插入userA,userB, userC的时候, @One和@Many都插入了,但@ManyMany是team-->job的映射,并没有插入哦
// 因为nutz只认单层单向映射
// TeamA的任务,就是UserA的任务
teamA.setJobs(new ArrayList<SystemJob>(userA.getJobs()));
// TeamB的任务, 是UserB和UserC的任务的集合
ArrayList<SystemJob> jobs = new ArrayList<SystemJob>();
jobs.addAll(userB.getJobs());
jobs.addAll(userC.getJobs());
teamB.setJobs(jobs);
// 现在插入@ManyMany的数据
dao.insertRelation(teamA, null);
dao.insertRelation(teamB, null);
// ---------------------------------------------------
// 查询操作, fetch及fetchLinks
// 关键词: 单向,无状态
// 看看zozoh是谁
SystemUser who = dao.fetch(SystemUser.class, "zozoh");
assertNotNull(who);
// 注意,这是判断是null哦, 因为关联对象是不会主动取的
assertNull(who.getTeam());
// 一样是null!!!
assertNull(who.getJobs());
// 为什么是null呢? 看这句
assertTrue(SystemUser.class == who.getClass());
// 为什么是相等的呢? 因为Nutz中的Pojo都是无状态的, 不存在托管/非托管的状态
// 所以没有hibernate那种代理类的情况,所以数据库的字段也需要映射在具体的java属性中
// 而非代理类的隐藏属性里面
// 下面取出关联对象
// 仅取出jobs
dao.fetchLinks(who, "jobs");
assertNotNull(who.getJobs());
// 全部取出, 观察日志,会发现team和jobs都会取
dao.fetchLinks(who, null);
// 为什么jobs都取过,还会再取一次呢? 因为无状态哦, nutz是不会记住这个对象的状态的
assertNotNull(who.getJobs());
assertNotNull(who.getTeam());
// 那么, Team的关联对象呢?
assertNull(who.getTeam().getJobs());
// 原因是fetchLinks只读取一层
// 同理, job.getUser()也会是null
assertNull(who.getJobs().get(0).getUser());
dao.fetchLinks(who.getJobs().get(0), null);
// 现在, user.getJob().getUser 是否与 user是同一个对象呢?
assertFalse(who == who.getJobs().get(0).getUser());
// @ManyMany的取出操作是一个样
assertNull(who.getTeam().getJobs());
assertNotNull(dao.fetchLinks(who.getTeam(), null).getJobs());
// 批量fetchLinks
// 要不加个条件判断一下谁最蛋疼?
List<SystemUser> users = dao.query(SystemUser.class, null);
assertEquals(3, users.size());
dao.fetchLinks(users, null);
for (SystemUser user : users) {
assertNotNull(user.getTeam());
assertNotNull(user.getJobs());
}
// -------------------------------------------------------------------
// 更新/删除关联对象/关联信息操作
// @One更新, 把Team A的名字改成god --> 其实可以直接改... 只是为了演示...
SystemUser wendal = dao.fetch(SystemUser.class, "wendal");
// fetchLinks返回的就是原来的对象, 有返回值是为了方便链式调用
wendal = dao.fetchLinks(wendal, "team");
assertNotNull(wendal.getTeam());
wendal.getTeam().setName("god");
dao.updateLinks(wendal, null);
SystemTeam godTeam = dao.fetch(SystemTeam.class, "god");
assertNotNull(godTeam);
// @Many 更新
SystemUser zozoh = dao.fetchLinks(dao.fetch(SystemUser.class, "wendal"), null);
assertNotNull(zozoh.getJobs());
// 把前面4个任务的state设置为1, 算是完成吧
for (int i = 0; i < 4; i++) {
zozoh.getJobs().get(i).setState(1);
}
dao.updateLinks(zozoh, "jobs");
// 既然更新了,那看看未完成的任务是不是21个
assertEquals(21, dao.count(SystemJob.class, Cnd.where("state", "=", 0)));
// @ManyMany的更新
// 单纯更新job表的数据, 与前面的@Many无异, 不再重复
// 下面是要更新@ManyMany中的中间表
SystemTeam rootTeam = dao.fetch(SystemTeam.class, "root");
dao.fetchLinks(rootTeam, null);
assertNotNull(rootTeam.getJobs());
assertEquals(15, rootTeam.getJobs().size());
// 移除前11个任务的引用, 在下面的deleteLinks执行的时候, 它们就会幸免于难
for (int i = 0; i < 11; i++) {
rootTeam.getJobs().remove(0);
}
// deleteLinks的特点就是当前对象引用的关联对象才会删除哦
dao.deleteLinks(rootTeam, null);
// 重新fetchLinks, 就剩下11个job了
dao.fetchLinks(rootTeam, null);
assertEquals(11, rootTeam.getJobs().size());
// 现在,我们把pangw86这个用户及相关的job删除
SystemUser pangwu86 = dao.fetch(SystemUser.class, "pangwu86");
assertFalse(0 == dao.count(SystemJob.class, Cnd.where("userId", "=", pangwu86.getId())));
dao.fetchLinks(pangwu86, "jobs");
// 因为team还不能删除,所以需要制定只删除jobs
dao.deleteWith(pangwu86, "jobs");
assertNull(dao.fetch(SystemUser.class, "pangwu86"));
assertEquals(0, dao.count(SystemJob.class, Cnd.where("userId", "=", pangwu86.getId())));
// ---------------------------------
// 各种clear
// 现在,天黑了,统统杀掉
// 清除关联关系,直接全干掉
zozoh = dao.fetchLinks(dao.fetch(SystemUser.class, "zozoh"), null);
dao.clearLinks(zozoh, null);
assertEquals(0, dao.count(SystemJob.class, Cnd.where("userId", "=", dao.fetch(SystemUser.class, "zozoh").getId())));
// 人还在
assertNotNull(dao.fetch(SystemUser.class, "zozoh"));
// 干掉...
dao.delete(zozoh);
// 所在Team已经没人了,相关的job也清除掉
dao.clearLinks(zozoh.getTeam(), null);
// 连人带team带jobs全删!!
wendal = dao.fetch(SystemUser.class, "wendal");
SystemTeam team = dao.fetchLinks(wendal, "team").getTeam();
// 关联关系全删
dao.clearLinks(wendal, null);
// 删掉自己
dao.delete(wendal);
// team与job的关联关系也需要清除
// 二级关联,也干掉
dao.clearLinks(team, null);
// 人被删了...
assertNull(dao.fetch(SystemUser.class, "wendal"));
// 组也删了
assertNull(dao.fetch(SystemTeam.class, "sysadmin"));
// 即使数据库记录干掉了, wendal这个对象依然可用,因为完全跟数据库分离的
assertEquals(0, dao.count(SystemJob.class, Cnd.where("userId", "=", wendal.getId())));
// 应该都挂了吧? 检查一下
assertEquals(0, dao.count(SystemUser.class));
assertEquals(0, dao.count(SystemTeam.class));
assertEquals(0, dao.count(SystemJob.class));
// 等等, 别放过了关联表
// 可以直接传表名
assertEquals(0, dao.count("t_daoup_team_job"));
// 好了, 世界清静了...
}
Aggregations