使用Mapstruct和MyBatis映射嵌套列表对象

时间:2018-10-11 20:52:41

标签: spring-boot mybatis mapstruct

我不确定如何将嵌套结果集映射到域实体中。

下面是我要做什么的一个简单主意:

2张桌子

------------
BOOKS
------------
STUDENT_ID
BOOK_NAME
DUE_DATE

------------
STUDENTS
------------
STUDENT_ID
STUDENT_NAME

DomainEntity (它包含嵌套列表)

LoanEntity.java

String studentId;
String studentName;
List<Book> books;

Book.java

String studentId;
String bookName;
Date dueDate;

PersistenceEntity

Loans.java

String studentId;
String studentName;
String bookName;
Date dueDate;

Dao.xml (不确定如何映射,请尝试使用one

<resultMap id="loanMap" type="com.persistence.entity.Loans">
    <id property="studentId" column="studentId"/>
    <result property="studentName" column="studentName"/>
    <result property="bookName" column="bookName"/>
    <result property="dueDate" column="dueDate"/>

...

请注意,此查询将复制找到的图书数量的记录。

SELECT
    s.STUDENT_ID, s.STUDENT_NAME, b.BOOK_NAME, b.DUE_DATE
FROM STUDENTS s
LEFT JOIN
    BOOKS b ON s.STUDENT_ID=b.STUDENT_ID

LoanMapper.java

@Mappings({
    @Mapping(source="studentId", target="studentId"),
    @Mapping(source="studentName", target="studentName"),
    @Mapping(source="bookName", target="books.bookName"),
    @Mapping(source="dueDate", target="books.dueDate")
})
LoanEntity persistenceToDomainEntity(Loans loans);

List<LoanEntity> persistenceToDomainEntity(List<Loans> loans);

以下是我得到的错误:

错误:结果类型为com.loan.domain.model.Loan的未知属性“ books.bookName”。您是说“ books.empty”吗? 错误:结果类型为com.loan.domain.model.Loan的未知属性“ books.dueDate”。您是说“ books.empty”吗?

1 个答案:

答案 0 :(得分:0)

books是复数。因此有一个Collection。 MapStruct无法在嵌套映射(通常包含books.bookname)中实现.之类的功能。这种情况下的原因很简单。您尝试将列表中的内容映射到单个对象bookName。 MapStruct如何知道列表中应该选择哪个对象?您希望它生成哪些代码?

因此,要解决此问题:您可以让MapStruct来完成大部分工作(我想您比studentIdstudentName拥有更多的属性负载。然后,您可以再写一个手写的这样的方法:

@AfterMapping
default void persistenceToDomainEntity(Loans loans, @MappingTarget LoanEntity loanEntity) {
   loanEntity.setBookName( loans.getBooks().get(0).getBookName() ); //?
   loanEntity.setDueDate( loans.getBooks().get(0).getDueDate() ); //?
}

@Mappings({
    @Mapping(source="studentId", target="studentId"),
    @Mapping(source="studentName", target="studentName"),
    @Mapping(source="bookName", ignore = true),
    @Mapping(source="dueDate", ignore = true)
})
LoanEntity persistenceToDomainEntity(Loans loans);

也就是说,假设您需要第一个结果。

但是也许还有更好的与DB集成的解决方案。在MapStruct repo上查看示例。 JPA上的一个使用上下文与数据库交互。