Nutz Dao学习笔记
羿昊英
2023-12-01
Dao接口的基本操作:
插入:insert(一条sql插入一条记录或者多条记录)
FastInsert(一条sql通过batch插入多条记录)
查询:Fetch(一条sql获取一条记录)
Query(一条sql根据条件获取多条记录)
查询群全部记录:List<Person> people = dao.query(Person.class, null);
按条件查询:List<Person> people = dao.query(Person.class, Cnd.where("name", "like", "P%"));
分页查询:List<Person> people = dao.query(Person.class, Cnd.where("age", ">", 18), dao.createPager(2, 4));
删除:delete(一条sql删除一条记录)(直接删除表dao.delete(list);)
Clear(一条sql根据条件删除多条记录)
更新:Update(一条sql更新一条或多条记录)
建表:Create(根据实体建表)
dao.create(Pet.class,false);
删表:Drop(根据实体/表名称进行删表)
dao.drop(Pet.class);
聚合:Func(执行sum、count等聚合函数)
注意:如果通过Dao接口,你传入的是一个集合或者数组,它会为每一个元素都生成一条SQL语句并执行
同理:update、delete 和 insert 也支持传入数组和集合
插入和更新集合
无论是插入 (Insert) 还是更新 (Update),你传入的对象都可以不仅仅是一个 POJO,你可以传入:
集合 ( Collection<?> )
Map<?,?>
数组 ( T[] )
Nutz.Dao 会自动替你拆包,对集合成员依次执行相应操作。 对于 Map,它会迭代每一个值。
字段的详细定义,例如定义长度 :@ColDefine(width=1024)
private String data;
强制自定义字段类型:@ColDefine(customType="TEXT", type=ColType.VARCHAR)
private String fu;
添加索引, 类级注解:
TableIndexes({@Index(name="orderid_userid", fields={"orderId", "userId"})})
public class UserOrder {
private long id;
private long orderId;
private long userId;
//... 其他属性
}
表结构自动迁移:
// 单个迁移
Daos.migration(dao, User.class, true, false, false); // 新增字段true,删除字段false,检查索引false
// 批量迁移
Daos.migration(dao, "net.wendal.nutzbook.bean", true, false, false);
主键生成器:@Prev(els=@EL("uuid(32)"));
EL表达式中可用的变量:
$me -- 当前Pojo对象
view -- 当前Pojo对象的Entity实例, 可以拿到各种元数据,例如表名. 相当于 dao.getEntity(pojo.getClass())
field -- 当前属性, 相当于 dao.getEntity(pojo.getClass()).getField("id/name/...")
Condition 接口:只有一个方法(toSql(Entity<?> entity)),Nutz.Dao 会将toSql(Entity<?> entity) 的返回直接拼接到SQL 的 WHERE 关键字后面 。
Condition c = Cnd.where("age",">",30).and("name", "LIKE", "%K%").asc("name").desc("id");
这个条件将生成 SQL
WHERE age>30 AND name LIKE '%K%' ORDERBY name ASC, id DESC
模糊查询:Cnd cnd = Cnd.where("name", "like", "%" + str + "%s");
分页查询:<T> List<T> query(Class<T> classOfT, Condition condition, Pager pager);
这个接口有三个参数
1、classOfT 告诉 Nutz.Dao 需要查询的实体类型
2、condition 告诉 Nutz.Dao 查询出的列表需要符合的条件。Condition
3、最后一个参数,就是告诉 Nutz.Dao 将结果如何分页的了。
Pager 对象有如下几个注意事项:
1、如果 pager 被传入了 null,则不分页
2、生成 Pager 对象的时候需要传入 “当前页数” 和 “页大小”
3、Pager 虽然有 getRecordCount() 和 getPageCount() 方法,但是它不会自动被设值 -- 因为考虑到效率
4、通过 Pager.setRecordCount() 可以为 Pager 设置结果集的总数,Pager 会通过 getPageCount() 返回总页数
5、分页页数从1开始算,如果页数是0,代表不分页,请特别注意.
针对两个有关系的表进行操作时:用@View声明一个视图,通过这个注解,Nutz.Dao知道了当前查询数据的时候该从哪里获取数据;
通过@readonly注解知道,当修改或者删除数据的时候,哪些字段应该被忽略。
多对多映射:@ManyMany 注解告诉 Nutz.Dao 对象 Food 和 Pet 之间的关系,必须在数据库中有一个中间表,@ManyMany 注解告诉 Nutz.Dao 对象 Food 和 Pet 之间的关系
例如:
数据库中必须存在一个中间表 t_pet_food
该表有一个字段 foodid 对应到 Food 对象的主键
该表有一个字段 petid 对应到 Pet 对象的主键
Nutz.Dao 通过 @ManyMany 这四个属性了解到:
目标的 POJO 类 : Pet
关联表(或者说:中间表):t_pet_food
关联表的 foodid 字段对应到是本 POJO (Food)主键
关联表的 petid 字段对应到是目标 POJO (Pet) 主键
NutzDao-自定义SQL语句进行复杂查询:
1、通过占位符的方式来构建动态的SQL语句:
Sql sql=Sqls.create(delete from $table where name=@name);
sql.vars().set("table","t_table");
sql.vars().set("name","Tom");
· 通过$table来表示表名,用t_abc表来替换,$表示变量占位符
· 通过@name表示字段名,用Peter替换,@表示参数占位符
· 还有一个特殊的占位符,$condition,
它的用法如下:
Sql sql= Sqls.create("SELECT name FROM t_pet $condition");
sql.setCondition(Cnd.where("id", ">", 35));
2、SQL文件形式的自定义SQL语句:
一个应用通常由很多 SQL 语句构成,如何管理这些语句呢?用户可以将所有的 SQL 语句存放在一个或者多个文件中,语句的间隔可以通过注释,这是一种非 常简单的纯文本文件,文件里只
包含三种信息:
· SQL语句
· SQL语句的名称 (或者说是键值)。你的程序可以通过语句的名称获取到某一条或几条 SQL 语句
· 注释 (通常包括在 /* 与 */ 之间)
注意:你的 SQL 文件必须为UTF-8编码。
下面是一个SQL文件的例子,test.sqls文件:
/* insertUser */
insert into tbl_user (uname,uage) values (@uname, @uage)
/* deleteUser */
delete from tbl_user where uname=@uname
将这个文件以.sqls为后缀,添加到src类路径之中。
之后就是加载SQL文件,只要得到Dao的对象,可以使用dao.sqls()方法获得org.nutz.dao.SqlManager 接口,从这个接口中你就可以获得你预先定义好的Sql对象了。
对于 Dao 接口的默认实现,NutDao,提供两个方法,一个是通过构造函数,另一个是 setter 函数。
· 通过构造函数的方式
Dao dao = newNutDao(datasource,new FileSqlManager("test.sqls"));
System.out.println(dao.sqls().count());
· 通过setter方法
Dao dao = new NutDao(datasource);
((NutDao)dao).setSqlManager(new FileSqlManager("test.sqls"));
System.out.println(dao.sqls().count());
加载SQL文件完成之后,怎样同时执行多条SQL语句呢?这就用到了ComboSQL(组合SQL语句),代码如下:
// 组合SQL语句(Combo SQL)
Sql sql = dao.sqls().createCombo("insertUser","deleteUser");
sql.params().set("uname", "yan").set("uage", 33).set("uname", "jim");
// 同时执行多条SQL语句
dao.execute(sql);
关于 ComboSql,你还需要知道的是:
· ComboSql 也是一种 Sql,它也实现了 org.nutz.dao.sql.Sql 接口。
· 函数 createCombo 接受数目可变的字符串型参数,代表 SQL 的 key。
· 一个 ComboSql 被执行的顺序同你给定的 key 的顺序相同。
· 函数 createCombo 如果没有接受到参数,那么将会包括所有你文件中所有的 SQL 。
3、执行自定义SQL语句:
有了自定义的SQL语句,那么怎么执行SQL语句呢?
当你顺利的创建了一个 Sql 对象,执行它就相当简单了,比如:
void demoSql(Dao dao){
Sql sql =Sqls.create("SELECT name FROM t_abc WHERE name LIKE @name");
sql.params().set("name","A%");
dao.execute(sql);
}