NutzDao学习笔记-基本概念知识

 

一 环境搭建

  1. 首先,你必须安装 JDK 1.6,推荐JDK 8u112
  2. 其次,为了运行 Nutz.Dao,你必须要有一个数据库软件:
    1. Mysql,Postgresql, SQLServer, Oracle, DB2 , H2都可以。
  3. 建立一个 Java 项目:
    1. 推荐使用EclipseIdeaIDE工具
    2. 你要将数据库的 JDBC Driver 和你喜欢的连接池加入项目的 classpath
  4. NutDao并不依赖MVC环境及Ioc.
  5. Mvc环境下,通常使用Ioc管理NutDao的实例.
  6. NutDao是线程安全的,无需重复创建其实例.
    建立POJO
    创建NutzDao实例,定义dataSource (重点)
    二 Dao接口的基本操作

插入

Insert

一条 SQL 插入一条记录或者多条记录

插入

FastInsert

一条 SQL ,通过batch插入多条记录

删除

Delete

一条 SQL 删除一条记录

更新

Update

一条 SQL 更新一条或者多条记录

获取

Fetch

一条 SQL 获取一条记录

查询

Query

一条 SQL 根据条件获取多条记录

清除

Clear

一条 SQL 根据条件删除多条记录

建表

Create

根据实体建表

删表

Drop

根据实体/表名称进行删表

聚合

Func

执行sum,count等操作

传统关系型数据库定义了数据库的四种操作,增删改查,但是nutz.dao从用户角度,又扩展了好几种操作,而且都支持条件增删改查,专门为条件封装了接口,但是也有它的局限性

1 不生成外键,也不推荐用外键

2 只能解决一般建表需求,复杂的表结构需通过自定义sql完成

三 注意事项

主键

对于一个 POJO,你可以同时为其声明 @Id @Name,它们都能正常工作。你只需要保证 @Name 对应的字段 在数据库里有唯一性约束即可。 但是通常, Nutz.Dao 并没有假设你同时在一个 POJO 里应用 @Id, @Name @PK,如果你 这么做了,可能会引发一些奇怪的问题。事实上,你也不可能这么做,不是吗?

TIPS:注解 @Id 与注解 @Name 声明的字段不需要另外加上注解 @Column 在注解 @PK 里面声明的对应复合主键的字段不需要另外加上注解 @Column

默认的,nutz.dao认为一个整数型的主键是自增的。所以它会在执行

Dao.insert(pet);

之后,为你插入的对象执行

SELECT MAX(id) from t_pet;(如果你使用的数据库如mysql,支持主键返回,那这个操作不会出现)

不同的数据库获得自增值得方式是不一样的,通过@Next注解,声明数据库本地方言,来获取自增值,注意这里的自增是由数据库来实现的,而非nutzDao的内部自增机制

复杂的sql条件

  • 对于 Nutz.Dao 来说,它本质上就是将你的 Java 对象转化成 SQL,然后交给 JDBC 去执行。
  • SQL 中,当执行数据删除和查询操作时,最常用的就是 WHERE 关键字。
  • WHERE 关键字后面的就是所谓的复杂查询条件

有些情况,数据库中的字段同 Java 对象中的字段并不同名, 所以就需要给 Java 字段上的数据库字段注解加上参数 @Column("数据库字段名") 如果你通过 Cnd.wrap() 硬编码某个字段,那么当这个字段数据库字段名发生改变时,你就需要改动很多。 因此你希望仅仅将对于数据库的变动限制在 Java 对象的源文件里 所以 Nutz 提供了 Cnd.where() 方法

提供Criteria接口(继承Condition接口)

  1. 让程序员更容易的拼装复杂逻辑的条件
  2. 让生成的 SQL 可以被参数化,更好的支持 PreparedStatement
// 创建一个 Criteria 接口实例


Criteria cri = Cnd.cri();




// 组装条件

if(...){

    cri.where().andIn("id", 3,4,5).andIn("name", "Peter", "Wendal", "Juqkai");

}else if(...){

    cri.where().andLT("id", 9);

}




if(...){

    cri.where().andLike("name", "%A%");

}




cri.getOrderBy().asc("name").desc("id");




// 执行查询

List<MyObj> list = dao.query(MyObj.class, cri, null);

分页

使用数据库的应用程序,多数情况下都需要使用 分页 这个功能。尤其是在 Web 应用程序中,后端的分页查询尤其的普遍。 在以往的使用经验中,一个分页查询,除了能获取到一个列表外,我们通常需要如下几个信息才能在客户端显示出一个完整的翻页条。

  • 当前页数 -- 第几页
  • 页大小 -- 每页有多少条记录
  • 总页数 -- 一共多少页
  • 总记录数 -- 如果不分页,一共有多少条记录
    当我们获得了这四条信息后,对于维护一个翻页查询就足够。
    Nutz.Dao 的查询接口天然就支持分页查询。
