2013-08-18 15 views
20

私は以下のようにエンティティクラスを持っている:春データJPAとQuerydslを使用して春データJPAとQuerydsl

@Entity 
public class UserDemo implements Serializable { 

    @Id 
    private Long id; 

    private String username; 

    private String createdBy; 
    @Version 
    private int version; 

    /*** 
    * 
    * Getters and setters 
    */ 
} 


私はのページの取得はどうすればよいですUserDemoidusernameのプロパティのみが入力されていますか?私はページングと検索の両方を使う必要があります。要するに私は

Page<UserDemo> findAll(Predicate predicate, Pageable pageable); 

が、人口UserDemoの限られた分野と同じ結果を達成したいと思います。

答えて

28

カスタムリポジトリの実装のように見えるのは、今のところ似たようなものがSpringデータで利用可能になるまでです。

私はhttp://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/repositories.html#repositories.custom-implementations

通過したがここで働く私の実装です。しかしながら、スプリング-DATA-JPAで直接利用できるこの方法を有することが良いであろう

ステップ1:共有動作のための中間インターフェース

public interface CustomQueryDslJpaRepository <T, ID extends Serializable> 
     extends JpaRepository<T, ID>, QueryDslPredicateExecutor<T> { 
    /** 
    * Returns a {@link org.springframework.data.domain.Page} of entities matching the given {@link com.mysema.query.types.Predicate}. 
    * This also uses provided projections (can be JavaBean or constructor or anything supported by QueryDSL 
    * @param constructorExpression this constructor expression will be used for transforming query results 
    * @param predicate 
    * @param pageable 
    * @return 
    */ 
    Page<T> findAll(FactoryExpression<T> factoryExpression, Predicate predicate, Pageable pageable); 
} 

ステップ2:中間体インタフェースの実装

public class CustomQueryDslJpaRepositoryImpl<T, ID extends Serializable> extends QueryDslJpaRepository<T, ID> 
     implements CustomQueryDslJpaRepository<T, ID> { 

    //All instance variables are available in super, but they are private 
    private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE; 

    private final EntityPath<T> path; 
    private final PathBuilder<T> builder; 
    private final Querydsl querydsl; 

    public CustomQueryDslJpaRepositoryImpl(JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager) { 
     this(entityInformation, entityManager, DEFAULT_ENTITY_PATH_RESOLVER); 
    } 

    public CustomQueryDslJpaRepositoryImpl(JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager, 
           EntityPathResolver resolver) { 

     super(entityInformation, entityManager); 
     this.path = resolver.createPath(entityInformation.getJavaType()); 
     this.builder = new PathBuilder<T>(path.getType(), path.getMetadata()); 
     this.querydsl = new Querydsl(entityManager, builder); 
    } 

    @Override 
    public Page<T> findAll(FactoryExpression<T> factoryExpression, Predicate predicate, Pageable pageable) { 
     JPQLQuery countQuery = createQuery(predicate); 
     JPQLQuery query = querydsl.applyPagination(pageable, createQuery(predicate)); 

     Long total = countQuery.count(); 
     List<T> content = total > pageable.getOffset() ? query.list(factoryExpression) : Collections.<T> emptyList(); 

     return new PageImpl<T>(content, pageable, total); 
    } 
} 

手順3:既定の設定を置き換えるカスタムリポジトリファクトリを作成する

public class CustomQueryDslJpaRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable> 
     extends JpaRepositoryFactoryBean<R, T, I> { 

    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) { 

     return new CustomQueryDslJpaRepositoryFactory(entityManager); 
    } 
    private static class CustomQueryDslJpaRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory { 

     private EntityManager entityManager; 

     public CustomQueryDslJpaRepositoryFactory(EntityManager entityManager) { 
      super(entityManager); 
      this.entityManager = entityManager; 
     } 

     protected Object getTargetRepository(RepositoryMetadata metadata) { 
      return new CustomQueryDslJpaRepositoryImpl<>(getEntityInformation(metadata.getDomainType()), entityManager); 
     } 

     protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) { 
      return CustomQueryDslJpaRepository.class; 
     } 
    } 
} 

ステップ4:カスタムリポジトリインタフェースを置かないでください:注釈

@EnableJpaRepositories(repositoryFactoryBeanClass=CustomQueryDslJpaRepositoryFactoryBean.class) 

OR XML

<repositories base-package="com.acme.repository" factory-class="com.acme.CustomQueryDslJpaRepositoryFactoryBean" /> 

注意を使用してを使用してカスタムリポジトリ工場

を使用します同じdiの実装ベースパッケージとしての職場。あなたが配置されている場合は、それ以外の場合は春が彼らのために春データの最近のバージョンについては

使用例

public interface UserDemoRepository extends CustomQueryDslJpaRepository<UserDemo, Long>{ 
} 

