Search in sources :

Example 1 with Dao

use of org.nutz.dao.Dao 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 Dao

use of org.nutz.dao.Dao in project nutz by nutzam.

the class DaoUpTest method test_pojo.

/**
 * 2. 带Pojo的基本操作,单表无操作
 */
@Test
public void test_pojo() {
    // 首先,得到Dao实例, 同理, 已经初始化好了的
    // 因为
    Dao dao = DaoUp.me().dao();
    // 关于SimplePojo, 请务必打开看一眼哦
    // 这个类同时标注了@Id和@Name,自动建表时以@Id作为主键,@Name作为唯一键
    // 强制建表
    // 真实代码可别写true,被删表了别找我!!!
    dao.create(SimplePojo.class, true);
    // 先生成个随机字符串帮助实例, R是nutz内部的随机数相关的帮助类,有UUID, UU32, UU64等很多东西哦
    // 代表一个字符串长度为10的随机字符串生成器
    StringGenerator sg = R.sg(10);
    // 插入几条记录
    for (int i = 0; i < 100; i++) {
        // 如果用的是Oracle数据库死在这里了,请加上druid,使其用上连接池.
        dao.insert(new SimplePojo(sg.next(), "http://www." + sg.next() + ".cn", R.random(10, 100)));
    }
    // 统计一下,应该是100条
    assertEquals(100, dao.count(SimplePojo.class));
    // 批量插入1000条吧
    List<SimplePojo> list = new ArrayList<SimplePojo>();
    for (int i = 0; i < 100; i++) {
        list.add(new SimplePojo(sg.next(), "http://www." + sg.next() + ".cn", R.random(10, 100)));
    }
    // 注意, list里面的对象必须是同一个类型哦
    dao.fastInsert(list);
    // fastInsert的特点是快,但不会执行@Prev和@Next, 也不会取回生成的主键哦,有得有失嘛
    // 看看大于45岁的有多少人,虽然理论上是一半一半,事实上经常不是这样...
    int re = dao.count(SimplePojo.class, Cnd.where("age", ">", 45));
    log.infof("older than 45y : %d", re);
    // 分页查询,跟无Pojo时的操作差不多
    List<SimplePojo> pojos = dao.query(SimplePojo.class, Cnd.where("age", ">", 45), dao.createPager(2, 10));
    // 肯定小于等于10
    log.infof("size=%d", pojos.size());
    // 更新操作
    // 不加参数的话,就是取出第一条记录了
    SimplePojo pojo = dao.fetch(SimplePojo.class);
    // 肯定不为null啦
    assertNotNull(pojo);
    // nutzbook是一本很值得看的nutz书哦
    pojo.setWebsite("http://nutzbook.wendal.net");
    // 只需要更新website, 如果全部属性都更新就 dao.update(pojo, null)
    dao.update(pojo, "website");
    // 检查一下是不是真的变成nutzbook的网址了
    assertEquals("http://nutzbook.wendal.net", dao.fetch(SimplePojo.class, pojo.getId()).getWebsite());
    // 现在, 随便删掉一条记录
    // 传入的是数值,所以SimplePojo必须有个@Id的属性
    dao.delete(SimplePojo.class, 20);
    // 肯定删了,或者根本没有,呵呵
    assertNull(dao.fetch(SimplePojo.class, 20));
    // 再根据name删掉一条
    // 传入的是字符串,所以SimplePojo必须有个@Name
    dao.delete(SimplePojo.class, pojo.getName());
    assertNull(dao.fetch(SimplePojo.class, pojo.getName()));
    // delete方法时删除单条记录,而批量呢? clear方法
    // 开始大开杀戒
    // 删掉所有id小于20的记录,哈哈
    dao.clear(SimplePojo.class, Cnd.where("id", "<", 20));
    // 统计一下20以内的记录,应该是0哦
    assertEquals(0, dao.count(SimplePojo.class, Cnd.where("id", "<", 20)));
    // 现在,让id大于50的记录的website通通变成nutzbook,哈哈哈
    int count = dao.update(SimplePojo.class, Chain.make("website", "http://nutzbook.wendal.net").add("createTime", new Date()), Cnd.where("id", ">", 50));
    assertEquals(count, dao.count(SimplePojo.class, Cnd.where("id", ">", 50).and("website", "=", "http://nutzbook.wendal.net")));
    // 请留意一下Cnd和Chain的链式写法
    // 按某人的建议, 查询一下id大于30或者website为nutzbook且name包含a的记录
    // 翻译成伪sql就是  where id > 300 or (website like "%nutzbook%" and name like "%a%")
    int size = dao.count(SimplePojo.class, Cnd.where("id", ">", 300).or(Cnd.exps("website", "like", "%nutzbook%").and("name", "like", "%a%")));
    assertTrue(size > 0);
    // sql 输出类似于
    // SELECT COUNT(*) FROM t_test_simple_pojo  WHERE id>300 OR (website LIKE '%nutzbook%' AND name LIKE '%a%')
    // 关于日志中的sql, 特别说明一下, nutz真正执行的sql是
    /**
     * SELECT COUNT(*) FROM t_test_simple_pojo  WHERE id>? OR (website LIKE ? AND name LIKE ?)
     */
    // 即PreparedStatement, 参数都是以安全的方式传输.
    // 而日志中带上参数的以"For example"提示的sql是用于显示的,并非真正执行的sql
    // 好了, happy完了,全杀
    dao.clear(SimplePojo.class, null);
}
Also used : Dao(org.nutz.dao.Dao) StringGenerator(org.nutz.lang.random.StringGenerator) ArrayList(java.util.ArrayList) SimplePojo(org.nutz.dao.util.meta.SimplePojo) Date(java.util.Date) Test(org.junit.Test)

