Dao 接口的基本操作

优质
小牛编辑
131浏览
2023-12-01

传统关系型数据库定义了四种数据操作:

  1. 插入 Insert
  2. 删除 Delete
  3. 更新 Update
  4. 查询 Query

可以说,这四种操作涵盖了所有的数据操作。并且,除了 插入 操作,所有的操作都是可以一次针对多条记录的。

但是,Nutz.Dao 认为从使用者的角度来看,这四种操作还是有所不同的。比如,查询返回的结果,很多时候仅仅是一条记录。
我们需要为这种情况进行优化。所以,Nutz.Dao 在传统关系型数据库数据操作的基础上定义了如下的数据操作:



















































插入
Insert
一条 SQL 插入一条记录或者多条记录
插入
FastInsert
一条 SQL ,通过batch插入多条记录
删除
Delete
一条 SQL 删除一条记录
更新
Update
一条 SQL 更新一条或者多条记录
获取
Fetch
一条 SQL 获取一条记录
查询
Query
一条 SQL 根据条件获取多条记录
清除
Clear
一条 SQL 根据条件删除多条记录
建表
Create
根据实体建表
删表
Drop
根据实体/表名称进行删表
聚合
Func
执行sum,count等操作

请注意: 这里我是说 “一条” SQL。 如果通过 Dao 接口,你传入的是一个集合或者数组,它会为每一个元素
都生成一条 SQL 并执行,并更新操作:

Pet[] pets = xxxx;
dao.update(pets);    // 可以是数组,当然 pets 也可以是集合

同理,delete 和 insert 也支持传入数组和集合

示例的前提条件

  • 我们假设已经创建了实体类 com.zzh.demo.Person 和实体表 t_person
  • 在文档 Nutz.Dao 入门 中,我们已经声明了这个实体
  • 下述所有的操作都是假设已经有了 dao 变量,并且它指向一个 Dao 的实例。文档 Nutz.Dao 入门 中, 我们给出了如何创建 Dao 实例,以及如何搭建运行环境

创建数据表

为 Pet 创建数据表,如果数据表存在,则自动忽略

//一般我们都这样写
dao.create(Pet.class, false);

删除数据表

删除 Pet 的数据表

dao.drop(Pet.class);//全部删掉哦,没条件的,慎用!!

插入 Insert

Person p = new Person();
p.setName("Peter");
p.setAge(22);
dao.insert(p);
System.out.println(p.getId());

Person 对象的 Id 被自动更新了。

  • 更多的关于 @Id 注解的描述,请参看 关于主键 以及 在插入前后的为字段设值

取得 Fetch

根据名称获取 (如果你的实体声明了 @Name 字段, 字符型主键,或者带唯一性索引的字段)

Person p = dao.fetch(Person.class,"Peter");
System.out.println(p.getId());

根据 ID 获取 (如果你的实体声明了 @Id 字段, 数值型主键)

Person p = dao.fetch(Person.class,2);
System.out.println(p.getName());

@Id和@Name可以同时存在于一个Pojo类内,但不允许标注在同一个属性,毕竟不可以同时是数值型主键又是字符型主键

更新 Update

Person p = dao.fetch(Person.class,2);
p.setAge(32);
dao.update(p)

dao.update(p, "^age$"); //仅更新age,参数是个正则表达式
// 注意, p至少带@Id/@Name/@Pk中的一种

dao.update(list, "^age$"); //更新一个集合也是可以的

更新多条

// 根据特定条件更新特定字段
dao.update(Person.class, Chain.make("dead",true), Cnd.where("age",">",150));
// 常用的+1更新
dao.update(Person.class, Chain.makeSpecial("age", "+1").add("location", "yvr"), Cnd.where("name","=", "wendal"));

删除 Delete

直接删对象

dao.delete(pet); // Pet必须带@Id/@Name/@Pk中的一种或多种

根据名称删除 (如果你的实体声明了 @Name 字段). 批量删除请用clear

dao.delete(Person.class,"Peter");

根据 ID 删除 (如果你的实体声明了 @Id 字段)

dao.delete(Person.class,2);

直接删列表. 如果要按条件删,用dao.clear

dao.delete(list);

查询 Query

查询全部记录

List<Person> people = dao.query(Person.class, null);

按条件查询

List<Person> people = dao.query(Person.class, Cnd.where("name", "like", "P%"));
  • Cnd 类的全名是 org.nutz.dao.Cnd
    • 它主要是用来快速替你建立一个 org.nutz.dao.Condition 接口的实现类
    • where() 函数 第一个参数是字段名,要和 Java 类里面的字段名相同。
    • where() 函数 第二个参数遵循 SQL 的标准,可以是 >, <, >=, <= 等等
    • 提供了一个 wrap 函数,你可以直接写 SQL 的条件
  • 如果你愿意,你完全可以自己实现一个 Condition,来做更复杂灵活的判断
  • 关于更多的查询条件的说明,请参看 复杂条件

分页查询

List<Person> people = dao.query(Person.class, Cnd.where("age", ">", 18), dao.createPager(2, 4));
  • dao.createPager 第一个参数是第几页,第二参数是一页有多少条记录
  • 关于分页更多的说明,请参看 分页查询

清除 Clear

清除所有记录

dao.clear(Person.class); //还是那句,慎用

按条件清除

dao.clear(Person.class,Cnd.where("id", ">", 35));
  • 关于更多的清除条件的说明,请参看 复杂条件

插入和更新集合

无论是插入 (Insert) 还是更新 (Update),你传入的对象都可以不仅仅是一个 POJO,你可以传入:

  • 集合 ( Collection<?> )
  • Map<?,?>
  • 数组 ( T[] )

Nutz.Dao 会自动替你拆包,对集合成员依次执行相应操作。 对于 Map,它会迭代每一个值。

集合操作(func)

整数类型. 例如调用sum

dao.func(Person.class, "sum", "age");

其他类型

dao.func2(Person.class, "min", "price");

自动建表

Dao接口有一个create方法,通过它可以让nutz为你建好数据库表

dao.create(Pet.class, false);

第一个参数是Pojo类, 第二个参数是如果表存在,是不是先删再重新建,否则就是保持原样

字段的详细定义,例如定义长度

@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;
    //... 其他属性
}

局限性

  • 不生成外键,我们也不推荐用外键
  • 只能解决一般建表需求,复杂的表结构请通过自定义sql完成

批量建表,扫描某个package下的bean,为带@Table注解的类建表

Daos.createTablesInPackage(dao, "net.wendal.nutzbook.bean", false);

表结构自动迁移

// 单个迁移
Daos.migration(dao, User.class, true, false, false); // 新增字段true,删除字段false,检查索引false

// 批量迁移
Daos.migration(dao, "net.wendal.nutzbook.bean", true, false, false);