我在我的项目中使用JPA。
我遇到一个查询,我需要对五个表进行连接操作。因此,我创建了一个返回五个字段的本机查询。
现在我想将结果对象转换为java POJO类,其中包含相同的五个字符串。
在JPA中有任何方法可以直接将结果转换为POJO对象列表吗??
我想出了如下的解决办法。
@NamedNativeQueries({
@NamedNativeQuery(
name = "nativeSQL",
query = "SELECT * FROM Actors",
resultClass = db.Actor.class),
@NamedNativeQuery(
name = "nativeSQL2",
query = "SELECT COUNT(*) FROM Actors",
resultClass = XXXXX) // <--------------- problem
})
现在在resultClass中,我们需要提供一个实际的JPA实体类吗?
或
我们可以将其转换为包含相同列名的任何JAVA POJO类?
使用DTO设计模式。它在EJB 2.0中使用。实体由容器管理。采用DTO设计模式来解决这一问题。
但是,当应用程序分别开发服务器端和客户端时,现在可能会使用它。DTO用于服务器端不想将带有注释的实体传递/返回给客户端。
DTO示例:
PersonEntity.java
@Entity
public class PersonEntity {
@Id
private String id;
private String address;
public PersonEntity(){
}
public PersonEntity(String id, String address) {
this.id = id;
this.address = address;
}
//getter and setter
}
PersonDTO.java
public class PersonDTO {
private String id;
private String address;
public PersonDTO() {
}
public PersonDTO(String id, String address) {
this.id = id;
this.address = address;
}
//getter and setter
}
DTOBuilder.java
public class DTOBuilder() {
public static PersonDTO buildPersonDTO(PersonEntity person) {
return new PersonDTO(person.getId(). person.getAddress());
}
}
java <——可能需要
public class EntityBuilder() {
public static PersonEntity buildPersonEntity(PersonDTO person) {
return new PersonEntity(person.getId(). person.getAddress());
}
}
在这种情况下,使用“数据库视图”这样的实体也就是不可变实体是非常容易的。
正常的实体
@Entity
@Table(name = "people")
data class Person(
@Id
val id: Long = -1,
val firstName: String = "",
val lastName: String? = null
)
视图类实体
@Entity
@Immutable
@Subselect("""
select
p.id,
concat(p.first_name, ' ', p.last_name) as full_name
from people p
""")
data class PersonMin(
@Id
val id: Long,
val fullName: String,
)
在任何存储库中,我们都可以像这样创建查询函数/方法:
@Query(value = "select p from PersonMin p")
fun findPeopleMinimum(pageable: Pageable): Page<PersonMin>
最简单的方法就是使用投影。它可以将查询结果直接映射到接口,并且比使用SqlResultSetMapping更容易实现。
一个例子如下所示:
@Repository
public interface PeopleRepository extends JpaRepository<People, Long> {
@Query(value = "SELECT p.name AS name, COUNT(dp.people_id) AS count " +
"FROM people p INNER JOIN dream_people dp " +
"ON p.id = dp.people_id " +
"WHERE p.user_id = :userId " +
"GROUP BY dp.people_id " +
"ORDER BY p.name", nativeQuery = true)
List<PeopleDTO> findByPeopleAndCountByUserId(@Param("userId") Long userId);
@Query(value = "SELECT p.name AS name, COUNT(dp.people_id) AS count " +
"FROM people p INNER JOIN dream_people dp " +
"ON p.id = dp.people_id " +
"WHERE p.user_id = :userId " +
"GROUP BY dp.people_id " +
"ORDER BY p.name", nativeQuery = true)
Page<PeopleDTO> findByPeopleAndCountByUserId(@Param("userId") Long userId, Pageable pageable);
}
// Interface to which result is projected
public interface PeopleDTO {
String getName();
Long getCount();
}
投影接口中的字段必须与该实体中的字段匹配。否则字段映射可能会中断。
同样,如果你使用SELECT表。列表示法总是定义与实体名称匹配的别名,如示例所示。