春季启动,执行自定义查询

时间:2018-08-05 07:04:50

标签: mysql spring spring-boot spring-data-jpa entity

我是Web开发的新手,我做了一些示例,例如从mysql db获取数据并将其显示在jsp页面中。(使用CRUDRepository) 但是这样一来,我们只能显示一个表数据。 如果要显示合并两个表数据该怎么办。

我在进行um搜索时发现了这些,简直是在问我们如何对此进行更复杂的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);
}

如果我们可以在此处放置该复杂的查询(例如三个表或更多表), 我们应该根据查询列创建一个新的实体类吗? 再来就是这项工作,因为实际上没有这样的表。

1 个答案:

答案 0 :(得分:0)

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

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可以防止结果重复记录,更多信息请参见here。)


有用的资源

Spring Data JPA - Reference Documentation

SpEL support in Spring Data JPA @Query definitions

Hibernate ORM User Guide

JPQL Language Reference