57

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

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

SELECT i FROM ObjectName i WHERE i.id = 10

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

如果不使用标准查询,这可能吗?

4

6 回答 6

99

是的,就像在普通 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();

示例可以在本文中找到。

2018 年 3 月 29 日更新:

@克里什:

@PatrickLeitermann 对我来说它给出了 "Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate class ***" 异常。如何解决这个问题?

我猜你是在 Spring 应用程序的上下文中使用 JPA,不是吗?其他一些人遇到了完全相同的问题,他们的解决方案是在SELECT NEW关键字之后添加完全限定名称(例如 com.example.CustomObject) 。

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

于 2014-07-12T07:34:22.280 回答
24

你可以使用这样的东西:

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[]

于 2014-07-12T07:28:21.257 回答
12

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

从文档

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

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);
}
于 2016-08-28T07:38:11.780 回答
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();
于 2015-10-07T16:24:49.483 回答
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'
于 2014-07-12T07:28:38.100 回答
0

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

于 2014-07-12T07:31:47.157 回答