2

我是 JPA 的新手,我为我的 Web 服务编写了简单的 JPA 选择。我之前使用的是经典的 SQL 语句。太好了,我知道如何获得稳定的速度,但我现在在 5 个不同的项目中使用 3 个不同的数据库。所以我认为学习 JPA 是使用一种技术而不是必须了解 3 种 SQL 语言的好方法。所以我创建了一些表、实体并尝试使用 JPA。但是第一时间出了点问题——速度。

(我正在使用 MSSQL 2008)

我比较了简单的原生 SQL 选择和 JPA 选择:

em.createNativeQuery("SELECT c.* FROM Table c", MyTable.class);

em.createQuery("SELECT c FROM Table c", MyTable.class)

createNativeQuery快了 5 倍,但为什么呢?

所以我启动了包含在 MSSQL 包中的 SQL 分析器并调试了 JPA 正在做什么。我有一张包含 100 条记录的表,我所看到的让我感到惊讶:

  • createNativeQuery创建 1 个对 db 的请求,结果是查询中的 100 条记录
  • createQuery创建 100 个请求,每个请求返回 1 条记录。像这样的东西:

    1 SELECT Col1, Col2 FROM TABLE WHERE (ID = ?)<br>
    2 SELECT Col1, Col2 FROM TABLE WHERE (ID = ?)<br>
    .
    .
    .
    100 SELECT Col1, Col2 FROM TABLE WHERE (ID = ?)
    

我将 JPA 2 与 Eclipse Link 一起使用。这是 JPA 工作方式的正常行为吗?或者我在设置中做错了什么。

4

3 回答 3

1

这样做是为了优化不需要一次使用所有结果对象的场景。EclipseLink 首先加载对象骨架,当您遍历对象时,它会在场景后面填充它们。

如果您想一次加载所有对象,那么我认为QueryHint以下内容应该会有所帮助:

  Query query = em.createQuery("SELECT c FROM Table c", MyTable.class)
  query.setHint(QueryHints.BATCH_SIZE, 100); //set any appropriate batch size
于 2012-11-27T19:26:08.000 回答
0

您不应该使用createNativeQuery您提供的简单示例。

尝试这样的事情(Query改用):

    Query agedUsers = em.createQuery( "SELECT u " + "FROM Users u "
            + "WHERE u.age = :age" );
    agedUsers.setParameter( "age", age);
    List<User> users = agedUsers.getResultList();

表名是实体的名称,您必须使用别名而不是*.

于 2012-11-27T19:26:45.697 回答
0

抱歉,当让 jpa 使用逐行加载和使用 QueryHints.BATCH_SIZE 时,我有点乱。您能解释一下何时创建骨架以及何时填充数据吗?
当我将数据返回到列表时:

列出用户 =agedUsers.getResultList();

我已将列表映射到primefaces dataTable,当呈现dataTable 或查询返回列表时填充数据?

什么时候让 jpa 逐行加载数据有用,什么时候使用 QueryHints.BATCH_SIZE 加载数据更好?

于 2012-11-28T06:23:48.237 回答