我在我的项目中使用Spring Boot(1.3.3.RELEASE)和Hibernate JPA。我的实体看起来像这样:
@Data
@NoArgsConstructor
@Entity
@Table(name = "rule")
public class RuleVO {
@Id
@GeneratedValue
private Long id;
@Column(name = "name", length = 128, nullable = false, unique = true)
private String name;
@Column(name = "tag", length = 256)
private String tag;
@OneToMany(mappedBy = "rule", cascade = CascadeType.ALL, orphanRemoval = true)
private List<RuleOutputArticleVO> outputArticles;
@OneToMany(mappedBy = "rule", cascade = CascadeType.ALL, orphanRemoval = true)
private List<RuleInputArticleVO> inputArticles;
}
我的存储库看起来像这样:
@Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {
}
在某些情况下,我只需要获取实体RuleVO的 id 和 name 属性。我怎样才能做到这一点?我发现使用Criteria API和Projections应该可行,但是如何?提前谢谢了。 Vojtech
答案 0 :(得分:12)
<强>更新强>
正如我所指出的那样,我很懒,而且这很可能已经完成,因此我在浏览网页后正在更新我的答案。
以下是如何仅 id和 名称的示例:
@Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {
@Query("SELECT r.id FROM RuleVo r where r.name = :name")
List<Long> findIdByName(@Param("name") String name);
@Query("SELECT r.name FROM RuleVo r where r.id = :id")
String findNameById(@Param("id") Long id);
}
希望此更新证明有用
旧答案:
仅检索特定属性name / id是不可能的,因为这不是spring的设计方式或任何SQL数据库,因为你总是选择一个实体的行。
您可以做的是查询实体中的变量,例如:
@Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {
public RuleVo findOneByName(String name);
public RuleVo findOneByNameOrId(String name, Long id);
public List<RuleVo> findAllByName(String name);
// etc, depending on what you want
}
您可以根据需要修改这些w.r.t.您的需求。您可以直接通过自动装配的存储库调用这些方法
有关更多选项和示例,请参阅http://docs.spring.io/spring-data/jpa/docs/current/reference/html/第5.3节
答案 1 :(得分:3)
是的,您可以通过预测来实现它。您有很多方法可以应用它们:
如果您可以升级到Spring Data Hopper,它可以为投影提供易于使用的支持。了解如何在reference documentation中使用它们。
否则,首先要创建一个包含要加载的属性的DTO,如:
package org.example;
public class RuleProjection {
private final Long id;
private final String name;
public RuleProjection(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
}
当然,您也可以使用Lombok注释。
然后,您可以在JPQL查询中使用如下:
select new org.example.RuleProjection(rule.id, rule.name) from RuleVO rule order by rule.name
如果要避免在查询中使用DTO类名,另一个选项是使用QueryDSL实现自己的查询方法。使用Spring Data JPA,您必须:
使用新方法创建新界面。例如:
public interface RuleRepositoryCustom {
public List<RuleProjection> findAllWithProjection();
}
更改存储库以扩展新界面。例如:
public interface RuleRepository extends JpaRepository<RuleVO, Long>, RuleRepositoryCustom {
...
使用Spring Data JPA QueryDSL支持创建Custom存储库的实现。您必须先使用其Maven插件生成QueryDSL的Q版。例如:
public class RuleRepositoryImpl {
public List<RuleProjection> findAllWithProjection() {
QRuleVO rule = QRuleVO.ruleVO;
JPQLQuery query = getQueryFrom(rule);
query.orderBy(rule.name.asc());
return query.list(ConstructorExpression.create(RuleProjection.class, rule.id, rule.name));
}
}
答案 2 :(得分:2)
答案 3 :(得分:2)
您还可以使用JPQL定义自定义构造函数以获取特定列。
示例:
将{javaPackagePath}替换为该类的完整java包路径 在JPQL中用作构造函数。
public class RuleVO {
public RuleVO(Long id, String name) {
this.id = id;
this.name = name;
}
}
@Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {
@Query("SELECT new {javaPackagePath}.RuleVO(r.id, r.name) FROM RuleVo r where r.name = :name")
List<RuleVO> findIdByName(@Param("name") String name);
}
答案 4 :(得分:1)
interface IdOnly{
String getId();
}
@Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {
public List<IdOnly> findAllByName(String name);
}
我注意到这是一篇非常古老的文章,但是如果有人仍在寻找答案,请尝试一下。它对我有用。