public class UserDemoService { 
    @Inject 
    UserDemoRepository userDemoRepository; 

    public Page<User> findAll(UserSearchCriteria userSearchCriteria, Pageable pageable) { 
     QUserDemo user = QUserDemo.userDemo; 
     return userDemoRepository.findAll(Projections.bean(UserDemo.class, user.id, user.username), UserPredicate.defaultUserSearch(userSearchCriteria), pageable); 
    } 

} 
+0

FactoryExpressionとはカスタムクラスまたは事前定義されたものです。 –

+0

FactoryExpressionはQuerydslのProjectionsの基本クラスです。 http://www.querydsl.com/static/querydsl/3.2.0/apidocs/com/mysema/query/types/FactoryExpression.html – Murali

+0

「原因:org.springframework.data.mapping.PropertyReferenceException:No」というメッセージが表示されます。これを試したときに型のプロパティが見つかりました。何故ですか? はもちろんエンティティタイプを表します。 –

3

をBeanを作成しようとするスキャンから除外、私は受け入れ答えを得ることができませんでした問題を押すことなく動作しますが、春データドキュメントからのルートを下って行く、次のようにその答えを見直すことで作業を行うことが判明する:

1.リポジトリインタフェース

@NoRepositoryBean 
public interface QueryDslPredicateAndProjectionExecutor<T, ID extends Serializable> 
     extends JpaRepository<T, ID>, QueryDslPredicateExecutor<T> { 

    <PROJ> Page<PROJ> customFindWithProjection(FactoryExpression<PROJ> factoryExpression, Predicate predicate, Pageable pageable); 
} 

2。デフォルトのリポジトリの実装春データの現在のバージョンの

@EnableJpaRepositories(
    repositoryBaseClass=QueryDslJpaEnhancedRepositoryImpl.class, 
    basePackageClasses=SomeRepository.class) 
+0

コードベースはどこかにありますか?PROJは私の投影インターフェイス私はいくつかのコンパイルエラーを取得するpls任意のgithubサイトを共有するか、どこに私が参照することができます... – surya

+0

実際に私が実装した後、DSLの一部の作品は、結果が投影されていないが全体のオブジェクト。あなたがクエリdsl +投影 – surya

+0

のためにどこかのサンプルコードを持っているかどうか私に教えてください。1.4.0.RELEASEスプリングブートバージョン – surya

1

(1.11.1)とを設定するリポジトリの実装

public class QueryDslJpaEnhancedRepositoryImpl<T, ID extends Serializable> extends QueryDslJpaRepository<T, ID> 
     implements QueryDslPredicateAndProjectionExecutor<T, ID> { 

    //All instance variables are available in super, but they are private 
    private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE; 

    private final EntityPath<T> path; 
    private final PathBuilder<T> builder; 
    private final Querydsl querydsl; 

    public QueryDslJpaEnhancedRepositoryImpl(JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager) { 
     this(entityInformation, entityManager, DEFAULT_ENTITY_PATH_RESOLVER); 
    } 

    public QueryDslJpaEnhancedRepositoryImpl(JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager, 
           EntityPathResolver resolver) { 

     super(entityInformation, entityManager, resolver); 
     this.path = resolver.createPath(entityInformation.getJavaType()); 
     this.builder = new PathBuilder<T>(path.getType(), path.getMetadata()); 
     this.querydsl = new Querydsl(entityManager, builder); 
    } 

    @Override 
    public <PROJ> Page<PROJ> customFindWithProjection(FactoryExpression<PROJ> factoryExpression, Predicate predicate, Pageable pageable) { 
     JPQLQuery countQuery = createQuery(predicate); 
     JPQLQuery query = querydsl.applyPagination(pageable, createQuery(predicate)); 

     Long total = countQuery.count(); 
     List<PROJ> content = total > pageable.getOffset() ? query.list(factoryExpression) : Collections.<PROJ>emptyList(); 

     return new PageImpl<PROJ>(content, pageable, total); 
    } 
} 

3. QueryDSL(4)、あなたは変更する必要がcustomFindWithProjectionメソッドの実装は次のようになります。

@Override 
public <PROJ> Page<PROJ> customFindWithProjection(FactoryExpression<PROJ> factoryExpression, Predicate predicate, Pageable pageable) { 

    final JPQLQuery<?> countQuery = createCountQuery(predicate); 
    JPQLQuery<PROJ> query = querydsl.applyPagination(pageable, createQuery(predicate).select(factoryExpression)); 

    long total = countQuery.fetchCount(); 
    List<PROJ> content = pageable == null || total > pageable.getOffset() ? query.fetch() : Collections.<PROJ> emptyList(); 

    return new PageImpl<PROJ>(content, pageable, total); 
} 

残りのコードは同じです。