java - MySql - 一对多连接,将 JOIN 与 JDBI 映射到列表
问题描述
我正在尝试使用 JDBI 编写一个对象查询,它将从左表中获取一个完整的行,并将右表中的所有匹配行作为一个列表连接起来(一个作者可以有很多书)。
作者
id, name, createdAt, updatedAt, email, phoneNumber
书
id, title, authorId, categories, createdAt, updatedAt
我要创建的最终对象的结构如下:
class AuthorWithBooks() {
int id,
String name,
List<String> categories,
long createdAt,
long updatedAt,
String email,
String phoneNumber
List<Book> books
}
书在哪里:
class Book {
id,
title,
authorId,
categories,
createdAt,
updatedAt
}
这是我正在尝试的查询(不按原样抓取书籍)
@SqlQuery("SELECT " + AUTHOR_COLUMN MAMES + ", " + BOOK_COLUMN_NAMES + " FROM authors as author" +
" LEFT JOIN books AS book" +
" ON author.id = book.authorId" +
" WHERE id = :authorId")
List<AuthorWithBooks> getAuthorWithBooks(@Bind("authorId") int authorId);
将不胜感激任何帮助/有人指出我正确的方向!
谢谢!
解决方案
看来您需要@UseRowReducer
您的示例的实现如下所示:
@SqlQuery("SELECT a." + AUTHOR_COLUMN MAMES + ", b." + BOOK_COLUMN_NAMES + " FROM authors as author" +
" LEFT JOIN books AS book" +
" ON author.id = book.authorId" +
" WHERE id = :authorId")
@RegisterBeanMapper(value = Book.class, prefix = "b")
@RegisterBeanMapper(value = AuthorWithBooks.class, prefix = "a")
@UseRowReducer(AuthorBookReducer.class)
List<AuthorWithBooks> getAuthorWithBooks(@Bind("authorId") int authorId);
class AuthorBookReducer implements LinkedHashMapRowReducer<Integer, Author> {
@Override
public void accumulate(Map<Integer, Author> map, RowView rowView) {
Author author = map.computeIfAbsent(rowView.getColumn("a_id", Integer.class),
id -> rowView.getRow(Author.class));
if (rowView.getColumn("b_id", Integer.class) != null) {
author.getBooks().add(rowView.getRow(Book.class));
}
}
}
推荐阅读
- django - 熊猫,转换日期时间列格式的更改列类型
- crystal-reports - 交叉表报表查询
- c# - 在 C# Web Api 核心的控制器中动态实现服务
- angular - Angular / RXJS - 如何在 switchMap 之后执行逻辑
- c# - 如何在 api 中限制访问令牌的使用
- java - 如何将 XML 文件正确转换为字符串?
- python - 如何使用带有 Streamlit 的按钮显示文件夹中的图像?
- azure - 在c#中获取存储帐户文件共享中上传的所有文件
- kubernetes - 使用 Keda 强制缩放为零
- swift - Swift 如何使用复选框“记住我”来保护用户登录会话