有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring Data JPA+Hibernate是一种设置瞬态字段的方法,无需为每个实体点击db,也无需加载一个域集合

我有两个实体,简化了。isActive字段随当前时间变化,所以我不想将其存储在db中

激活状态:

isActive=1如果(userstatus.datebegin和userstatus.dateend之间的当前时间戳)否则isActive=0

我想要的:

我想获得一组所有用户,设置他们的isActive值,而不对每个用户点击db没有用户状态收集。有没有一种方法可以通过编程或jpa的方式来满足这种需求?或者,实现这一目标的最佳方式是什么

用户。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<>();


}

用户状态。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;


}

用户存储库。java:

@Repository
public interface UserRepository extends JpaRepository<User, long> {

  Set<User> findAllFetchWithIsActive();
}

我尝试的方式:

*方式1:后装载 问题:如果我不获取userStatus,它会命中每个用户对象的数据库

*Way2:JPQL查询: 问题:除了此处建议的in之外,找不到设置瞬时值的查询。问题是它会再次影响每个用户对象的数据库

*方法3:急切地获取userStatus,计算服务中的isActive值,在传递之前在DTO中隐藏userStatus集。 问题:这是我最后的手段,我怀疑为所有用户设置userStatus是否是一个好方法


共 (2) 个答案

  1. # 1 楼答案

    您可能需要使用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
    
  2. # 2 楼答案

    我认为最好的方法是这样的:

    @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
          }
      }
    
    }