<T> List<T> query(Class<T> classOfT, Condition condition, Pager pager);

 

这个接口有三个参数

  • classOfT 告诉 Nutz.Dao 需要查询的实体类型
  • condition 告诉 Nutz.Dao 查询出的列表需要符合的条件。详细请看 复杂条件
  • 最后一个参数,就是告诉 Nutz.Dao 将结果如何分页的了。
    Pager 对象有如下几个注意事项:
  • 如果 pager 被传入了 null,则不分页
  • 生成 Pager 对象的时候需要传入 当前页数 页大小
  • Pager 虽然有 getRecordCount() getPageCount() 方法,但是它不会自动被设值 -- 因为考虑到效率
  • 通过 Pager.setRecordCount() 可以为 Pager 设置结果集的总数,Pager 会通过 getPageCount() 返回总页数
  • 分页页数从1开始算,如果页数是0,代表不分页,请特别注意
     

支持一对一,一对多,多对多映射,支持自定义sql

事务

对于事务安全,nutz提供了事务模板

  • org.nutz.trans.Trans 类提供了两个函数 exec
    • 一个接受数目可变的 Atom 对象
    • 一个接受一个整型值用以界定本事务的级别,以及一个数目可变的 Atom 对象
  • Atom 类就是 java.lang.Runnable 的一个别名
  • 在一个 Atom 里,无论同时操作多少 DataSource,都是事务安全的(由于不是使用XADataSource,无法100%保证)
  • 你可以通过实现自己的 Transaction 实现类,扩展 Nutz.Dao 对于事务的支持

示例

final Pet pet1 = dao.fetch(Pet.class,"XiaoBai");


final Pet pet2 = dao.fetch(Pet.class,"XiaoHei");




pet1.setNickname("BaiBai");

pet2.setNickname("HeiHei");

// Begin transaction        

Trans.exec(new Atom(){

    public void run() {

        dao.update(pet1);

        dao.update(pet2);

    }

});

提供一个org.nutz.trans.Atom接口的匿名类来实现,在里面的所有的dao操作都是原子性的,以为他们在同一个原子里面“Atom”

设置事务的隔离级别

public static void exec(int level, Atom... atoms);

这里的第一个参数 level java.sql.Connection 接口中的 setTransactionIsolation 规定的 level 是一样的。下面 是在 java.sql.Connection 里面关于 level 参数的 JDoc 说明:

它可以是下列常量中的任意一个值:

  • Connection.TRANSACTION_READ_UNCOMMITTED
  • Connection.TRANSACTION_READ_COMMITTED
  • Connection.TRANSACTION_REPEATABLE_READ
  • Connection.TRANSACTION_SERIALIZABLE
    实体解析
     

Class<?>  --->  Entity<?> ---> PojoMaker ---> DaoStatement ---> DaoExecutor ---> JDBC

           |               |              |                 |                |

           \------------------------ NutDao 的实现流程 -----------------------/

  • PojoMaker 接口负责语句的生成
  • DaoExecutor 接口负责语句的执行
    内置服务类
    单独的调用一行接口,多传入一个参数到没什么,但是如果频繁的被使用,每次都要多写一个参数毕竟很是麻烦,nutzdao提供了服务类来简化这些操作
  • 如果 POJO 即声明了 @Id 又声明了 @Name,那么适合采用 IdNameEntityService
  • 如果 POJO 仅声明了 @Id,那么适合采用 IdEntityService
  • 如果 POJO 仅声明了 @Name,那么适合采用 NameEntityService
  • 如果 POJO 即没声明了 @Id 又没声明了 @Name,那么适合采用 EntityService
     
  • 这四个内置的服务类,仅仅提供了一些基本的操作。
  • 这些服务类都是支持泛型。
  • 你可以直接使用,或者你可以从这四个服务类继承你自己的实现。
  • 如果你继承这些服务类,请务必声明泛型

Dao拦截器

var ioc = {


        dao : {

            type : "org.nutz.dao.impl.NutDao",

            args : [{refer:"dataSource"}],

            fields : {

                interceptors : [

                            "log", //输入sql语句到日志,这是nutdao默认情况下唯一启用的拦截器

                            "time", // 打印sql时耗

                            "net.demo.MyDaoInterceptor", // 自定义拦截器,需要实现DaoInterceptor

                            {refer:"superI"} // 引用另外一个bean作为拦截器

                            ]

            }

        }

}

 参考资料:http://www.nutzam.com/index.html

猜你喜欢

转载自blog.csdn.net/qq_33543634/article/details/84066030
今日推荐