跳到主要内容

保存长关联

何谓长关联

所谓长关联,指不仅要改变当前对象和其他对象之间的关联关系,还要进一步修改关联对象。

对于UI界面而言,通常表现为父子表单的嵌套 (甚至树形递归)。形式多样,以表单内嵌子表颇为常见,如下:

商品数量单价明细价删除
268536
238238
总额:774
信息

只要开发人员愿意,这种父子表单嵌套结构的深度可以不只两层,从理论上讲,深度可以无限,这就是称其为长关联的原因。

编写DTO

在当前例子的在实体定义中,比较适合作为长关联的例子是保存BookStore以及它的books关联集合。

  1. 安装DTO语言Intellij插件:https://github.com/ClearPlume/jimmer-dto (此过程不是必须的,但非常推荐)

  2. 新建目录src/main/dto

  3. src/main/dto下建立一个文件BookStore.dto,编写代码如下

    BookStore.dto
    export org.doc.j.model.BookStore
    -> package org.doc.j.model.dto

    input BookStoreWithLongAssociation {
    #allScalars(this)
    books { // LongAssociation
    #allScalars(this)
    -id
    id(authors) as authorIds
    }
    }

生成的代码

编译,Jimmer会生成如下代码

BookStoreWithLongAssociation.java
@GeneratedBy(
file = "<yourproject>/src/main/dto/BookStore.dto"
)
public class BookStoreWithLongAssociation implements Input<BookStore> {

@Nullable
private Long id;

@NotNull
private String name;

@Nullable
private String website;

@NotNull
private List<TargetOf_books> books;

...省略其他方法...

public static class TargetOf_books implements Input<Book> {

@NotNull
private String name;

private int edition;

@NotNull
private BigDecimal price;

@NotNull
private List<Long> authorIds;

...省略其他方法...
}
}

编写HTTP服务

BookStoreController.java
@RestController
public class BookStoreController {

private final JSqlClient sqlClient;

public BookController(JSqlClient sqlClient) {
this.sqlClient = sqlClient;
}

@PutMapping("/bookStore")
pubic int saveBookStoreWithLongAssociation(
@RequestBody BookStoreWithLongAssociation input
) {
return sqlClient
.save(input)
.getTotoalAffectedRowCount();
}
}

可见,无论Input DTO如何改变,Jimmer仍然只需一个方法调用即可完成数据保存。