草庐IT

java - Spring Data JPA Projection 从数据库中选择的字段

coder 2023-05-18 原文

我正在测试 Spring Data 1.10.4.RELEASE,遵循 Spring Data Docs http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections 中的示例

我注意到一些问题,我有 2 个问题。

首先让我们假设我有这两个实体:

@Entity
public class Person {

  @Id @GeneratedValue
  private Long id;
  private String firstName, lastName;

  @OneToOne
  private Address address;
}

@Entity
public class Address {

  @Id @GeneratedValue
  private Long id;
  private String street, state, country;
}
  • 问题 1:

对于以下预测:

interface PersonLimited {  

  String getFirstName(); 

  AddressLimited getAddress();
}

interface AddressLimited {  

  String getCountry(); 
}

当我运行 findPersonByFirstNameProjectedForLimitedData

interface PersonRepository extends CrudRepository<Person, Long> {

  @Query("select p from Person p where p.firstName = ?1")
  PersonLimited findPersonByFirstNameProjectedForLimitedData(String firstName);
}

它返回的正是预期的:

{
    firstName: 'Homer',
    address: {
        country: 'USA'
    }
}

现在,如果我查看生成的 SQL,这就是我所拥有的:

SELECT person0_.firstName      AS col_0_0_, 
       address1_.id            AS id1_13_, 
       address1_.street        AS street2_13_, 
       address1_.state         AS state3_13_, 
       address1_.country       AS country4_13_
FROM   person person0_ 
       LEFT OUTER JOIN address address1_ 
                    ON person0_.addressId = address1_.id 
WHERE  person0_.firstName = ?  

“Person”实体的投影仅选择“fistName”,这是 100% 正确的,因为在 PersonLimited 接口(interface)中我只定义了“getFirstName”。

但是对于“Address”实体,它选择了所有字段,这是错误的,因为在AddressLimited接口(interface)中我只定义了“getCountry”,它应该只选择“country”。

生成的查询应该是这样的:

SELECT person0_.firstName      AS col_0_0_, 
       address1_.country       AS country4_13_
FROM   person person0_ 
       LEFT OUTER JOIN address address1_ 
                    ON person0_.addressId = address1_.id 
WHERE  person0_.firstName = ?  

所以问题是,为什么它不只为地址“实体”选择“国家”字段?为什么需要选择所有字段?这是 Spring 中的错误吗?

  • 问题 2:

对于与上面相同的投影,

当我运行 findAllPersonsProjectedForLimitedData

interface PersonRepository extends CrudRepository<Person, Long> {

  @Query("select p from Person p")
  List<PersonLimited> findAllPersonsProjectedForLimitedData();
}

它返回的正是预期的:

[
     {
        firstName: 'Homer',
        address: {
            country: 'USA'
        }
     },
     {
        firstName: 'Maggie',
        address: {
            country: 'USA'
        }
     }
]

现在,如果我查看生成的 SQL,这就是我所拥有的:

SELECT person0_.id                 AS id1_18_, 
       person0_.firstName          AS firstName2_18_, 
       person0_.lastName           AS lastName3_18_, 
       person0_.addressid          AS company4_18_
FROM   person person0_ 

SELECT address0_.id         AS id1_13_0_, 
       address0_.street     AS street2_13_0_, 
       address0_.state      AS state3_13_0_, 
       address0_.country    AS country4_13_0_
FROM   address address0_ 
WHERE  address0_.id = ? 

这里,Person 和 Address 实体的投影都选择了所有错误的字段,它应该只选择“firstName”和“country”。

生成的查询应该是这样的:

SELECT person0_.firstName        AS firstName2_18_
FROM   person person0_ 

SELECT address0_.country    AS country4_13_0_
FROM   address address0_ 
WHERE  address0_.id = ? 

这是正常行为吗,不应该只选择我们需要的字段吗?

谢谢,

最佳答案

如果您想将注释 @Query 与 Spring Data Projections 一起使用,您必须使用字段别名,并且您需要确保为与投影字段匹配的项目设置别名。以下代码适用于问题 1:

interface PersonRepository extends CrudRepository<Person, Long> {

  @Query("select p.firstName as firstname, p.address as address from Person p where p.firstName = ?1")
  PersonLimited findPersonByFirstNameProjectedForLimitedData(String firstName);
}

您可以使用的另一种方法是使用 Property Expressions 定义您的查询。 .只要有可能:

interface PersonRepository extends CrudRepository<Person, Long> {

  List<PersonLimited> findByFirstName(String firstName);
}

关于java - Spring Data JPA Projection 从数据库中选择的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40194614/

有关java - Spring Data JPA Projection 从数据库中选择的字段的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  3. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  4. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  5. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  6. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  9. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  10. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

随机推荐