学习
实践
活动
专区
工具
TVP
写文章
专栏首页Nicky's blogSpringBoot系列之基于MongoRepository实现分页

SpringBoot系列之基于MongoRepository实现分页

Spring Data MongoDB项目提供了与MongoDB文档数据库的集成。是Spring Data项目的一个分支。本博客基于Spring Data MongoDB实现,引入项目spring-boot-starter-data-mongodb实现MongoDB的分页,仅供参考

环境准备

  • 开发环境
    • JDK 1.8
    • SpringBoot2.2.1
    • Maven 3.2+
  • 开发工具
    • IntelliJ IDEA
    • smartGit
    • Navicat15

Maven配置

新建一个SpringBoot下面,在pom配置文件里加上,dependencyManagement进行Springboot统一的版本控制

<properties>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <spring-boot.version>2.2.1.RELEASE</spring-boot.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

加上mongoDB的starter配置,加上spring-boot-starter-data-mongodb封装好的starter

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

也可以加上PageHelper的配置,非必须

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.10</version>
</dependency>

MongoDB配置

有些版本启动可能会报错,所以可以先exclude数据库的自动配置,在Application类加上@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})

加上MongoDB的一些自定义配置

package com.example.mongodb.configuration;

import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import java.util.Collection;
import java.util.Collections;

@Configuration
@EnableMongoRepositories(basePackages = "com.example.mongodb.repository")
public class MongoConfiguration extends AbstractMongoClientConfiguration {

    private static final String DB_NAME = "test";
    private static final String IP = "127.0.0.1";
    private static final String PORT = "27017";

    @Override
    public MongoClient mongoClient() {
        ConnectionString str = new ConnectionString("mongodb://"+ IP + ":"+ PORT + "/" + getDatabaseName());
        MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
                .applyConnectionString(str)
                .build();
        return MongoClients.create(mongoClientSettings);
    }


    @Override
    public MongoTemplate mongoTemplate() throws Exception {
        return new MongoTemplate(mongoClient() , getDatabaseName());
    }

    @Override
    protected String getDatabaseName() {
        return DB_NAME;
    }

    @Override
    protected Collection<String> getMappingBasePackages() {
        return Collections.singleton("com.example.mongodb");
    }
}

代码实现

加上Document类,collection 对应数据库对应的文档

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoId;

import java.io.Serializable;

@Data
@SuperBuilder(toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Document(collection = "user")
public class User implements Serializable {
    @MongoId
    private Long id;
    private String name;
    private Integer age;
    private String email;

}

加上接口实现MongoRepository<User, Long> ,一个User是对应的文档类,Long是对应的主键id

import com.example.mongodb.model.User;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface UserRepository extends MongoRepository<User, Long> {

    @Query("{ 'email' : ?0 }")
    User findByEmail(String email);

    @Query("{'_id' : ?0 }")
    Optional<User> findById(Long id);

}

业务实现类:基于ExampleMatcher 实现业务参数的加入,Pageable封装分页的参数

@Override
public org.springframework.data.domain.Page<User> mongoPageList(PageBean pageBean, User queryParam) {
    User param = new User();
    if (StrUtil.isNotBlank(queryParam.getName())) {
        param.setName(queryParam.getName());
    }
    ExampleMatcher matcher = ExampleMatcher.matching()
            .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains());
    Example<User> example = Example.of(param, matcher);
    Sort sort = Sort.by(Sort.Direction.DESC, "_id");
    Pageable pageable = PageRequest.of(pageBean.getPageIndex() - 1, pageBean.getPageRowNum(), sort);
    org.springframework.data.domain.Page<User> page = userRepository.findAll(example, pageable);
    return new PageImpl<User>(page.getContent() , pageable , page.getTotalElements());
}

拓展

分页基于MongoRepository实现比较容易,不过发现index是从0开始的,返回的参数比较少,比如总页数,虽然也可以前端自己计算,不过为了统一规范,可以自己再根据需要进行封装

定义一个ResultBean,返回给前端

package com.example.mongodb.common.rest;

