Spring boot,执行自定义查询

问题描述 投票:0回答:1

我是 Web 开发的新手,我做了一些示例,例如从 MySQL 数据库获取数据并将它们显示在 jsp 页面中(使用 CRUDRepository), 但这样我们只能显示一个表数据。

如果我们想显示两个表合并的数据该怎么办?

我在搜索时发现了这些,我只是想问我们如何对此进行更复杂的 SQL 查询。

public interface UserRepository extends JpaRepository<User, Long> {

  @Query("select u from User u where u.lastname like ?1%")
  List<User> findByAndSort(String lastname, Sort sort);

  @Query("select u.id, LENGTH(u.firstname) as fn_len from User u where u.lastname like ?1%")
  List<Object[]> findByAsArrayAndSort(String lastname, Sort sort);
}

如果我们可以在这里使用复杂的查询(例如三个表或更多), 我们是否应该根据查询列创建一个新的实体类?

话又说回来,这行得通吗,因为实际上没有这样的桌子。

mysql spring spring-boot spring-data-jpa entity
1个回答
0
投票

要从数据库获取更复杂的数据,您可以使用投影,例如:

public interface UserProjection {
    Long getId();
    Long getFirstNameLen();
}

@Query("select u.id as id, LENGTH(u.firstName) as firstNameLen from User u where u.lastname like ?1%")
List<UserProjection> getProjections(String lastName, Sort sort);

请注意,您应该在查询中使用必须与投影中的 getter 匹配的别名 (

... as firstNameLen
->
getFirstNameLen()
)

您可以通过相同的方式从多个(连接的)实体获取数据。

如果您有一个具有某些关联的实体,例如:

@Entity
public class User {
    //...
    @OneToMany
    private List<Role> roles;
}

然后您可以使用存储库方法来获取用户及其角色数据,即使没有任何投影,仅针对主要实体(

User
)。然后 Spring 自己完成剩下的工作:

@EntityGraph(attributePaths = "roles")
List<User> findByFirstNameContainingIgnoreCase(String firstName);

或与查询相同:

@Query("select distinct u from User u left join fetch u.roles where upper(p.firstName) like concat('%', upper(?1), '%')")
List<User> findWithQuery(String firstName);

在这种情况下,所有用户的角色列表都将填充

roles
表中的数据。

(注意在查询中使用

distinct
,防止结果出现重复记录,更多信息参见这里。)


有用的资源:

Spring Data JPA - 参考文档

Spring Data JPA @Query 定义中的 SpEL 支持

Hibernate ORM 用户指南

JPQL 语言参考

© www.soinside.com 2019 - 2024. All rights reserved.