Java Spring数据jpa,jpa替代DTO对象的字符串的正向返回列表

Java Spring数据jpa,jpa替代DTO对象的字符串的正向返回列表,java,spring,jpa,spring-data,spring-data-jpa,Java,Spring,Jpa,Spring Data,Spring Data Jpa,我有一个接口实现JPARepository,有三种方法,其中一种是自定义@查询 public interface PersonRepository extends JpaRepository<Person, Long> { List<Person> getPersonBycountryCode(String countryCode); List<Person> findByCountryCodeAndCity(String string,Strin

我有一个
接口
实现
JPARepository
,有三种方法,其中一种是自定义
@查询

public interface PersonRepository extends JpaRepository<Person, Long> {

  List<Person> getPersonBycountryCode(String countryCode);

  List<Person> findByCountryCodeAndCity(String string,String city);

  @Query(value = "SELECT person.firstName as firstName, person.lastName as lastName, person.countryCode as country, person.city as city,"
              + " SQRT(POWER((69.1 * (person.age - :age )) , 2 )"
              + " + POWER((53 * (person.experience - :experience )), 2)) as eligibility"
              + " FROM Person person"
              + " ORDER BY eligibility ASC")
  List<PersonDetailsDto> findPersonDetailsByEligibility(
          @Param("age") BigDecimal age,
          @Param("experience") BigDecimal experience,
          Pageable pageable
  );
}
公共接口PersonRepository扩展了JpaRepository{
列出getPersonBycountryCode(字符串countryCode);
列出findByCountryCodeAndCity(字符串字符串,字符串城市);
@查询(value=“选择person.firstName作为firstName,person.lastName作为lastName,person.countryCode作为country,person.city作为city,”
+SQRT(权力((69.1*(人.年龄-:年龄)),2)
+“+权力((53*(person.experience-:experience)),2))作为资格”
+“来自个人”
+“按资格排序ASC”)
列出FindPersonDetailsByLigibility(
@参数(“年龄”)大十进制年龄,
@Param(“经验”)BigDecimal经验,
可寻呼可寻呼
);
}
问题是:使用
@Query
的方法不返回
persondetailsdo的列表,而是返回字符串列表(

PersonDetailsDto
是一个POJO类,包含查询输出中描述的所有变量(firstName、lastName、country、city、qualification),也是一个构造函数,包含所有变量作为参数。其他两个方法不返回Person对象的列表


有什么想法吗?

如果我没有错的话,JPA不寻找特定字段的想法是,从表的一行中获取一列或所有列的成本(效率)是相同的。但要解决您的问题,您可以从存储库类的
@Query
注释中设置
nativeQuery=true
,如下所示:

public static final String FIND_SOMETHING = "SELECT somethingId, somethingName FROM something";

@Query(FIND_SOMETHING, nativeQuery = true)
public List<Object[]> findSomethings();
public static final String FIND\u SOMETHING=“从某物中选择somethingId,somethingName”;
@查询(FIND_SOMETHING,nativeQuery=true)
公共列表查找某些内容();

我希望这将帮助您解决问题。

您可以在@query的查询中使用new关键字。并确保为PersonDetailsDto提供了适当的构造函数,并更改包名

@Query(value = "SELECT new com.company.PersonDetailsDto(person.firstName, person.lastName, person.countryCode , person.city ,"
          + " SQRT(POWER((69.1 * (person.age - :age )) , 2 )"
          + " + POWER((53 * (person.experience - :experience )), 2)) "
          + " FROM Person person"
          + " ORDER BY eligibility ASC")
List<PersonDetailsDto> findPersonDetailsByEligibility(
      @Param("age") BigDecimal age,
      @Param("experience") BigDecimal experience,
      Pageable pageable
);
@Query(value=“选择新建com.company.persondetailsdo(person.firstName、person.lastName、person.countryCode、person.city,”
+SQRT(权力((69.1*(人.年龄-:年龄)),2)
+“+权力((53*(person.experience-:experience)),2”)”
+“来自个人”
+“按资格排序ASC”)
列出FindPersonDetailsByLigibility(
@参数(“年龄”)大十进制年龄,
@Param(“经验”)BigDecimal经验,
可寻呼可寻呼
);

类似。

实际上
JpaRepository
意味着,在jpa存储库方法中,只能使用Person作为dto

对于您的解决方案,您只需在存储库中定义dto接口:

public interface PersonRepository extends JpaRepository<Person, Long> {

  List<Person> getPersonBycountryCode(String countryCode);

  List<Person> findByCountryCodeAndCity(String string,String city);

  @Query(value = "SELECT person.firstName as firstName, person.lastName as lastName, person.countryCode as country, person.city as city,"
              + " SQRT(POWER((69.1 * (person.age - :age )) , 2 )"
              + " + POWER((53 * (person.experience - :experience )), 2)) as eligibility"
              + " FROM Person person"
              + " ORDER BY eligibility ASC")
  List<PersonDetailsDto> findPersonDetailsByEligibility(
          @Param("age") BigDecimal age,
          @Param("experience") BigDecimal experience,
          Pageable pageable
  );

 //define the interface here
 public interface PersonDetailsDto{
   public String getFirstName();
   public String getLastName();
   public String getCountry();
   public String getCity();
   public Integer getEligibility();
 }

}
公共接口PersonRepository扩展了JpaRepository{
列出getPersonBycountryCode(字符串countryCode);
列出findByCountryCodeAndCity(字符串字符串,字符串城市);
@查询(value=“选择person.firstName作为firstName,person.lastName作为lastName,person.countryCode作为country,person.city作为city,”
+SQRT(权力((69.1*(人.年龄-:年龄)),2)
+“+权力((53*(person.experience-:experience)),2))作为资格”
+“来自个人”
+“按资格排序ASC”)
列出FindPersonDetailsByLigibility(
@参数(“年龄”)大十进制年龄,
@Param(“经验”)BigDecimal经验,
可寻呼可寻呼
);
//在这里定义接口
公共接口persondetailsdo{
公共字符串getFirstName();
公共字符串getLastName();
公共字符串getCountry();
公共字符串getCity();
公共整数getquality();
}
}

只要用它的别名来称呼它,它对我来说就是这样 例:

@Query(value=“从人员中选择人员”
+“按资格排序ASC”)
列出FindPersonDetailsByLigibility(
@参数(“年龄”)大十进制年龄,
@Param(“经验”)BigDecimal经验,
可寻呼可寻呼
);

首先,其中一些语法是无效的JPQL(POWER,SQRT)。其次,您没有为查询指定结果类(或者在JPQL中使用了“NEW PersonDetailsDto(…))。谢谢,但它对我不起作用。它在生成过程中引发了hibernate异常,说明找不到PersondetailsTo类。我相信我的配置存在问题。hibernate似乎没有选择非实体类。请提供完全限定的包名,然后重试。例如,选择new com.company.PersondetailsTo(…)我尝试了这个方法,首先它给了我一个异常,说明本机查询不允许使用Pageable(动态分页和排序选项)。然后我从方法中删除了Pageable参数,但它仍然给了我相同的结果列表来代替List
@Query(value = "SELECT person FROM Person person"
          + " ORDER BY eligibility ASC")
List<PersonDetailsDto> findPersonDetailsByEligibility(
      @Param("age") BigDecimal age,
      @Param("experience") BigDecimal experience,
      Pageable pageable
);