34

I have an entity class as below:

@Entity
public class UserDemo implements Serializable {

    @Id
    private Long id;

    private String username;

    private String createdBy;
    @Version
    private int version;

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


Using Spring Data JPA and Querydsl how do I fetch a page of UserDemo with only id and username properties populated? I need to use paging as well as searching. In short I would like to achieve the same result as

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

but with limited field of UserDemo populated.

4

7 回答 7

37

看起来自定义存储库实现是现在要走的路,直到在 spring 数据中提供类似的东西。

我已经浏览了http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/repositories.html#repositories.custom-implementations

这是我的有效实现。但是,最好在 Spring-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);
}

第二步:中间接口的实现

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)

或使用 XML

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

注意:不要将自定义存储库接口和实现放在与 base-package 相同的目录中。如果您要放置,则将它们排除在扫描之外,否则 spring 将尝试为它们创建 bean

示例使用

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

}
于 2013-08-19T12:00:44.087 回答
9

对于 Spring Data 的更新版本,我无法在没有遇到问题的情况下获得公认的工作答案,但发现从 Spring Data 文档开始,通过按如下方式修改该答案确实可以工作:

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. 存储库实现

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.设置默认存储库实现

@EnableJpaRepositories(
    repositoryBaseClass=QueryDslJpaEnhancedRepositoryImpl.class,
    basePackageClasses=SomeRepository.class)
于 2016-01-29T14:54:30.820 回答
6

对于 Spring Data (1.11.1) 和 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);
}

其余代码保持不变。

于 2017-03-02T18:33:16.877 回答
2

我自己也遇到了同样的问题。简而言之 - 我们必须指定自定义存储库工厂 bean,它告诉使用我们的自定义存储库作为另一个“片段”。所以我覆盖了 factory.getRepositoryFragments 以包含一个自定义投影谓词实现(恕我直言,它解决了问题No property found for type... custom Spring Data repository中的问题)。

更新的代码,基于所有以前的答案:

1.QuerydslPredicateProjectionRepositoryFactory

import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.querydsl.EntityPathResolver;
import org.springframework.data.querydsl.SimpleEntityPathResolver;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryComposition;
import org.springframework.data.repository.core.support.RepositoryFragment;

import javax.persistence.EntityManager;
import java.io.Serializable;

import static org.springframework.data.querydsl.QuerydslUtils.QUERY_DSL_PRESENT;

public class QuerydslPredicateProjectionRepositoryFactory extends JpaRepositoryFactory {

    private final EntityManager entityManager;
    private EntityPathResolver entityPathResolver;

    public QuerydslPredicateProjectionRepositoryFactory(EntityManager entityManager) {
        super(entityManager);
        this.entityManager = entityManager;
        this.entityPathResolver = SimpleEntityPathResolver.INSTANCE;
    }

    @Override
    protected RepositoryComposition.RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata) {
        RepositoryComposition.RepositoryFragments fragments = super.getRepositoryFragments(metadata);

        boolean isQueryDslRepository = QUERY_DSL_PRESENT
                && QuerydslPredicateProjectionRepository.class.isAssignableFrom(metadata.getRepositoryInterface());

        if (isQueryDslRepository) {

            JpaEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());

            Object querydslFragment = getTargetRepositoryViaReflection(QuerydslPredicateProjectionRepositoryImpl.class, entityInformation,
                    entityManager, entityPathResolver, null);

            fragments = fragments.append(RepositoryFragment.implemented(querydslFragment));
        }

        return fragments;

    }
}

2.QuerydslPredicateProjectionRepositoryFactoryBean

import java.io.Serializable;

import javax.persistence.EntityManager;

import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;

public class QuerydslPredicateProjectionRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends JpaRepositoryFactoryBean<T, S, ID> {
    public QuerydslPredicateProjectionRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
        super(repositoryInterface);
    }

    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
        return new QuerydslPredicateProjectionRepositoryFactory(entityManager);
    }
}

3.QuerydslPredicateProjectionRepository在这里我们添加新方法,使用投影等......

import com.querydsl.core.types.FactoryExpression;
import com.querydsl.core.types.Predicate;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.util.List;

public interface QuerydslPredicateProjectionRepository<T> {
    <Projection> Page<Projection> findAll(Predicate predicate, Pageable pageable, FactoryExpression<Projection> factoryExpression);
    <Projection> List<Projection> findAll(Predicate predicate, Sort sort, FactoryExpression<Projection> factoryExpression);
    <Projection> List<Projection> findAll(Predicate predicate, FactoryExpression<Projection> factoryExpression);
}

4.QuerydslPredicateProjectionRepositoryImpl这里我们实现repository接口方法

