添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
光明磊落的蚂蚁  ·  ZYaller/tag/linux/linu ...·  1 月前    · 
深情的青蛙  ·  tensorflow::ops::Softm ...·  2 月前    · 
礼貌的凉面  ·  Help And Training ...·  2 月前    · 

有两张数据表,其中A表的某个字段的值指向B表的主键。因为B表的任何一条记录理论上可以对应A表的多条记录,所以称这种 映射为B表对A表数据的一对多映射。

上述结构,如果用 POJO 来表示的话,可以参看下图:

如上图,一个 Master 自然就能对应多个 Pet ,所以, Master.pets (一个 List<Pet> ) 就可以指向多个 Pet 对象, 那么我们说 Master.pets 就是 Master 对 Pet 的一对多映射。

在 POJO 中配置一对多映射

在 POJO 类中字段中增加注解 @Many @Table("t_master") public class Master extends Pojo { @Many(field = "masterId") // 1.r.59之前需要写target参数 // @Many(target = Pet.class, field = "masterId") private List<Pet> pets; public List<Pet> getPets() { return pets; public void setPets(List<Pet> pets) { this.pets = pets;

在 Master 对象中必须存在一个 List<Pet> 类型的字段,你的一对多映射就需要配置在这个字段上。通过 @Many 注解告诉 Nutz.Dao 对象 Pet 和 Master 对象的关系,其中:

  • 1.r.59之前你需要使用 target 表示你要映射的对象类型, 新版能自动识别类型.若识别失败,则需要主动声明target类型,并烦请报个issue给我们.
  • field 表示你打算依靠 目标对象 的哪一个属性来映射本对象的主键
  • 目标 POJO 类 ( Pet )中 必须 存在一个属性,用来同本 POJO POJO 类的主键 关联
  • 还要注意 ,这里的名称是 目标 POJO 的 JAVA 字段的名称。
  • 注意 ,这里是大小写敏感的。
  • 该字段必须同本 POJO 类的主键 类型相同
  • 如果你已经实现准备好了这样的对象: Master master = new Master(); master.setName("Peter"); List<Pet> pets = new ArrayList<Pet>(); pets.add(new Pet("XiaoBai")); pets.add(new Pet("XiaoHei")); master.setPets(pets);

    那么你可以一次将 master 以及它对应的 pets 一起插入到数据表中 dao.insertWith(master, "pets");

    Nutz.Dao 会根据正则表达式 "pets" 寻找可以被匹配上的映射字段(只要声明了 @One, @Many, @ManyMany 任何一个注解,都是映射字段) 并根据注解具体的配置信息,执行相应的 SQL。比如上面的操作,会实际上: 执行 SQL : INSERT INTO t_master (name) VALUES("Peter"); 执行 SQL 获取 最大值: SELECT MAX(id) FROM t_master // 假设返回的值是 29 将该最大值 29 赋给 master 对象的主键 id 循环 master.pets,将该最大值 29 赋给每一个 pet 对象的 pet.masterId 字段 执行 SQL : INSERT INTO t_pet (name,masterId) VALUES("XiaoBai",29) 执行 SQL : INSERT INTO t_pet (name,masterId) VALUES("XiaoHei",29)

    这里通过 SELECT MAX 来获取插入的最大值,是默认的做法,如果你想修改这个默认做法,请参看 关于主键 一章。

  • 这里因为是一对多映射,所以会首先插入主对象,以便用新的主键值更新映射对象的映射字段
  • 如果你的对象中包括多个 @Many 字段,被你的正则式匹配上,那么这些字段对应的字段(如果不为null)都会被匹配,并首先被插入
  • 当然,你要想选择仅仅只插入映射字段的话,你可以: dao.insertLinks(master,"pets");

    那么上述操作实际上会执行: 循环 master.pets,将该master.id (主键) 赋给每一个 pet 对象的 pet.masterId 字段,我们假设该值为 29 执行 SQL : INSERT INTO t_pet (name,masterId) VALUES("XiaoBai",29) 执行 SQL : INSERT INTO t_pet (name,masterId) VALUES("XiaoHei",29)

    看,并不会插入 master 对象。

    仅仅获取映射对象: Master master = dao.fetch(Master.class, "Peter"); dao.fetchLinks(master, "pets");

    这会执行操作: 执行 SQL: SELECT * FROM t_master WHERE name='Peter'; // 如果 master.id 是 12 执行 SQL: SELECT * FROM t_pet WHERE masterId=12;

    但是 Nutz.Dao 没有提供一次获取 master 对象以及 pets 对象的方法,因为,你完全可以把上面的两句话写在一行上: Master master = dao.fetchLinks(dao.fetch(Master.class, "Peter"), "pets");

    然后,你可以通过 master.getPets() 得到 Nutz.Dao 为 master.pets 字段设置的值。

    同时更新 pet 和 master dao.updateWith(master, "pets"); 执行SQL: UPDATE t_master .... 循环 master.pets 并依次执行SQL: UPDATE t_pet ...

    仅仅更新 pets dao.updateLinks(master, "pets"); 循环 master.pets 并依次执行SQL: UPDATE t_pet ...

    同时删除 master 和 pets dao.deleteWith(master, "pets");

    仅仅删除 pets dao.deleteLinks(master, "pets");

    清除 pets dao.clearLinks(master, "pets");

    清除同删除的区别在于,清除只会执行一条 SQL 删除一批映射对象,而且删除会逐个调用 dao.delete 来删除对象

    本页面的文字允许在 知识共享 署名-相同方式共享 3.0协议 GNU自由文档许可证 下修改和再使用。