具有“完整实体”类:
@Entity(name = "vacancy_dec_to_words")
public class VacancyDescriptionToWords {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@JoinColumn(name = "vacancy_description_id")
@ManyToOne(cascade = CascadeType.ALL)
private VacancyDescription vacancyDescription;
@JoinColumn(name = "words_id")
@ManyToOne
private Words words;
@Column(name = "qty")
private int qty;
@Column(name = "create_date")
private Date date;
//...getters and setters
在某些方法中,我只需要使用此数据库中的两列:word_id
和qty
我尝试以下方法:
投影 https://docs.spring.io/spring-data/jpa/docs/2.1.2.RELEASE/reference/html/#projections
public interface QtyWords {
Long getWords();
Integer getQty();
}
Jpa存储库:
*查询,我使用了经过测试且可行的查询,我在JpaRepository
中使用了他:
@Repository
public interface SmallVDTWRepository extends JpaRepository<VacancyDescriptionToWords, Long> {
@Query(nativeQuery = true,
value = "SELECT sum(qty), words_id FROM vacancy_desc_to_words WHERE vacancy_description_id IN (" +
"SELECT id FROM vacancy_description WHERE vacancy_id IN (" +
"SELECT id FROM vacancy WHERE explorer_id = :exp))" +
"GROUP BY words_id")
List<QtyWords> getDistinctWordsByExplorer(@Param("exp") long exp);
}
但是当我获得实体列表时,我得到一些有趣的结果:
List<QtyWords> list = vdtwService.getByExplorerId(72);
我没有任何例外,但是我有一个清单,都是未知对象。该对象包含我需要的数据(qty
和words_id
),但是我无法从他那里获取数据。
我可以使用此方法(Projection
)来完成此任务,并且在这种情况下,通常如何正确地实现“轻型实体”?
答案 0 :(得分:3)
Spring提供了两种机制,可用于限制要获取的数据。
通过设置要确切获取的属性,投影可以帮助您减少从数据库检索的数据。
@Entity
class Person {
@Id UUID id;
String firstname, lastname;
@OneToOne
Address address;
}
@Entity
static class Address {
@Id UUID id;
String zipCode, city, street;
}
interface NamesOnly {
String getFirstname();
String getLastname();
}
@Repository
interface PersonRepository extends Repository<Person, UUID> {
Collection<NamesOnly> findByLastname(String lastname);
}
注释EntityGraph
通过设置需要获取的确切相关实体,可以帮助您减少对数据库的查询量。
@Entity
@NamedEntityGraph(name = "GroupInfo.detail", attributeNodes = @NamedAttributeNode("members"))
public class GroupInfo {
@Id UUID id;
@ManyToMany //default fetch mode is lazy.
List<GroupMember> members = new ArrayList<GroupMember>();
}
@Repository
public interface GroupRepository extends CrudRepository<GroupInfo, String> {
@EntityGraph(value = "GroupInfo.detail", type = EntityGraphType.LOAD)
GroupInfo getByGroupName(String name); //Despite of GroupInfo.members has FetchType = LAZY, it will be fetched because of using EntityGraph
}
EntityGraph
有两种类型:
EntityGraphType.LOAD
-用于指定实体图,由实体图的属性节点指定的属性视为FetchType.EAGER
,未指定的属性根据其指定或默认值处理FetchType
。 EntityGraphType.FETCH
-用于指定实体图,将由实体图的属性节点指定的属性视为FetchType.EAGER
,将未指定的属性视为FetchType.LAZY
。 PS:另外请记住,您可以设置延迟获取类型:@ManyToOne(fetch = FetchType.LAZY)
,并且在获取父对象时JPA不会获取子实体。