import com.querydsl.core.QueryResults;
import com.querydsl.core.types.EntityPath;
import com.querydsl.core.types.FactoryExpression;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.jpa.JPQLQuery;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.support.CrudMethodMetadata;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.Querydsl;
import org.springframework.data.jpa.repository.support.QuerydslJpaPredicateExecutor;
import org.springframework.data.querydsl.EntityPathResolver;
import org.springframework.data.querydsl.SimpleEntityPathResolver;

import javax.persistence.EntityManager;
import java.util.List;

public class QuerydslPredicateProjectionRepositoryImpl<T> extends QuerydslJpaPredicateExecutor<T> implements QuerydslPredicateProjectionRepository<T> {
    private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE;

    private final Querydsl querydsl;


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

    public QuerydslPredicateProjectionRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager, EntityPathResolver resolver) {
        super(entityInformation, entityManager, resolver, null);

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

    public QuerydslPredicateProjectionRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager, EntityPathResolver resolver, CrudMethodMetadata metadata) {
        super(entityInformation, entityManager, resolver, metadata);
        EntityPath<T> path = resolver.createPath(entityInformation.getJavaType());
        PathBuilder<T> builder = new PathBuilder<T>(path.getType(), path.getMetadata());
        this.querydsl = new Querydsl(entityManager, builder);
    }

    @Override
    public <Projection> List<Projection> findAll(Predicate predicate, FactoryExpression<Projection> factoryExpression) {
        return createQuery(predicate).select(factoryExpression).fetch();
    }

    @Override
    public <Projection> List<Projection> findAll(Predicate predicate, Sort sort, FactoryExpression<Projection> factoryExpression) {
        JPQLQuery<Projection> query = createQuery(predicate).select(factoryExpression);
        querydsl.applySorting(sort, query);

        return query.fetch();
    }

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

        QueryResults<Projection> queryResults = query.fetchResults();
        return new PageImpl<>(queryResults.getResults(), pageable, queryResults.getTotal());
    }
}

5.示例实体

@Entity
public class Example extends Serializable{
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;
    @Column
    private String name;
    @Column
    private String surname;
    @Column
    private Integer year;

    public Example() {
    }
    public Long getId() {return id;}
    public void setId(Long id) {this.id = id;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public String getSurname() {return surname;}
    public void setSurname(String surname) {this.surname= surname;}
    public Integer getYear() {return year;}
    public void setSurname(Integer year) {this.year= year;}
}

6.示例存储库

@Repository
public interface ExampleRepository extends JpaRepository<Example, Long>, QuerydslPredicateProjectionRepository<Example> { }

7.示例使用 配置:

@EnableJpaRepositories(repositoryFactoryBeanClass = QuerydslPredicateProjectionRepositoryFactoryBean.class)

典型用法:

//get list of entities only with year field value set - memory consuming
List<Example> years = repository.findAll(predicate, Projections.fields(Example.class, QExample.example.year)); 
//get list of tuples - looks nicer - less memory consuming
List<Tuple> years = repository.findAll(predicate, Projections.tuple(QExample.example.year));
//get list of integers - nice :)
List<Integer> years = repository.findAll(predicate, Projections.constructor(Integer.class, QExample.example.year));
于 2019-03-29T06:44:54.087 回答
2

作为一种(尽管非常丑陋且效率低下)的解决方法,我只是Page从我的存储库中检索了一个包含实体的常规并将它们手动映射到控制器中的投影,如下所示:

@GetMapping(value = "/columns")
public Page<ColumnProjection> getColumns(@QuerydslPredicate(root = Column.class) final Predicate predicate,
                                         final Pageable pageable) {
 Page<Column> filteredColumns = columnRepository.findAll(predicate, pageable);
 List<ColumnProjection> filteredColumnProjections = new ArrayList<>();
 filteredColumns.forEach(c -> filteredColumnProjections.add(new ColumnProjectionImpl(c)));
 return new PageImpl<>(filteredColumnProjections, pageable, filteredColumnProjections.size());
}

ColumnProjectionImpl实现我的ColumnProjection接口的类在哪里。

这是我可以想出的最简单的解决方案,而无需调整我现有的 ColumnRepository。

于 2018-07-13T10:14:09.457 回答
2

只需一点代码,我就能达到相同的结果。

public class Queryable<T> extends QuerydslJpaPredicateExecutor<T> {

  private static final EntityPathResolver resolver = SimpleEntityPathResolver.INSTANCE;

  private final Querydsl querydsl;

  public Queryable(Class<T> domainClass, EntityManager entityManager) {
      this(JpaEntityInformationSupport.getEntityInformation(domainClass, entityManager), 
           entityManager);
  }