Example 3 with Dao

use of org.nutz.dao.Dao in project nutz by nutzam.

the class DaoUpTest method test_connection.

/**
 * 操作数据库连接
 * @throws SQLException
 */
@Test
public void test_connection() throws SQLException {
    // 有2种方式,看你喜欢
    // 第一种, 在Dao接口下执行
    Dao dao = DaoUp.me().dao();
    dao.run(new ConnCallback() {

        public void invoke(Connection conn) throws Exception {
        // 做任何你想做的jdbc操作,但最好别关闭这个conn, 因为nutz会为你处理好
        // 如果当前上下文是事务,那这个连接就是事务那个连接
        }
    });
    // 第二种,不经过Dao,直接从DataSource. 如果是Mvc应用,请通过注入获取DataSource
    DataSource ds = DaoUp.me().getDataSource();
    Connection conn = null;
    try {
        conn = ds.getConnection();
    // 做爱做的事吧 ^_^
    } finally {
        try {
            if (conn != null)
                // 务必关闭连接!!!
                conn.close();
        } catch (Throwable e) {
            log.debug("fail to close Connection", e);
        }
    }
}
Also used : Dao(org.nutz.dao.Dao) ConnCallback(org.nutz.dao.ConnCallback) Connection(java.sql.Connection) SQLException(java.sql.SQLException) DataSource(javax.sql.DataSource) Test(org.junit.Test)

Example 4 with Dao

use of org.nutz.dao.Dao 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 5 with Dao

use of org.nutz.dao.Dao 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

Dao (org.nutz.dao.Dao)11 Test (org.junit.Test)9 Record (org.nutz.dao.entity.Record)3 NutDao (org.nutz.dao.impl.NutDao)3 SystemUser (org.nutz.dao.util.meta.SystemUser)3 Connection (java.sql.Connection)2 SQLException (java.sql.SQLException)2 ArrayList (java.util.ArrayList)2 DataSource (javax.sql.DataSource)2 Sql (org.nutz.dao.sql.Sql)2 SystemTeam (org.nutz.dao.util.meta.SystemTeam)2 ResultSet (java.sql.ResultSet)1 Date (java.util.Date)1 User (net.wendal.nutzdemo.bean.User)1 ConnCallback (org.nutz.dao.ConnCallback)1 NutTxDao (org.nutz.dao.impl.NutTxDao)1 Pet (org.nutz.dao.test.meta.Pet)1 Issue1163Pet (org.nutz.dao.test.meta.issue1163.Issue1163Pet)1 AbcPet (org.nutz.dao.test.meta.nutzcn.AbcPet)1 SimplePojo (org.nutz.dao.util.meta.SimplePojo)1