Spring 启动,执行自定义查询
Spring boot, execute custom query
我是网络开发的新手,我做了一些例子,比如从 mysql 数据库获取数据并在 jsp 页面中显示它们。(使用 CRUDRepository )
但是这样我们只能显示一个 table 数据。
如果我们想显示合并两个 table 数据,我们应该怎么做。
我在搜索时发现了这些,只是想问一下我们如何对此进行更复杂的 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);
}
如果我们可以在此处放置复杂的查询(例如三个 table 或更多),
我们应该根据查询列创建一个新实体 class 吗??
然后又是那个工作,因为实际上没有任何 table 那样。
要从数据库中获取更复杂的数据,您可以使用 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
table.
的数据
(注意在查询中使用 distinct
以防止结果出现重复记录,更多信息请参阅 。)
有用的资源:
Spring Data JPA - Reference Documentation
我是网络开发的新手,我做了一些例子,比如从 mysql 数据库获取数据并在 jsp 页面中显示它们。(使用 CRUDRepository ) 但是这样我们只能显示一个 table 数据。 如果我们想显示合并两个 table 数据,我们应该怎么做。
我在搜索时发现了这些,只是想问一下我们如何对此进行更复杂的 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);
}
如果我们可以在此处放置复杂的查询(例如三个 table 或更多), 我们应该根据查询列创建一个新实体 class 吗?? 然后又是那个工作,因为实际上没有任何 table 那样。
要从数据库中获取更复杂的数据,您可以使用 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
table.
(注意在查询中使用 distinct
以防止结果出现重复记录,更多信息请参阅
有用的资源:
Spring Data JPA - Reference Documentation