  private Queryable(JpaEntityInformation<T, ?> entityInformation,
      EntityManager entityManager) {
    super(entityInformation, entityManager, resolver, null);
    EntityPath<T> path = resolver.createPath(entityInformation.getJavaType());
    PathBuilder<?> builder = new PathBuilder<>(path.getType(), path.getMetadata());
    this.querydsl = new Querydsl(entityManager, builder);
  }

  public Page<T> findAll(Expression<T> expression, Predicate predicate, Pageable pageable) {
     JPQLQuery<?> countQuery = createQuery(predicate);
     JPQLQuery<T> query = querydsl.applyPagination(pageable,
                          createQuery(predicate).select(expression));
     List<T> dtos = query.fetch();
     return PageableExecutionUtils.getPage(dtos, pageable, countQuery::fetchCount);
  }
}

用法:

@Repository
@Transactional
class UserDemoRepository
    private static final QUserDemo q = QUserDemo.userDemo;
    private static final QBean<UserDemo> PROJECTION = Projections.bean(UserDemo.class, 
            q.id, q.username);

    @PersistenceContext
    private EntityManager entityManager;
    public Page<UserDemo> findAll(Predicate predicate, Pageable pageable) {
        return new Queryable<UserDemo>(UserDemo.class, entityManager)
               .findAll(PROJECTION, predicate, pageable);
  }
}

(灵感来自https://stackoverflow.com/a/53960209/1833472

于 2019-07-19T18:21:40.473 回答
1

1.CustomJpaRepositoryFactoryBean

import java.io.Serializable;

import javax.persistence.EntityManager;

import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;

public class CustomJpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends JpaRepositoryFactoryBean<T, S, ID> {
    public CustomJpaRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
        super(repositoryInterface);
    }

    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
        return new CustomJpaRepositoryFactory(entityManager);
    }
}

2.CustomJpaRepositoryFactory

import static org.springframework.data.querydsl.QueryDslUtils.QUERY_DSL_PRESENT;

import javax.persistence.EntityManager;

import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.QueryDslJpaRepository;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.RepositoryMetadata;

public class CustomJpaRepositoryFactory extends JpaRepositoryFactory {
    public CustomJpaRepositoryFactory(EntityManager entityManager) {
        super(entityManager);
    }

    @Override
    protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
        if(QUERY_DSL_PRESENT) {
            Class<?> repositoryInterface = metadata.getRepositoryInterface();
            if(CustomQueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface)) {
                return CustomQueryDslJpaRepository.class;
            } else  if(QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface)) {
                return QueryDslJpaRepository.class;
            }
        }
        return SimpleJpaRepository.class;
    }
}

3.CustomQueryDslJpaRepository

import java.io.Serializable;

import javax.persistence.EntityManager;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.QueryDslJpaRepository;
import org.springframework.data.jpa.repository.support.Querydsl;
import org.springframework.data.querydsl.EntityPathResolver;
import org.springframework.data.querydsl.SimpleEntityPathResolver;

import com.querydsl.core.QueryResults;
import com.querydsl.core.types.EntityPath;
import com.querydsl.core.types.FactoryExpression;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.jpa.JPQLQuery;

public class CustomQueryDslJpaRepository<T, ID extends Serializable> extends QueryDslJpaRepository<T, ID> implements CustomQueryDslPredicateExecutor<T> {
    private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE;

    private final Querydsl querydsl;

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

    public CustomQueryDslJpaRepository(JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager, EntityPathResolver resolver) {
        super(entityInformation, entityManager, resolver);

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

    public <DTO> Page<DTO> findAll(Predicate predicate, Pageable pageable, FactoryExpression<DTO> factoryExpression) {
        JPQLQuery<DTO> query = createQuery(predicate).select(factoryExpression);
        querydsl.applyPagination(pageable, query);
        querydsl.applySorting(pageable.getSort(), query);

        QueryResults<DTO> queryResults = query.fetchResults();
        return new PageImpl<>(queryResults.getResults(), pageable, queryResults.getTotal());
    }
}

4.CustomQueryDslPredicateExecutor

import com.querydsl.core.types.FactoryExpression;
import com.querydsl.core.types.Predicate;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;

public interface CustomQueryDslPredicateExecutor<T> extends QueryDslPredicateExecutor<T> {
    <DTO> Page<DTO> findAll(Predicate predicate, Pageable pageable, FactoryExpression<DTO> factoryExpression);
}

5. 例子

@EnableJpaRepositories(
    ...
    repositoryFactoryBeanClass = CustomJpaRepositoryFactoryBean.class
)


public interface ProductRepository extends JpaRepository<Product, Long> implements CustomQueryDslPredicateExecutor<Product> {
}
于 2018-07-23T02:30:00.997 回答