import lombok.Data;
import org.springframework.http.HttpStatus;

@Data
public class ResultBean<T> {

	/**
	 * 状态
	 * */
	private int status;
	/**
	 * 描述
	 * */
	private String desc;
	/**
	 * 数据返回
	 * */
	private T data;

	public ResultBean(int status, String desc, T data) {
		this.status = status;
		this.desc = desc;
		this.data = data;
	}

	public ResultBean(T data) {
		this.status = HttpStatus.OK.value();
		this.desc = "处理成功";
		this.data = data;
	}

	public static <T> ResultBean<T> ok(T data) {
		return new ResultBean(data);
	}

	public static <T> ResultBean<T> ok() {
		return new ResultBean(null);
	}

	public static <T> ResultBean<T> badRequest(String desc,T data) {
		return new ResultBean(HttpStatus.BAD_REQUEST.value(), desc, data);
	}

	public static <T> ResultBean<T> badRequest(String desc) {
		return new ResultBean(HttpStatus.BAD_REQUEST.value(), desc, null);
	}

	public static <T> ResultBean serverError(String desc, T data){
		return new ResultBean(HttpStatus.INTERNAL_SERVER_ERROR.value(),"服务器内部异常:"+desc,data);
	}

	public static <T> ResultBean serverError(String desc){
		return new ResultBean(HttpStatus.INTERNAL_SERVER_ERROR.value(),"服务器内部异常:"+desc,null);
	}

}

分页的对象

package com.example.mongodb.common.page;

import lombok.Data;

@Data
public class PageObject {
    // 当前页
    private long pageIndex;
    // 当前页数
    private long pageRowNum;
    // 总页数
    private long totalPage;
    // 总数量
    private long totalRow;

}

分页查询类

package com.example.mongodb.common.page;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Optional;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PageBean {

    // 当前页
    private Integer pageIndex = 1;
    // 一页的条数
    private Integer pageRowNum = 10;

    @JsonIgnore
    private Page pages;

    public void initPage() {
        this.pages = PageHelper.startPage(pageIndex , pageRowNum);
    }

    public PageDataBean loadData(List dataList) {
        return new PageDataBean(dataList , pages.getTotal() , pageIndex , pageRowNum);
    }

    public PageBean setPageBean(org.springframework.data.domain.Page page) {
        PageBean pageBean = new PageBean();
        pageBean.setPageRowNum(pageRowNum);
        pageBean.setPageIndex(pageIndex);
        Optional.ofNullable(page).ifPresent(e->{
            Page<?> pageHelper = new Page<>();
            pageHelper.setTotal(page.getTotalElements());
            pageHelper.setPageNum(pageRowNum);
            pageHelper.setPageSize(pageIndex);
            pageBean.setPages(pageHelper);
        });
        return pageBean;
    }

}

分页数据返回类:

package com.example.mongodb.common.page;


import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Data
public class PageDataBean<T> {

    private List<T> dataList = new ArrayList<>();

    private PageObject pageObj = new PageObject();

    public PageDataBean(List<T> dataList , Long totalRow , Integer pageIndex , Integer pageRowNum) {
        this.dataList = dataList;
        pageObj.setPageIndex(pageIndex);
        pageObj.setPageRowNum(pageRowNum);
        pageObj.setTotalRow(totalRow);
        pageObj.setTotalPage(totalRow / pageRowNum + (totalRow % pageRowNum == 0 ? 0 : 1));
    }

}

基于上面的封装类,Controller类进行调用:

