精华内容
下载资源
问答
  • 本篇文章主要介绍了spring data jpa分页查询示例代码,分页在很多项目中都能使用,具有一定的参考价值,有兴趣的可以了解一下。
  • 主要介绍了Spring Data JPA带条件分页查询实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • JPA分页查询与条件分页查询

    万次阅读 2019-05-06 00:02:00
    JPA分页查询与条件分页查询 情有独钟的JPA 平时在写一些小项目时,比较喜欢引用 Spring Data Jpa,其实还是图他写代码快~在日常的开发工作中,分页列表查询基本是随处可见,下面一起看一下如何...

    JPA分页查询与条件分页查询

    情有独钟的JPA

    平时在写一些小项目时,比较喜欢引用 Spring Data Jpa,其实还是图他写代码快~
    在日常的开发工作中,分页列表查询基本是随处可见,下面一起看一下如何使用 jpa 进行多条件查询以及查询列表分页呢?

    关于JPA的使用

    关于 jpa 的使用,下面2步简单过一下,详细资料,小伙伴自行搜索一下吧~

    1、导入依赖
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        mysql、web、druid......
    </dependency>
    2、配置yml

    图方便直接贴代码了:

    spring:
      # 数据源
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/tmax?useUnicode=true&characterEncoding=utf-8&useSSL=false
        username: root
        password: 1234
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.jdbc.Driver
      jpa:
        # 操作数据库时显示sql语句
        show-sql: true
        # 自动生成表结构
        generate-ddl: true
        hibernate:
          ddl-auto: none
        database-platform: org.hibernate.dialect.MySQL57Dialect

    分页查询

    我们了解 jpa 基本是不用去写 sql 的,继承 JpaRepository 即可,同样也提供给了我们分页查询的方法:

    举例:

    Page<VideoCategory> findByCondition(SearchVo searchVo, Pageable pageable);

    通过传入一个遵循 pageale 协议的对象来获取某一页的数据,通过源码查看,发现 Pageable 是一个接口,提供了分页一组方法的声明,如第几页,每页多少条记录,排序信息等,部分方法如下:

    int getPageNumber();

    int getPageSize();

    int getOffset();

    Sort getSort();

    Pageable next();

    Pageable previousOrFirst();

    Pageable first();

    boolean hasPrevious();

    通过这些方法我们可以构造我们的 pageable 对象,需要注意的是 jpa 在构造页码初始时,是从 0 开始的。

    废话不多说,来看一段代码吧:

    1. impl
        @Override
        public Page<VideoCategory> findByCondition(VideoCategory videoCategory, SearchVo searchVo, Pageable pageable
    {

            return videoCategoryDao.findAll(new Specification<VideoCategory>() {
                @Nullable
                @Override
                public Predicate toPredicate(Root<VideoCategory> root, CriteriaQuery<?> cq, CriteriaBuilder cb
    {

                    // 可添加你的其他搜索过滤条件 默认已有创建时间过滤
                    Path<Date> createTimeField=root.get("createTime");
                    Path<String> categoryIdField=root.get("categoryId");

                    List<Predicate> list = new ArrayList<Predicate>();

                    //创建时间
                    if(StrUtil.isNotBlank(searchVo.getStartDate())&&StrUtil.isNotBlank(searchVo.getEndDate())){
                        Date start = DateUtil.parse(searchVo.getStartDate());
                        Date end = DateUtil.parse(searchVo.getEndDate());
                        list.add(cb.between(createTimeField, start, DateUtil.endOfDay(end)));
                    }

                    // 视频分类
                    if(StrUtil.isNotBlank(videoCategory.getCategoryId())){        
                        list.add(cb.equal(categoryIdField,videoCategory.getCategoryId()));
                    }

                    Predicate[] arr = new Predicate[list.size()];
                    cq.where(list.toArray(arr));
                    return null;
                }
            }, pageable);
        }
    2. controller
        @RequestMapping(value = "/getByCondition", method = RequestMethod.GET)
        @ApiOperation(value = "多条件分页获取")
        public Result<Page<VideoCategory>> getByCondition(
                @ModelAttribute VideoCategory videoCategory,
                @ModelAttribute SearchVo searchVo,
                @ModelAttribute PageVo pageVo){

            Page<VideoCategory> page = videoCategoryService.findByCondition(videoCategory, searchVo, PageUtil.initPage(pageVo));
            return new ResultUtil<Page<VideoCategory>>().setData(page);
        }
    3. PageUtil
    public static Pageable initPage(PageVo page){

            Pageable pageable = null;
            int pageNumber = page.getPageNumber();
            int pageSize = page.getPageSize();
            String sort = page.getSort();
            String order = page.getOrder();

            if(pageNumber<1){
                pageNumber = 1;
            }
            if(pageSize<1){
                pageSize = 10;
            }
            if(StrUtil.isNotBlank(sort)) {
                Sort.Direction d;
                if(StrUtil.isBlank(order)) {
                    d = Sort.Direction.DESC;
                } else {
                    d = Sort.Direction.valueOf(order.toUpperCase());
                }
                Sort s = new Sort(d, sort);
                pageable = PageRequest.of(pageNumber-1, pageSize, s);
            } else {
                pageable = PageRequest.of(pageNumber-1, pageSize);
            }
            return pageable;
        }

    如果文章有错的地方欢迎指正,大家互相留言交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:niceyoo

    posted @ 2019-05-06 00:02 niceyoo 阅读( ...) 评论( ...) 编辑 收藏
    展开全文
  • jpa分页查询

    2018-07-25 09:55:07
    法一(本地sql查询,注意表名啥的都用数据库中的名称,适用于特定数据库的查询) public interface UserRepository extends JpaRepository&lt;User, Long&gt; { @Query(value = "SELECT * FROM U.....

    转自https://www.cnblogs.com/hdwang/p/7843405.html

    法一(本地sql查询,注意表名啥的都用数据库中的名称,适用于特定数据库的查询)

    public interface UserRepository extends JpaRepository<User, Long> {
     
      @Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",
        countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
        nativeQuery = true)
      Page<User> findByLastname(String lastname, Pageable pageable);
    }

     

    法二(jpa已经实现的分页接口,适用于简单的分页查询)

    public interface PagingAndSortingRepository<T, ID extends Serializable>
      extends CrudRepository<T, ID> {
     
      Iterable<T> findAll(Sort sort);
     
      Page<T> findAll(Pageable pageable);
    }
     
    Accessing the second page of User by a page size of 20 you could simply do something like this:
     
    PagingAndSortingRepository<User, Long> repository = // … get access to a bean
    Page<User> users = repository.findAll(new PageRequest(1, 20));

     

    User findFirstByOrderByLastnameAsc();
     
    User findTopByOrderByAgeDesc();
     
    Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);
     
    Slice<User> findTop3ByLastname(String lastname, Pageable pageable);
     
    List<User> findFirst10ByLastname(String lastname, Sort sort);
     
    List<User> findTop10ByLastname(String lastname, Pageable pageable);
    //service 
    Sort sort = new Sort(Sort.Direction.DESC,"createTime"); //创建时间降序排序 
    Pageable pageable = new PageRequest(pageNumber,pageSize,sort); this.depositRecordRepository.findAllByUserIdIn(userIds,pageable); 
    //repository 
    Page<DepositRecord> findAllByUserIdIn(List<Long> userIds,Pageable pageable);
    

    法三(Query注解,hql语局,适用于查询指定条件的数据)

     @Query(value = "select b.roomUid from RoomBoard b where b.userId=:userId and b.lastBoard=true order by  b.createTime desc")
        Page<String> findRoomUidsByUserIdPageable(@Param("userId") long userId, Pageable pageable);
    	
    	
    	Pageable pageable = new PageRequest(pageNumber,pageSize);
    Page<String> page = this.roomBoardRepository.findRoomUidsByUserIdPageable(userId,pageable);
    List<String> roomUids = page.getContent();
    //可以自定义整个实体(Page<User>),也可以查询某几个字段(Page<Object[]>),和原生sql几乎一样灵活。

     

    法四(扩充findAll,适用于动态sql查询

    public interface UserRepository extends JpaRepository<User, Long> ,JpaSpecificationExecutor<User>{
     
        Page<User> findAll(Specification<User> spec, Pageable pageable);
    } 
     
    @Service
    public class UserService {
     
        @Autowired
        private UserRepository userRepository;
     
        public Page<User> getUsersPage(PageParam pageParam, String nickName) {
            //规格定义
            Specification<User> specification = new Specification<User>() {
     
                /**
                 * 构造断言
                 * @param root 实体对象引用
                 * @param query 规则查询对象
                 * @param cb 规则构建对象
                 * @return 断言
                 */
                @Override
                public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                    List<Predicate> predicates = new ArrayList<>(); //所有的断言
                    if(StringUtils.isNotBlank(nickName)){ //添加断言
                        Predicate likeNickName = cb.like(root.get("nickName").as(String.class),nickName+"%");
                        predicates.add(likeNickName);
                    }
                    return cb.and(predicates.toArray(new Predicate[0]));
                }
            };
            //分页信息
            Pageable pageable = new PageRequest(pageParam.getPage()-1,pageParam.getLimit()); //页码:前端从1开始,jpa从0开始,做个转换
            //查询
            return this.userRepository.findAll(specification,pageable);
        }
     
    }

     

    法五(使用entityManager,适用于动态sql查询)

        @Service
        @Transactional
        public class IncomeService{
         
            /**
             * 实体管理对象
             */
            @PersistenceContext
            EntityManager entityManager;
         
            public Page<IncomeDaily> findIncomeDailysByPage(PageParam pageParam, String cpId, String appId, Date start, Date end, String sp) {
                StringBuilder countSelectSql = new StringBuilder();
                countSelectSql.append("select count(*) from IncomeDaily po where 1=1 ");
         
                StringBuilder selectSql = new StringBuilder();
                selectSql.append("from IncomeDaily po where 1=1 ");
         
                Map<String,Object> params = new HashMap<>();
                StringBuilder whereSql = new StringBuilder();
                if(StringUtils.isNotBlank(cpId)){
                    whereSql.append(" and cpId=:cpId ");
                    params.put("cpId",cpId);
                }
                if(StringUtils.isNotBlank(appId)){
                    whereSql.append(" and appId=:appId ");
                    params.put("appId",appId);
                }
                if(StringUtils.isNotBlank(sp)){
                    whereSql.append(" and sp=:sp ");
                    params.put("sp",sp);
                }
                if (start == null)
                {
                    start = DateUtil.getStartOfDate(new Date());
                }
                whereSql.append(" and po.bizDate >= :startTime");
                params.put("startTime", start);
         
                if (end != null)
                {
                    whereSql.append(" and po.bizDate <= :endTime");
                    params.put("endTime", end);
                }
         
                String countSql = new StringBuilder().append(countSelectSql).append(whereSql).toString();
                Query countQuery = this.entityManager.createQuery(countSql,Long.class);
                this.setParameters(countQuery,params);
                Long count = (Long) countQuery.getSingleResult();
         
                String querySql = new StringBuilder().append(selectSql).append(whereSql).toString();
                Query query = this.entityManager.createQuery(querySql,IncomeDaily.class);
                this.setParameters(query,params);
                if(pageParam != null){ //分页
                    query.setFirstResult(pageParam.getStart());
                    query.setMaxResults(pageParam.getLength());
                }
         
                List<IncomeDaily> incomeDailyList = query.getResultList();
              if(pageParam != null) { //分页
                    Pageable pageable = new PageRequest(pageParam.getPage(), pageParam.getLength());
                    Page<IncomeDaily> incomeDailyPage = new PageImpl<IncomeDaily>(incomeDailyList, pageable, count);
                    return incomeDailyPage;
                }else{ //不分页
                    return new PageImpl<IncomeDaily>(incomeDailyList);
                }
            }
         
            /**
             * 给hql参数设置值
             * @param query 查询
             * @param params 参数
             */
            private void setParameters(Query query,Map<String,Object> params){
                for(Map.Entry<String,Object> entry:params.entrySet()){
                    query.setParameter(entry.getKey(),entry.getValue());
                }
            }
        }
    
    

     

    展开全文
  • 针对使用JPA方式操作数据库的复杂查询快速开发,复制代码直接使用,快速开发
  • 如何使用jpa进行多条件查询以及查询列表分页呢?下面我将介绍两种多条件查询方式。具体实例代码大家参考下本文吧
  • JPA分页查询,在单表查询以及数据量不大的情况下,非常容易写,也利于后面的维护,但是效率却达不到预期

    涉及

    • Spring Data JPA

    • MySQL


    前言

    由于公司的基础框架封装使用的是JPA,一开始的分页查询使用了JPA封装的findAll()方法实现,在单表查询以及数据量不大的情况下,这种方式的查询非常容易写,也利于后面的维护

    以学生实体StudentEntity为例,写一个简单的分页查询,我只需要下面几个步骤:

    //创建一个查询用的实体类,需要查询的实际值 set 进该实体类里
    StudentEntity queryEntity = new Studentity();
    queryEntity.setName("王");
    queryEntity.setAge(10);
    //创建一个 ExampleMatcher 对象
    ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                    .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.startsWith())
                    .withMatcher("age", ExampleMatcher.GenericPropertyMatchers.exact());
    //查询分页结果
    StudentDao.findAll(Example.of(queryEntity, exampleMatcher),PageRequest.of(0, 10, Sort.of("modiFyTime")));
    

    还原生成的SQL语句

    通过还原语句,发现JPA生成的语句是下面这样的

    select name, age, ... from student where name like '王%', age = 10 order by modifyTime desc limit 10
    

    当 Limit 特别大,到十万甚至百万数据时,会导致查询速度呈几何倍下降,将真实的数据导入后,第一页的查询耗时竟然超过了一秒,到万页时耗时竟然超过了40S,这是不能接受的,优化它成为了必然事件


    JPA查询优化

    由于 JPA 生成的语句不符合要求,于是我选择了原生 SQL 的方式,自定义原生语句进行查询

    优化思路是这样的:

    • 语句是一定要优化的,生成的语句根本无法满足这么大数据量的分页查询需求
    • 要查看不同条件下是否都走了索引,联合索引的建立是否合理

    第一点,我们强制让语句走索引,并且只查它的主键来提高查询速度

    select id from student order by modifyTime desc limit 0, 10
    

    此时语句的执行速度是非常快的,会从秒级提升到毫秒级,在实际业务中 pageSize 也不会特别大,接口也是有做限制的,在下一步,把这个语句的查询结果当做子查询,把语句变成下面这样

    select * from student a, (select id from student order by modifyTime desc limit 0, 10) b where a.id = b.id
    

    配合动态查询条件的联合索引,哪怕是百万级,千万级数据,其查询速度也能维持在毫秒级


    优化后的 JPA DAO方法:

    @Query(value = "select * from student a, (select id from student where name like contact(:name, '%') and age = :age order by modifyTime desc limit :pageNo, :pageSize) b where a.id = b.id", nativeQuery = true)
    List<Student> findAll(String name, int age, int pageNo, int pageSize);
    

    📖 使用JPA面临的另一个问题:

    既然是分页,还得解决一个问题是如何把总数一起查出来,比如查询18岁的老王,第一页,查十条,需要返回给前端的还有一共有多少个老王

    目前解决方案是把上面语句的查询字段从*改为count(id),进行两次查询,两次毫秒级的查询组合在一起,似乎也不是不能接受

    展开全文
  • SpringBoot ——JPA分页查询

    千次阅读 2019-01-20 15:05:48
    JpaRepository提供了如下表所述的内置查询: 方法 描述 List findAll() 返回所有实体 List findAll(Iterable ids) 返回指定id的所有实体 T getOne(ID id) 根据id返回对应的实体,如果未找到,则...

    JpaRepository提供了如下表所述的内置查询:

    方法描述
    List findAll()返回所有实体
    List findAll(Iterable ids)返回指定id的所有实体
    T getOne(ID id)根据id返回对应的实体,如果未找到,则返回空
    List findAll(Sort sort)返回所有实体,按照指定顺序排序返回
    Page findAll(Pageable pageable)返回实体列表,实体的offset和limit通过pageable来指定

     

     

     

     

     

     

     

    主要讲讲第5个方法:
    Pageable接口:

    PageRequest是Pageable的实现类,可以通过以下工厂方法创建:

    public static PageRequest of(int page,int size)

    public static PageRequest of(int page,int size,Sort sort)

    public static PageRequest of(int page,int size,Direction direction,String ... properties)

    page从0开始,表示查询页,size是个数

    Page类:

    int getTotalPages()    获取总的页数

    long getTotalElements()   返回总数

    List getContent()     返回某页的结果集

     

    例子:

    @Entity
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
        @Column(length = 255)
    
        private String name;
        @Column(length = 2)
        private String sex;
        @Column(length = 255)
        private String address;
        public User(){}
    
        public User(int id, String name, String sex, String address) {
            this.id = id;
            this.name = name;
            this.sex = sex;
            this.address = address;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", sex='" + sex + '\'' +
                    ", address='" + address + '\'' +
                    '}';
        }
    }
    @Repository
    public interface UserRepository extends JpaRepository<User,Integer> {
    }
        @Test
        public void contextLoads() {
            PageRequest pageReques=PageRequest.of(0,2);   //获取第1页的两条记录
            Page<User>  page=userRepository.findAll(pageReques);
            List<User> users=page.getContent();
            for(User t:users)
                System.out.println(t);
         }

     

    展开全文
  • Springboot 快速学会使用 JPA 分页查询

    千次阅读 2019-10-16 10:04:12
    如果还不知道springboot怎么使用JPA的,先参考这篇 Springboot快速整合JPA实现增删查改:...示例场景,将下面表数据分页查询出来: 简单模拟, mapper: @Query(value="select * from u...
  • 脑壳疼,一个分页弄老半天,原来就一句话的事情,唉 先来说说正常的JPA如何操作 实体类对应表来创建,举个例子 @Entity @Table(name = "td_user") public class TdUser extends BaseModel { private static ...
  • springboot jpa 分页查询(增删改查)总结

    万次阅读 2018-11-12 19:27:13
    springboot jpa 分页查询(增删改查)总结  jpa 大白话可以把它理解为一个插件,在开发过程中,目的在于可以提供你更加简单的编程模型,简单方便 。  JPA框架中支持大数据集、事务、并发等容器级事务,使得 JPA ...
  • 使用jpa查询,带分页时候,由于数据量千万级别,导致查询时候过慢。   <p>2.尝试解决方法:重写jpa方法,让其返回Slice<T>类, 可以避免统计总数量的sql语句。...
  • JPA分页查询

    2020-05-19 15:19:04
    1、Dao层自定义函数 2、service层获取分页参数
  • SpringDataJpa 分页查询

    2019-09-28 23:32:47
    org.springframework.data.jpa.repository.QueryHints; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import javax.persistence....
  • 主要介绍了SpringBoot Jpa分页查询配置方式解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • jpa的首页是从0开始的 解决了一下午的bug,头疼
  • Jpa分页查询遇到的bug

    2020-04-16 16:48:19
    使用Jpa hsql直接进行分页查询,查询失败 报错error Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: order near line 1, column 14 ...
  • SpringBoot Jpa 分页查询 JpaRepository提供了如下表所述的内置查询: 方法 描述 List findAll() 返回所有实体 List findAll(Iterable ids) 返回指定id的所有实体 T getOne(ID id) 根据id返回...
  • JPA分页查询有total没有content

    千次阅读 2019-11-27 11:10:03
    (1)首先原因是pageable这个插件中默认的page是从0开始读的和我们之前用的pageHelper的page默认初始值是不一样的 解决方法: // controller接口的方法 public ResponseEntity listUserForParam(@RequestParam...
  • 主要介绍了JPA多条件复杂SQL动态分页查询功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
  • Spring JPA 分页查询

    2020-10-29 11:01:15
    这次项目需要Spring JPA分页 ,动手写了一下。 其实 Spring JPA 已经有封装好的分页方法,但是,那些只适合特定的查询条件, 不适合动态条件查询。 方法1: 注意表名啥的都用数据库中的名称, 适用于特定数据库...
  • SpringData JPA分页查询

    2017-10-22 12:12:35
    首先我们的持久化层继承JpaRepository,相当于继承了增删改查的持久化层以及分页查询的持久化层 所以如果我们要使用分页查询 ,我们只需要直接调用 由一开始的图也可以看到Pageable的其中一个实现,直接新建一...
  • 主要介绍了Spring Data JPA分页复合查询原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  •  上一篇博客(JPA排序中的join排序及case when的使用)中有提到一个场景:对象A中包含了Set&lt;B&gt; objBs这样一个成员,要求查询A时按A中包含的B数量排序,当时的解决方案是count一下B,然后order by这个...
  • 查询出数据,但是每页查询出的数据都相同 错误原因: 主键设置错误,JPA要求每一个实体Entity,必须有且只有一个主键 在唯一属性上添加@Id 和@GeneratedValue错误解决 @GeneratedValue:为实体生成一个唯一标识的...
  • jpa 分页查询

    千次阅读 2018-02-14 22:38:50
    转自https://www.cnblogs.com/hdwang/p/7843405.html法一(本地sql查询,注意表名啥的都用数据库中的名称,适用于特定数据库的查询)public interface UserRepository extends JpaRepository&lt;User, Long&...
  • 出现BUG: 数据不知道,应该为74条数据,在分页查询时会出现查询数与实际条数不符情况. 归结原因为 : 第一次查询第一页后将数据状态修改,第二次查询第二页总页数变为2页,导致应该查询之前的第二页变为查询第三页,过滤...
  • 在执行查询方法时,可以传入一个PageRequest对象,代表进行分页查询。 PageRequest对象代表了查询的条件和约束,通常包含当前页数,每页几条数据。 也可以在分页查询时指定Direction或Sort。 查询的结果为Page&...
  • Spring Data JPA分页查询

    千次阅读 2018-07-28 22:46:02
    使用Spring Data JPA的朋友,在实际工作中经常需要用到分页查询。下面介绍一个简单的分页查询的例子:查询学生信息,每页10行数据,并按成绩排序。先看数据表:   实现:repo需要继承PagingAndSortingRepository...
  • 使用JPA分页查询自定义语句的坑和解决方案 ![sql](https://img-blog.csdnimg.cn/20191107153821739.png) ![报错信息](https://img-blog.csdnimg.cn/20191107153952299.png) 解决方案一 删除sql语句中开头的空格 ![]...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,722
精华内容 7,088
关键字:

jpa分页查询