JPA select为db,performance创建了许多请求

时间:2012-11-27 19:19:34

标签: java jpa-2.0 eclipselink

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

(我正在使用MSSQL 2008)

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

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

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

createNativeQuery速度提高了5倍,但为什么呢?

所以我启动了包含在MSSQL包中的SQL profiler并调试了JPA正在做的事情。 我有一张包含100条记录的表格,我看到的东西让我感到惊讶:

  • createNativeQuery向db创建1个请求,结果为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 = ?)
    

我正在使用带有Eclipse Link的JPA 2。这是JPA如何工作的正常行为?或者我在我的设置中做错了什么。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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();

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

答案 2 :(得分:0)

抱歉,当jpa使用逐行加载和使用QueryHints.BATCH_SIZE时,我有点乱。 你能解释我什么时候创建骨架以及什么时候填充数据? 当我将数据返回列表时:

列出users = agedUsers.getResultList();

我将列表映射到primefaces dataTable,在呈现DataTable时填充数据,或者在查询返回时填充数据 列出?

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