是否可以统一由 findby spring 数据生成的查询
Is It possible to unify queries generated by findby spring data
我有一个这样的实体 Class:
@Entity
@Table(name="app_user_role")
public class AppUserRole implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private AppUserRolePK id;
//uni-directional many-to-one association to App
@ManyToOne
@JoinColumn(name="id_app", insertable=false, updatable=false)
private App app;
//uni-directional many-to-one association to Role
@ManyToOne
@JoinColumn(name="id_role", insertable=false, updatable=false)
private Role role;
//uni-directional many-to-one association to User
@ManyToOne
@JoinColumn(name="id_user", insertable=false, updatable=false)
private User user;
}
然后,调用下一个方法:
List<AppUserRole> appUserRoles= appUserRoleRepository.findByAppAndUser(app, user);
然后,它生成下一个查询:
Hibernate: select appuserrol0_.id_app as id_app1_2_, appuserrol0_.id_role as id_role2_2_, appuserrol0_.id_user as id_user3_2_, appuserrol0_.state as state4_2_ from security.app_user_role appuserrol0_ left outer join security.app app1_ on appuserrol0_.id_app=app1_.id left outer join security.user user2_ on appuserrol0_.id_user=user2_.id where app1_.id=? and user2_.id=?
Hibernate: select app0_.id as id1_0_0_, app0_.app as app2_0_0_, app0_.descr as descr3_0_0_ from security.app app0_ where app0_.id=?
Hibernate: select role0_.id as id1_4_0_, role0_.id_app as id_app3_4_0_, role0_.role as role2_4_0_, app1_.id as id1_0_1_, app1_.app as app2_0_1_, app1_.descr as descr3_0_1_ from security.role role0_ left outer join security.app app1_ on role0_.id_app=app1_.id where role0_.id=?
Hibernate: select user0_.id as id1_5_0_, user0_.mail as mail2_5_0_, user0_.password as password3_5_0_, user0_.username as username4_5_0_ from security.user user0_ where user0_.id=?
它生成了多个分开的查询,
如何将这些查询统一到一个查询中?
考虑下一个方法只生成了一个查询:
AppUserRolePK appUserRolePK = new AppUserRolePK(app.getId(), role.getId(), user.getId() );
AppUserRole appUserRole1 = appUserRoleRepository.findOne(appUserRolePK);
生成的查询:
Hibernate: select appuserrol0_.id_app as id_app1_2_0_, appuserrol0_.id_role as id_role2_2_0_, appuserrol0_.id_user as id_user3_2_0_, appuserrol0_.state as state4_2_0_, app1_.id as id1_0_1_, app1_.app as app2_0_1_, app1_.descr as descr3_0_1_, role2_.id as id1_4_2_, role2_.id_app as id_app3_4_2_, role2_.role as role2_4_2_, app3_.id as id1_0_3_, app3_.app as app2_0_3_, app3_.descr as descr3_0_3_, user4_.id as id1_5_4_, user4_.mail as mail2_5_4_, user4_.password as password3_5_4_, user4_.username as username4_5_4_ from security.app_user_role appuserrol0_ left outer join security.app app1_ on appuserrol0_.id_app=app1_.id left outer join security.role role2_ on appuserrol0_.id_role=role2_.id left outer join security.app app3_ on role2_.id_app=app3_.id left outer join security.user user4_ on appuserrol0_.id_user=user4_.id where appuserrol0_.id_app=? and appuserrol0_.id_role=? and appuserrol0_.id_user=?
提前致谢
这是映射对象时的常规行为(预先加载,@ManyToOne
的默认值是多少)。
您的示例中的第一个查询会收到映射对象的标识符:
appuserrol0_.id_app as id_app1_2_, appuserrol0_.id_role as id_role2_2_, appuserrol0_.id_user as id_user3_2_,
以下查询正在获取每个对象本身及其值(需要满足映射获取策略),如果它们在当前持久性上下文中尚不可用。如果它们已经存在于(第一级)缓存中,则不需要额外的选择。
如果您想覆盖此行为,请自行编写 HQL,您也可以使用 @Query
注释在 Spring Data JPA 存储库上执行此操作:
@Query("FROM AppUserRole aur JOIN FETCH aur.app a JOIN FETCH aur.user u JOIN FETCH aur.role r WHERE a =:app AND u =:user")
Set<AppUserRole> findByAppAndUser(@Param("app") App app, @Param("user") User user);
请记住,当您将此查询与 JOIN FETCH
语句一起使用时,您将失去延迟加载方法的所有优势。
我有一个这样的实体 Class:
@Entity
@Table(name="app_user_role")
public class AppUserRole implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private AppUserRolePK id;
//uni-directional many-to-one association to App
@ManyToOne
@JoinColumn(name="id_app", insertable=false, updatable=false)
private App app;
//uni-directional many-to-one association to Role
@ManyToOne
@JoinColumn(name="id_role", insertable=false, updatable=false)
private Role role;
//uni-directional many-to-one association to User
@ManyToOne
@JoinColumn(name="id_user", insertable=false, updatable=false)
private User user;
}
然后,调用下一个方法:
List<AppUserRole> appUserRoles= appUserRoleRepository.findByAppAndUser(app, user);
然后,它生成下一个查询:
Hibernate: select appuserrol0_.id_app as id_app1_2_, appuserrol0_.id_role as id_role2_2_, appuserrol0_.id_user as id_user3_2_, appuserrol0_.state as state4_2_ from security.app_user_role appuserrol0_ left outer join security.app app1_ on appuserrol0_.id_app=app1_.id left outer join security.user user2_ on appuserrol0_.id_user=user2_.id where app1_.id=? and user2_.id=?
Hibernate: select app0_.id as id1_0_0_, app0_.app as app2_0_0_, app0_.descr as descr3_0_0_ from security.app app0_ where app0_.id=?
Hibernate: select role0_.id as id1_4_0_, role0_.id_app as id_app3_4_0_, role0_.role as role2_4_0_, app1_.id as id1_0_1_, app1_.app as app2_0_1_, app1_.descr as descr3_0_1_ from security.role role0_ left outer join security.app app1_ on role0_.id_app=app1_.id where role0_.id=?
Hibernate: select user0_.id as id1_5_0_, user0_.mail as mail2_5_0_, user0_.password as password3_5_0_, user0_.username as username4_5_0_ from security.user user0_ where user0_.id=?
它生成了多个分开的查询, 如何将这些查询统一到一个查询中?
考虑下一个方法只生成了一个查询:
AppUserRolePK appUserRolePK = new AppUserRolePK(app.getId(), role.getId(), user.getId() );
AppUserRole appUserRole1 = appUserRoleRepository.findOne(appUserRolePK);
生成的查询:
Hibernate: select appuserrol0_.id_app as id_app1_2_0_, appuserrol0_.id_role as id_role2_2_0_, appuserrol0_.id_user as id_user3_2_0_, appuserrol0_.state as state4_2_0_, app1_.id as id1_0_1_, app1_.app as app2_0_1_, app1_.descr as descr3_0_1_, role2_.id as id1_4_2_, role2_.id_app as id_app3_4_2_, role2_.role as role2_4_2_, app3_.id as id1_0_3_, app3_.app as app2_0_3_, app3_.descr as descr3_0_3_, user4_.id as id1_5_4_, user4_.mail as mail2_5_4_, user4_.password as password3_5_4_, user4_.username as username4_5_4_ from security.app_user_role appuserrol0_ left outer join security.app app1_ on appuserrol0_.id_app=app1_.id left outer join security.role role2_ on appuserrol0_.id_role=role2_.id left outer join security.app app3_ on role2_.id_app=app3_.id left outer join security.user user4_ on appuserrol0_.id_user=user4_.id where appuserrol0_.id_app=? and appuserrol0_.id_role=? and appuserrol0_.id_user=?
提前致谢
这是映射对象时的常规行为(预先加载,@ManyToOne
的默认值是多少)。
您的示例中的第一个查询会收到映射对象的标识符:
appuserrol0_.id_app as id_app1_2_, appuserrol0_.id_role as id_role2_2_, appuserrol0_.id_user as id_user3_2_,
以下查询正在获取每个对象本身及其值(需要满足映射获取策略),如果它们在当前持久性上下文中尚不可用。如果它们已经存在于(第一级)缓存中,则不需要额外的选择。
如果您想覆盖此行为,请自行编写 HQL,您也可以使用 @Query
注释在 Spring Data JPA 存储库上执行此操作:
@Query("FROM AppUserRole aur JOIN FETCH aur.app a JOIN FETCH aur.user u JOIN FETCH aur.role r WHERE a =:app AND u =:user")
Set<AppUserRole> findByAppAndUser(@Param("app") App app, @Param("user") User user);
请记住,当您将此查询与 JOIN FETCH
语句一起使用时,您将失去延迟加载方法的所有优势。