Search in sources :

Example 1 with SystemUser

use of org.nutz.dao.util.meta.SystemUser in project nutz by nutzam.

the class DaoUpTest method test_sql.

/**
 * 自定义SQL, 解决绝大部分Dao接口无法满足你的sql调用
 */
@Test
public void test_sql() {
    // 不再啰嗦, 不然你也烦了..
    Dao dao = DaoUp.me().dao();
    // 首先,我们用前一个test的pojo建表
    dao.create(SystemUser.class, true);
    dao.create(SystemTeam.class, true);
    // 建1个用户,一个Team
    SystemUser user = new SystemUser();
    user.setName("wendal");
    SystemTeam team = new SystemTeam();
    team.setName("root");
    user.setTeam(team);
    dao.insertWith(user, "team");
    // Dao接口大部分操作都生成单表SQL, 除了@ManyMany.
    // 所以很多人觉得@One也查2次很浪费啊, 那这里写一条
    String str = "select u.*,t.* from $user_table u INNER JOIN $team_table t ON u.t_id = t.id where u.nm=@name";
    // 创建一个自定义Sql对象, 还有各种形式哦
    Sql sql = Sqls.create(str);
    // $开头的是变量,会直接拼入sql哦
    sql.vars().set("user_table", dao.getEntity(SystemUser.class).getTableName());
    // 同上
    sql.vars().set("team_table", dao.getEntity(SystemTeam.class).getTableName());
    // @开头的是参数, 会变成问号哦
    sql.params().set("name", "wendal");
    // Sqls.callback提供N种常用的回调,你需要的一般都在里面了
    sql.setCallback(Sqls.callback.record());
    // 注意, execute是没有返回值的, 所需要的值都通过callback来获取
    dao.execute(sql);
    // 不抛出异常就是执行成功
    // Sqls.callback.record()的返回值就是Record
    Record record = sql.getObject(Record.class);
    // 从Record还原出Pojo来
    SystemUser u = record.toEntity(dao.getEntity(SystemUser.class), "u.");
    assertNotNull(u);
    SystemTeam t = record.toEntity(dao.getEntity(SystemTeam.class), "t.");
    assertNotNull(t);
    u.setTeam(t);
}
Also used : Dao(org.nutz.dao.Dao) SystemUser(org.nutz.dao.util.meta.SystemUser) Record(org.nutz.dao.entity.Record) SystemTeam(org.nutz.dao.util.meta.SystemTeam) Sql(org.nutz.dao.sql.Sql) Test(org.junit.Test)

Example 2 with SystemUser

use of org.nutz.dao.util.meta.SystemUser 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"));
// 好了, 世界清静了...
}
Also used : SystemJob(org.nutz.dao.util.meta.SystemJob) Dao(org.nutz.dao.Dao) ArrayList(java.util.ArrayList) SystemUser(org.nutz.dao.util.meta.SystemUser) SystemTeam(org.nutz.dao.util.meta.SystemTeam) Test(org.junit.Test)

Example 3 with SystemUser

use of org.nutz.dao.util.meta.SystemUser in project nutz by nutzam.

the class DaoUpTest method test_custom_sql.

/**
 * 自定义SQL, 进阶, 自定义回调
 */
@Test
public void test_custom_sql() {
    Dao dao = DaoUp.me().dao();
    // 建表,准备数据
    dao.create(SystemUser.class, true);
    SystemUser user = new SystemUser();
    user.setName("wendal");
    dao.fastInsert(user);
    user = new SystemUser();
    user.setName("zozoh");
    dao.fastInsert(user);
    Sql sql = Sqls.create("select id from $table $condition");
    // 设置之后, setCondition里面的条件就可以用java属性名了
    sql.setEntity(dao.getEntity(SystemUser.class));
    sql.setCondition(Cnd.where("name", "=", "zozoh"));
    // 只是为了演示变量设置, 你可以直接在sql里写好表名
    sql.vars().set("table", dao.getEntity(SystemUser.class).getTableName());
    sql.getContext().attr("hi-我是自定义上下文变量", "哈哈哈哈");
    sql.setCallback(new // 同样的功能可以用内置的Sqls.callback.integer();
    SqlCallback() {

        public Object invoke(Connection conn, ResultSet rs, Sql sql) throws SQLException {
            assertEquals(sql.getContext().attr("hi-我是自定义上下文变量"), "哈哈哈哈");
            if (rs.next())
                return rs.getInt(1);
            return -1;
        // 这里的conn和rs不需要用户代码关闭哦.
        // 你可以通过sql.
        }
    });
    dao.execute(sql);
    // 还有sql.getXXXX等等方法等着你哦
    assertEquals(2, sql.getInt());
}
Also used : Dao(org.nutz.dao.Dao) SQLException(java.sql.SQLException) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) SystemUser(org.nutz.dao.util.meta.SystemUser) Sql(org.nutz.dao.sql.Sql) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)3 Dao (org.nutz.dao.Dao)3 SystemUser (org.nutz.dao.util.meta.SystemUser)3 Sql (org.nutz.dao.sql.Sql)2 SystemTeam (org.nutz.dao.util.meta.SystemTeam)2 Connection (java.sql.Connection)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 ArrayList (java.util.ArrayList)1 Record (org.nutz.dao.entity.Record)1 SystemJob (org.nutz.dao.util.meta.SystemJob)1