我是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如何工作的正常行为?或者我在我的设置中做错了什么。
答案 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)
列出users = agedUsers.getResultList();
我将列表映射到primefaces dataTable,在呈现DataTable时填充数据,或者在查询返回时填充数据 列出?
什么时候有用让jpa逐行加载数据,什么时候使用QueryHints.BATCH_SIZE更好地加载数据?