使用什么而不是获取.渴望春季数据?



我正在使用 spring-boot 和 angular5,我在 spring 中有这个实体:

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Contrat implements Serializable{
@Id @GeneratedValue
private Long id;
private Date dateDebut ;
private Date dateFin ;
@ManyToOne
@JoinColumn(name = "Id_Project")
@JsonBackReference(value="projet-contrat")
private Project project;
@ManyToOne
@JoinColumn(name = "Id_AppUser")
@JsonBackReference(value="appuser-contrat")
private AppUser appUser;
}

存储库 :

public interface ContratRepo extends JpaRepository<Contrat,Long> {
public Page<Contrat> findByAppUser(@Param("userApp") AppUser userApp, Pageable pageable);
}

由于 fetch.lazy 是默认的,当我尝试调用方法 findByAppUser 时,我得到的结果是:

{id: 1, dateDebut: 1526083200000, dateFin: 1526083200000} 

这很正常,我想要的情况是加载实体中存在的对象"项目",但我不想使用提取。渴望,这个目标有什么解决方案吗?

您的实体是一对多关系对象。如果不使用 EAGER,则 spring 数据将获取没有相关成员对象的对象。如果你通过contract.getProject().getName()得到它,那么将发送另一个查询来获取该成员。

如果您记录 SQL,您可以看到,将有 2 个查询。但是,如果将字段设置为 EAGER,则只有 1 个查询。你显然可以得到改进。

但是你不应该总是使用EAGER 。如果在 90% 的时间内,您只需要 Contract 对象,而不需要它的项目数据。得到它是浪费时间。因为在 SQL 中,它将关联 2 个表并获取所有数据列。

因此,您应该根据您对此实体的使用情况做出此决定。

[根据评论更新]

您可以使用Query来编写 sql 表达式。 例如,我有一个方法来获取包含详细信息的实体:

@Query("select s from Contract s left join fetch s.project pr where s.id = ?1 ")
Contract findOneWithDetail(Long id);

如果我需要在 ONE sql 中获取详细信息,我可以使用此方法。如果我不需要项目细节,我只需使用提供的接口findOne(Long id)

而且,如果你只想获取一些列,你需要用一个构造函数定义一个 DTO,并像这样编写你的方法:

@Query("SELECT NEW com.mypackage.dto.ContractDTO(s.id, s.name, s.status)  FROM Contract AS s WHERE s.status = ?1")
List<ContractDTO> findDTOAllByStatus(String status);

在你的 repo 方法中提供查询,例如(语法可能是错误的,只是告诉你的想法(

public interface ContratRepo extends JpaRepository<Contrat,Long> {
@Query(query="from Contrat c left join fetch c.project " +
"where c.userApp = :userApp")
public Page<Contrat> findByAppUser(@Param("userApp") AppUser userApp, Pageable pageable);
}

最新更新