【问题标题】:CrudRepositry Using @Query to Check if Collection Contains an itemCrudRepositry 使用 @Query 检查集合是否包含项目
【发布时间】:2019-01-28 04:39:36
【问题描述】:

我不知道如何检查我的User 在我的数据库中是否有某个Role。具体来说,我想运行一个计数查询 - 并且希望避免在数据库之外进行处理。

我们的代码库使用org.springframework.data.repository.CrudRepository - 因此我们使用@Query 来指定复杂的查询。 (org.springframework.data.jpa.repository.Query)

这个 SQL 查询返回我想要的:

SELECT Count(*) 
FROM user 
where id in (
    select user_id 
    from user_role 
    where role_type = 'ROLE_USER'
);

但我无法获得 @Query 来返回我想要的内容。

这里有一些代码:

User类:

@Entity
@ApiModel(description = "Represents an user of the system")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "ID")
    @ApiModelProperty(value = "The ID of the user", required = true)
    private Long id;

    @Column(name = "USERNAME", unique = true)
    @ApiModelProperty(value = "The userName of the user", required = true)
    private String username;

    @Column(name = "STATUS", nullable=false)
    @Enumerated(EnumType.STRING)
    @ApiModelProperty(value = "The status of the user", required = true)
    private UserStatus status;

    @Column(name = "PASSWORD")
    @ApiModelProperty(value = "The encrypted password of the user")
    private String password;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "USER_ID", nullable=false)
    @ApiModelProperty(value = "The role of the user", required = true)
    private Set<UserRole> userRoles;
}

UserRole班级:

@Entity
public class UserRole implements Serializable {

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "ROLE_TYPE")
    @Enumerated(EnumType.STRING)
    private UserRoleType roleType;

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "USER_ID", nullable=false, insertable=false, updatable=false)
    @ApiModelProperty(value = "The id the user (link to User table)", required = true)
    private User user;
}

以及存储库类:

//这个位不起作用 - 但在这里表明我想做的事情的意图!

public interface UserDao extends CrudRepository<User, Long> {    

    @Query("select count(u) from User u where u.status='ACTIVE' and u.userRoles contains 'ROLE_USER')
    public long countAllActiveUser();


}

数据库非常简单,包含User 表和User_Role 表。

User 表有 IdUsernamePasswordStatus 列。

例如

  • 1,戴夫,****,活跃
  • 2,约翰,****,活跃

User_Role 表有 IdRole_TypeUser_Id 列。

例如

  • 1,ROLE_USER,1
  • 2, ROLE_ADMIN, 1
  • 3,ROLE_USER,2

在上面的例子中 - 计数 SQL 的答案是 2! (有2个用户是ACTIVE,角色为:ROLE_USER

【问题讨论】:

  • 所以您的User_Role 表中有重复条目?
  • 您是否考虑过将用户角色设为枚举?
  • @chrylis :没有重复 - 只是多个角色! (我纠正了错误!)
  • @PinkieSwirl - 用户角色类型是枚举。这个结构在我来之前就已经实现了!
  • 好的,现在您编辑了您的问题以提供不同的数据,正确答案是 2。(如果您想说“2 是正确答案,但这不是我得到的",那么您需要更具体地了解正在发生的事情。)

标签: java spring spring-data-jpa repository jpql


【解决方案1】:

您可以通过存储库界面中的一个简单函数来解决这个问题:

long countByStatusAndUserRoles_roleType(status: UserStatus, roleType: UserRoleType)

这个查询应该做同样的事情:

@Query("select count(u) from User u left join u.userRoles ur where u.status = :status and ur.roleType = :roleType")
long countAllActiveUser(status: UserStatus, roleType: UserRoleType);

您当然可以硬编码 statusroleType

所以你首先需要加入实体(表)。我选择了左连接,因为您需要来自两个实体的项目,请参阅here 以获取有关连接类型的更详细答案。如果通过上下文给出,JPA 连接将自动加入正确的键,否则会出错。

然后你可以像往常一样指定条件。

【讨论】:

  • 嗨 Pinkie Swirl:谢谢你 - 这将解决问题 - 但我需要将其扩展到多个不同的查询,以检查该表(以及另一个“userProfile”表)上的不同参数。 ..其中一些可能不容易用这种函数写出来。 (例如,字段是 null 还是空字符串)是否有可以使用 @Query 代替的解决方案?
  • 我没有使用@Query 方法,所以很抱歉帮不上忙。
  • 不用担心 - 不过我会 +1 你的回复 - 因为它会为试图对我做类似事情的人派上用场 :) [PS 原来我不够了解 +1你公开!]
  • 你用@Query(nativeQuery=true)试试你的说法了吗?
  • 是的 - 我不得不求助于我在实体中没有明确映射的地方......但我确信我应该能够使用角色来管理它,因为我有附在实体上的细节!!
猜你喜欢
  • 1970-01-01
  • 2017-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-30
  • 1970-01-01
  • 2013-04-20
相关资源
最近更新 更多