web-dev-qa-db-ja.com

Spring JPAを使用してエンティティの選択された属性のみを取得する方法は?

私は自分のプロジェクトで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を使用して実行できるはずの通知を見つけましたが、どのようにですか?事前に感謝します。ヴォイテック

13
Vojtech

UPDATE:

私に指摘されたように、私は怠け者であり、これは非常にうまくやることができるので、適切なものを探してウェブを見てから答えを更新しています。

次に、IDのonlyと名前のonlyを取得する方法の例を示します。

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

このアップデートが役立つことを願っています


古い回答:

特定の属性の名前/ IDのみを取得することはできません。これは、エンティティである行を常に選択するため、スプリングの設計方法や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

12

はい、プロジェクションでそれを達成できます。それらを適用する多くの方法があります:

Spring Data Hopperにアップグレードできれば、プロジェクションの使いやすいサポートが提供されます。 リファレンスドキュメント でそれらの使用方法を参照してください。

それ以外の場合は、まず、ロードする属性を持つ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サポートを使用して、カスタムリポジトリの実装を作成します。 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));
        }
    }
    
4
Cèsar

また、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);
}
2
Abhilekh Singh
interface IdOnly{
    String getId();
}

@Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {
    public List<IdOnly> findAllByName(String name);
}

これは非常に古い投稿であることに気づきましたが、誰かがまだ答えを探しているなら、これを試してください。それは私のために働いた。

2
Pranjal Gore

@Queryアノテーション(HQL)を使用して実行できます。

以下のSpringドキュメントを参照してください。

http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query

(春のドキュメントで@Queryを検索)

2
shankarsh15