@GetMapping(value = "/user/mongoPageList")
public ResultBean<PageDataBean<List<User>>> mongoPageList(PageBean pageBean , User param) {
    Page<User> pageDataBean = userService.mongoPageList(pageBean, param);
    pageBean = pageBean.setPageBean(pageDataBean);
    return ResultBean.ok(pageBean.loadData(pageDataBean.getContent()));
}
本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!
本文分享自作者个人站点/博客:https://blog.csdn.net/u014427391复制
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • SpringBoot系列之MongoDB分页接口实现

    spring-boot-starter-data-mongodb也有集成基于Spring Data的分页实现,但是习惯了用PageHelper,所以基于Page...

    SmileNicky
  • 【SpringBoot2.0系列09】SpringBoot之rabbitmq使用实现

    RabbitMQ是由Erlang语言编写的实现了高级消息队列协议(AMQP)的开源消息代理软件(也可称为 面向消息的中间件)。支持Windows、Linux/U...

    yukong
  • SpringBoot整合Spring Data Mongodb

    爱撒谎的男孩
  • SpringBoot系列之集成kafka实现事件发布

    事件发布订阅实现,我们经常使用到spring框架提供的ApplicationEventPublisher,基于kafka的特性,我们也可以简单实现类似的效果

    SmileNicky
  • SpringBoot源码学习系列之@PropertySource注解实现

    因为yaml语法很简洁,比较喜欢写yaml配置文件,但是经过试验,@PropertySource默认不支持yaml读取,我们改成@Value注解也是可以读取的,...

    SmileNicky
  • 第五十二章:基于SpringBoot2使用Rest访问MongoDB数据

    恒宇少年
  • 让 MongoDB 的 CRUD 有 JPA 的味道

    文末提供我整理的 SpringBoot 整合、操作 MongoDB 文档的下载方式!!!

    码农UP2U
  • 【SpringBoot2.0系列05】SpringBoot之整合Mybatis前言实现

    【SpringBoot2.0系列02】SpringBoot之使用Thymeleaf视图模板

    yukong
  • 【SpringBoot2.0系列10】SpringBoot之@Scheduled任务调度实现结语

    相信大家在实际工作场景中会遇到这样的情况,系统之间存在数据交换,为了不影响正常服务器运,我们需要在每天的凌晨来进行数据交换,但是让程序每天凌晨自动执行呢,下面带...

    yukong
  • 【SpringBoot2.0系列08】SpringBoot之redis数据缓存管理目标实现

    【SpringBoot2.0系列02】SpringBoot之使用Thymeleaf视图模板

    yukong
  • 第五十一章:基于SpringBoot2 & MongoDB完成自动化集成本章目标为你推荐企业级核心技术学习专题准备MongDB构建项目测试总结

    恒宇少年
  • SpringBoot系列之canal和kafka实现异步实时更新

    canal是阿里开源的, 对数据库增量日志解析,提供增量数据订阅和消费的组件。引用官网的图片,canal的工作原理主要是模拟 MySQL slave 的交互协议...

    SmileNicky
  • SpringBoot系列之使用Spring Task实现定时任务

    定时任务是企业开发中很常用的,比如定时推送一些接口数据,在java中实现定时任务的方法有Spring Task、Quartz等等框架,也有JDK自带的Sched...

    SmileNicky
  • 芋道 Spring Boot MongoDB 入门

    MongoDB 中的许多概念在 MySQL 中具有相近的类比。本表概述了每个系统中的一些常见概念。

    芋道源码
  • 【SpringBoot系列02】SpringBoot之使用Thymeleaf视图模板前言一、目标二、实现三、总结

    Thymeleaf 是Java服务端的模板引擎,与传统的JSP不同,前者可以使用浏览器直接打开,因为可以忽略掉拓展属性,相当于打开原生页面,给前端人员也带来一定...

    yukong
  • 【SpringBoot DB 系列】Mybatis基于AbstractRoutingDataSource与AOP实现多数据源切换

    前面一篇博文介绍了 Mybatis 多数据源的配置,简单来讲就是一个数据源一个配置指定,不同数据源的 Mapper 分开指定;本文将介绍另外一种方式,借助Abs...

    一灰灰blog
  • 【SpringBoot DB 系列】Mybatis 基于 AbstractRoutingDataSource 与 AOP 实现多数据源切换

    前面一篇博文介绍了 Mybatis 多数据源的配置,简单来讲就是一个数据源一个配置指定,不同数据源的 Mapper 分开指定;本文将介绍另外一种方式,借助Abs...

    一灰灰blog

扫码关注腾讯云开发者

领取腾讯云代金券