JPA查询仅选择特定列而不使用Criteria Query?

时间:2014-07-12 07:15:41

标签: java jpa jpa-2.0 jpa-2.1 criteriaquery

是否可以使用JPA查询从对象中仅选择属性A和B而不使用条件查询?

要选择所有属性,我只需执行以下操作:

SELECT i FROM ObjectName i WHERE i.id = 10

但我在遗留系统上有一个很多属性的对象,并且想要选择一些,即使我知道选择多个属性通常很快。

如果不使用条件查询,这是否可行?

谢谢!

6 个答案:

答案 0 :(得分:80)

是的,就像在普通的SQL中一样,您可以指定要选择的属性类型:

SELECT i.firstProperty, i.secondProperty FROM ObjectName i WHERE i.id=10

执行此查询将返回Object []列表,其中每个数组都包含一个对象的选定属性。

另一种方法是将所选属性包装在自定义对象中并在TypedQuery中执行:

String query = "SELECT NEW CustomObject(i.firstProperty, i.secondProperty) FROM ObjectName i WHERE i.id=10";
TypedQuery<CustomObject> typedQuery = em.createQuery(query , CustomObject.class);
List<CustomObject> results = typedQuery.getResultList();

示例可以在this文章中找到。

更新29.03.2018:

@Krish:

  

@PatrickLeitermann为我提供了“引起:org.hibernate.hql.internal.ast.QuerySyntaxException:无法找到类***”的异常。怎么解决这个?

我猜你在Spring应用程序的上下文中使用JPA,不是吗?其他人确切地the same problem,他们的解决方案是在 SELECT NEW 关键字之后添加完全限定名称(例如com.example.CustomObject)。

也许Spring数据框架的内部实现只能识别用 @Entity 注释的类,或者通过简单名称在特定的orm文件中注册,这会导致使用这种解决方法。

答案 1 :(得分:16)

您可以使用以下内容:

List<Object[]> list = em.createQuery("SELECT p.field1, p.field2 FROM Entity p").getResultList();

然后你可以迭代它:

for (Object[] obj : list){
    System.out.println(obj[0]);
    System.out.println(obj[1]);
}

但是如果您在查询中只有一个字段,则会得到一个不是来自Object []

的类型列表

答案 2 :(得分:8)

优秀的答案!我确实有一个小的补充。关于这个解决方案:

TypedQuery<CustomObject> typedQuery = em.createQuery(query , String query = "SELECT NEW CustomObject(i.firstProperty, i.secondProperty) FROM ObjectName i WHERE i.id=100";
TypedQuery<CustomObject> typedQuery = em.createQuery(query , CustomObject.class);
List<CustomObject> results = typedQuery.getResultList();CustomObject.class);

要防止找不到类错误,只需插入完整的包名称即可。假设org.company.directory是CustomObject的包名:

String query = "SELECT NEW org.company.directory.CustomObject(i.firstProperty, i.secondProperty) FROM ObjectName i WHERE i.id=10";
TypedQuery<CustomObject> typedQuery = em.createQuery(query , CustomObject.class);
List<CustomObject> results = typedQuery.getResultList();

答案 3 :(得分:6)

Projections可用于仅选择实体对象的特定属性(列)。

来自文档

  

Spring Data Repositories通常在使用查询方法时返回域模型。但是,有时,您可能需要根据各种原因更改该模型的视图。在this部分中,您将学习如何定义投影以提供简化和缩减的资源视图。

定义仅包含所需getters的界面。

interface CustomObject {  
    String getA(); // Actual property name is A
    String getB(); // Actual property name is B 
}

现在从您的存储库返回CustomObject,如下所示:

public interface YOU_REPOSITORY_NAME extends JpaRepository<YOUR_ENTITY, Long> {
    CustomObject findByObjectName(String name);
}

答案 4 :(得分:0)

如果我正确理解了您的问题,我想您可以查看此链接http://www.javacodegeeks.com/2012/07/ultimate-jpa-queries-and-tips-list-part_09.html

例如,他们创建了一个类似的查询:

 select id, name, age, a.id as ADDRESS_ID, houseNumber, streetName ' +
 20' from person p join address a on a.id = p.address_id where p.id = 1'

答案 5 :(得分:0)

是的,有可能。您所要做的就是将查询更改为SELECT i.foo, i.bar FROM ObjectName i WHERE i.id = 10之类的内容。查询结果将是List数组的Object。每个数组中的第一个元素是i.foo的值,第二个元素是值i.bar。请参阅JPQL reference的相关部分。