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; | |
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"; | |
public MongoClient mongoClient() { | |
ConnectionString str = new ConnectionString("mongodb://"+ IP + ":"+ PORT + "/" + getDatabaseName()); | |
MongoClientSettings mongoClientSettings = MongoClientSettings.builder() | |
.applyConnectionString(str) | |
.build(); | |
return MongoClients.create(mongoClientSettings); | |
} | |
public MongoTemplate mongoTemplate() throws Exception { | |
return new MongoTemplate(mongoClient() , getDatabaseName()); | |
} | |
protected String getDatabaseName() { | |
return DB_NAME; | |
} | |
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; | |
public class User implements Serializable { | |
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; | |
public interface UserRepository extends MongoRepository<User, Long> { | |
User findByEmail(String email); | |
Optional<User> findById(Long id); | |
} |
业务实现类:基于ExampleMatcher 实现业务参数的加入,Pageable
封装分页的参数
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; | |
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; | |
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; | |
public class PageBean { | |
// 当前页 | |
private Integer pageIndex = 1; | |
// 一页的条数 | |
private Integer pageRowNum = 10; | |
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; | |
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类进行调用:
= "/user/mongoPageList") | (value|
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())); | |
} |