gpt4 book ai didi

java - Eclipselink:批量读取创建大量查询

转载 作者:行者123 更新时间:2023-11-30 06:50:24 25 4
gpt4 key购买 nike

我使用 eclipselink 2.6.4 并且我有以下实体

@Entity
@Table(name = "articles")
public class Article {

@Id
@Column(name = "id")
private Integer id;

@Column(name = "title")
private String title;

@OneToMany(fetch = FetchType.EAGER,mappedBy = "article")
@BatchFetch(BatchFetchType.IN)
private List<Author> authors

//+ setters and getters
}

@Entity
@Table(name = "authors")
public class Author {

@Id
@Column(name = "id")
private Integer id;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "articleId")
private Article article;

@Column(name = "surname")
private String surname;

//+setters and getters
}

这是我用来阅读所有作者文章的代码:

String queryString="SELECT e FROM Article e";
Query query = em.createQuery(queryString);
query.setHint("eclipselink.batch.type", "IN");
query.setHint("eclipselink.batch", "e.authors");
query.setFirstResult(position);
query.setMaxResults(amount);
List<Article> items=query.getResultList();

在 DB 中,我有 3 篇文章,每篇文章都有两位作者。这些是 eclipse 链接执行的查询:

SELECT id AS a1, title AS a2 FROM articles LIMIT ? OFFSET ? bind => [2 parameters bound]
SELECT id, surname, articleId FROM authors WHERE (articleId IN (?,?,?)) bind => [3 parameters bound]
SELECT id, title FROM articles WHERE (id IN (?,?)) bind => [2 parameters bound]
SELECT id, surname, articleId FROM authors WHERE (articleId = ?) bind => [1 parameter bound]
SELECT id, surname, articleId FROM authors WHERE (articleId = ?) bind => [1 parameter bound]

为什么有这么多查询?我希望只有两个查询。我的错误是什么?

编辑
我又做了两个测试:

  1. 我只在字段作者的 Article 类中使用了注释 @BatchFetch(BatchFetchType.IN)(没有添加查询提示)
  2. 我没有使用注释 @BatchFetch(BatchFetchType.IN) 但在查询中使用了两个提示:

    String queryString="SELECT e FROM Article e";查询 query = em.createQuery(queryString);query.setHint("eclipselink.batch.type", "IN");query.setHint("eclipselink.batch", "e.authors");query.setFirstResult(0);查询.setMaxResults(10);List items=query.getResultList();

文章表中的数据:

| id | title    |
-----------------
| 1 | article1 |
| 2 | article2 |
| 3 | article3 |

作者表中的数据:

| id | articleId |  surname  |
------------------------------
| 1 | 1 | Author1 |
| 2 | 1 | Author2 |
| 3 | 2 | Author3 |
| 4 | 2 | Author4 |
| 5 | 3 | Author5 |
| 6 | 3 | Author6 |

在每个测试中执行 6 个查询:

SELECT id AS a1, title AS a2 FROM articles LIMIT ? OFFSET ? bind => [2 parameters bound]
SELECT id, surname, articleId FROM authors WHERE (articleId IN (?,?,?)) bind => [3 parameters bound]
SELECT id, title FROM articles WHERE (id = ?) bind => [1 parameter bound]
SELECT id, surname, articleId FROM authors WHERE (articleId = ?) bind => [1 parameter bound]
SELECT id, title FROM articles WHERE (id = ?) bind => [1 parameter bound]
SELECT id, surname, articleId FROM authors WHERE (articleId = ?) bind => [1 parameter bound]

最佳答案

我们可以通过两种方式设置批量获取。

  1. 注解 @BatchFetch(BatchFetchType.IN)
  2. 查询提示 query.setHint(QueryHints.BATCH, column); query.setHint(QueryHints.BATCH_TYPE, BatchFetchType.IN);

在你的情况下,我看到你在 Author 表中添加了注释,但带有提示的查询是在 Article 表上完成的。我不知道这背后的全部逻辑,但我建议:

@Entity
@Table(name = "articles")
public class Article {

@Id
@Column(name = "id")
private Integer id;

@Column(name = "title")
private String title;

@OneToMany(mappedBy = "article", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@BatchFetch(BatchFetchType.IN)
private List<Author> authors

//+ setters and getters
}

@Entity
@Table(name = "authors")
public class Author {

@Id
@Column(name = "id")
private Integer id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "articleId")
private Article article;

@Column(name = "surname")
private String surname;

//+setters and getters
}

不要使用该注释,仅使用提示进行查询:

String queryString="SELECT e FROM Article e";
Query query = em.createQuery(queryString);
query.setHint("eclipselink.batch.type", "IN");
query.setHint("eclipselink.batch", "e.authors");
query.setFirstResult(position);
query.setMaxResults(amount);
List<Article> items=query.getResultList();

还有一点:根据 JPA 2.0 规范,默认值如下所示:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

Eclipse 链接使用相同的:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

@OneToMany 必须是 (fetch = FetchType.EAGER),@ManyToOne 必须是 (fetch = FetchType.LAZY)。

关于java - Eclipselink:批量读取创建大量查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41415680/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com