我有两个实体,简化了这个案子。isActive字段随当前时间而变化,因此我不想将其存储在db中。
等活性的条件:
isActive =1 if (current_timestamp介于userstatus.datebegin和userstatus.dateend之间)userstatus.dateend=0
我想要的:
我想要获得一组所有用户的,他们的isActive值设置为,而不访问每个用户的db ,最好是;没有userStatus的集合带在周围。是否有一种通过编程或jpa方式来满足这一需求的方法?或者说,实现这一目标的最佳方式是什么?
User.java:
@Entity
public class User {
@Id
private long id;
@Transient
private int isActive;
@OneToMany(mappedBy = "user",fetch = FetchType.LAZY)
private Set<UserStatus> userStatus = new HashSet<>();
}
UserStatus.java:
public class UserStatus {
@Id
private long id;
@Column
private Date dateBegin;
@Column
private Date dateEnd;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name= "user_tr_id_no")
private UmutUser user;
}
UserRepository.java:
@Repository
public interface UserRepository extends JpaRepository<User, long> {
Set<User> findAllFetchWithIsActive();
}
我尝试过的方式:
*Way1: PostLoad问题:如果我不获取userStatus,它会针对每个用户对象访问db。
*Way2: JPQL查询:问题:除了这里建议的in之外,找不到设置瞬态值的查询。问题是,它再次访问每个用户对象的db。
*Way3 3:急切地获取userStatus,计算服务中的isActive值,在传递之前隐藏DTO中的用户状态集。问题:这是我的最后一招,我怀疑为所有用户获取userStatus集是一种很好的方法。
发布于 2017-02-21 13:13:23
我认为最好的办法是这样做:
@Query("SELECT e FROM User u WHERE u.userStatus.dateBegin < CURRENT_DATE AND u.userStatus.dateEnd > CURRENT_DATE")
Iterable<User> findAllActiveUsers();
在您的用户类中
@Entity
public class User {
@Id
private long id;
@OneToMany(mappedBy = "user",fetch = FetchType.LAZY)
private Set<UserStatus> userStatus = new HashSet<>();
@Transient
public int isActive(){
for(UserStatus status: userStatus) {
//Add your logic to check if the current date is between the range
}
}
}
发布于 2017-02-21 14:26:17
您可能需要使用new
操作符:
select new UserWithStatus(
u,
u.userStatus.dateBegin < CURRENT_DATE AND u.userStatus.dateEnd > CURRENT_DATE)
from User u
并让你的对象UserWithStatus
public class UserWithStatus {
private User user;
private boolean active;
public UserWithStatus(User user, boolean active) {
this.user = user;
this.active = active;
}
}
并将其保存在存储库中:
@Query("...")
Set<UserWithStatus> findAllFetchWithIsActive();
注意:,我认为这会给您带来重复(例如:一个具有多个状态的用户)。您可能需要使用子查询,我不知道JPQL是否允许这样做:
select new UserWithStatus(u,
(select count(*)
from u.userStatus w
where w.dateBegin < CURRENT_DATE
and w.dateEnd > CURRENT_DATE)) > 0
from User u
https://stackoverflow.com/questions/42361726
复制相似问题