这节我们将整合Spring Boot与Mongo DB实现增删改查的功能,并且实现序列递增。Mongo DB下载地址。Mongo DB的基本介绍和增删改查的用法可以参考文章: MongoDB shell MongoDB文档CUD MongoDB 文档查询

新建一个Spring Boot项目,版本为2.1.3.RELEASE,并引入如下依赖:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-mongodb</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-web</artifactId>
  8. </dependency>

然后可以通过Mongo Shell或者Mongo Compass工具创建一个名称为testdb的数据库,并新增user文档(文档,类似与关系型数据库里的数据表):

Spring Boot整合Mongo DB - 图1

在配置文件application.yml里配置Mongo DB:

  1. spring:
  2. data:
  3. mongodb:
  4. host: localhost
  5. port: 27017
  6. database: testdb

Mongo DB的默认端口为27017,使用的数据库为刚刚创建的testdb。

创建User实体类:

  1. @Document(collection = "user")
  2. public class User {
  3. @Id
  4. private String id;
  5. private String name;
  6. private Integer age;
  7. private String description;
  8. // get set 略
  9. }

@Document(collection = "user")表明这是一个文档对象,名称为user,对应Mongo DB里的user表。@Id标注主键字段,String类型的主键值在插入的时候Mongo DB会帮我们自动生成。如果对象中的某个属性为非表字段,可以使用注解@Transient进行排除。

准备好这些后,我们开始编写一些简单的增删改查样例。

简单增删改查

创建一个UserDao接口:

  1. @Repository
  2. public interface UserDao extends MongoRepository<User, String> {
  3. }

接口继承自MongoRepository,泛型分别为实体对象和主键类型。通过继承MongoRepositoryUserDao包含了一些增删改查的方法,如下图所示:

Spring Boot整合Mongo DB - 图2

接着编写UserService,为了方便这里不再编写接口:

  1. @Service
  2. public class UserService {
  3. @Autowired
  4. private UserDao userDao;
  5. public List<User> getUsers() {
  6. return userDao.findAll();
  7. }
  8. public Optional<User> getUser(String id) {
  9. return this.userDao.findById(id);
  10. }
  11. /**
  12. * 新增和修改都是 save方法,
  13. * id 存在为修改,id 不存在为新增
  14. */
  15. public User createUser(User user) {
  16. user.setId(null);
  17. return userDao.save(user);
  18. }
  19. public void deleteUser(String id) {
  20. this.userDao.findById(id)
  21. .ifPresent(user -> this.userDao.delete(user));
  22. }
  23. public void updateUser(String id, User user) {
  24. this.userDao.findById(id)
  25. .ifPresent(
  26. u -> {
  27. u.setName(user.getName());
  28. u.setAge(user.getAge());
  29. u.setDescription(user.getDescription());
  30. this.userDao.save(u);
  31. }
  32. );
  33. }
  34. }

上面我们编写了基本的增删改查样例,新增和修改都是通过save方法完成的,当主键存在时则为修改,主键不存在则为新增。

最后编写一个RESTful的UserController(为了方便,没有对参数进行校验):

  1. @RestController
  2. @RequestMapping("user")
  3. public class UserController {
  4. @Autowired
  5. private UserService userService;
  6. @GetMapping
  7. public List<User> getUsers() {
  8. return userService.getUsers();
  9. }
  10. @PostMapping
  11. public User createUser(User user) {
  12. return userService.createUser(user);
  13. }
  14. @DeleteMapping("/{id}")
  15. public void deleteUser(@PathVariable String id) {
  16. userService.deleteUser(id);
  17. }
  18. @PutMapping("/{id}")
  19. public void updateUser(@PathVariable String id, User user) {
  20. userService.updateUser(id, user);
  21. }
  22. /**
  23. * 根据用户 id查找
  24. * 存在返回,不存在返回 null
  25. */
  26. @GetMapping("/{id}")
  27. public User getUser(@PathVariable String id) {
  28. return userService.getUser(id).orElse(null);
  29. }
  30. }

启动项目,使用postman来测试接口的可用性。

测试新增用户:

Spring Boot整合Mongo DB - 图3

新增成功,查看数据库:

Spring Boot整合Mongo DB - 图4

测试查询用户:

Spring Boot整合Mongo DB - 图5

查询成功。

测试通过用ID查找用户:

Spring Boot整合Mongo DB - 图6

更新用户:

Spring Boot整合Mongo DB - 图7

查看数据库是否更新成功:

Spring Boot整合Mongo DB - 图8

更新成功。

最后测试通过用户ID删除用户:

Spring Boot整合Mongo DB - 图9

返回状态码200,删除成功。

查看数据库,删除成功:

Spring Boot整合Mongo DB - 图10

多条件查询

其实UserDao通过继承MongoRepository已经具有了JPA的特性,我们可以通过方法名来构建多查询条件的SQL。比如通过用户的年龄段来查询:

  1. @Repository
  2. public interface UserDao extends MongoRepository<User, String> {
  3. /**
  4. * 根据年龄段来查找
  5. *
  6. * @param from from
  7. * @param to to
  8. * @return List<User>
  9. */
  10. List<User> findByAgeBetween(Integer from, Integer to);
  11. }

在输入findBy后,IDEA会根据实体对象的属性和SQL的各种关键字自动组合提示:

Spring Boot整合Mongo DB - 图11

比如再在创建一个通过年龄段,用户名和描述(模糊查询)查询用户的方法:

  1. /**
  2. * 通过年龄段,用户名,描述(模糊查询)
  3. *
  4. * @param from from
  5. * @param to to
  6. * @param name name
  7. * @param description description
  8. * @return List<User>
  9. */
  10. List<User> findByAgeBetweenAndNameEqualsAndDescriptionIsLike(Integer from, Integer to, String name, String description);

方法参数个数需要和方法名中所需要的参数个数对应上。

排序与分页

排序和分页需要使用MongoTemplate对象来完成,在UserService里新增一个getUserByCondition方法:

  1. @Autowired
  2. private MongoTemplate template;
  3. public Page<User> getUserByCondition(int size, int page, User user) {
  4. Query query = new Query();
  5. Criteria criteria = new Criteria();
  6. if (!StringUtils.isEmpty(user.getName())) {
  7. criteria.and("name").is(user.getName());
  8. }
  9. if (!StringUtils.isEmpty(user.getDescription())) {
  10. criteria.and("description").regex(user.getDescription());
  11. }
  12. query.addCriteria(criteria);
  13. Sort sort = new Sort(Sort.Direction.DESC, "age");
  14. Pageable pageable = PageRequest.of(page, size, sort);
  15. List<User> users = template.find(query.with(pageable), User.class);
  16. return PageableExecutionUtils.getPage(users, pageable, () -> template.count(query, User.class));
  17. }

size表示每页显示的条数,page表示当前页码数,0表示第一页。上面的方法通过namedescription(模糊查询)来查询用户分页信息,并且查询结果使用age字段降序排序。方法返回Page对象。

UserController里添加:

  1. @GetMapping("/condition")
  2. public Page<User> getUserByCondition(int size, int page, User user) {
  3. return userService.getUserByCondition(size, page, user);
  4. }

重启项目,我们往数据库里多加几条数据:

Spring Boot整合Mongo DB - 图12

获取第1页数据,每页显示10条:

Spring Boot整合Mongo DB - 图13

返回数据:

  1. {
  2. "content": [
  3. {
  4. "id": "5ca56ae2f08f0b6048fd470d",
  5. "name": "jane",
  6. "age": 26,
  7. "description": "web developer"
  8. },
  9. {
  10. "id": "5ca56ad1f08f0b6048fd470c",
  11. "name": "scott",
  12. "age": 23,
  13. "description": "ui designer"
  14. },
  15. {
  16. "id": "5ca56afaf08f0b6048fd470e",
  17. "name": "mike",
  18. "age": 21,
  19. "description": "python developer"
  20. },
  21. {
  22. "id": "5ca56b38f08f0b6048fd470f",
  23. "name": "mrbird",
  24. "age": 18,
  25. "description": "java noob"
  26. }
  27. ],
  28. "pageable": {
  29. "sort": {
  30. "sorted": true,
  31. "unsorted": false,
  32. "empty": false
  33. },
  34. "offset": 0,
  35. "pageSize": 10,
  36. "pageNumber": 0,
  37. "unpaged": false,
  38. "paged": true
  39. },
  40. "last": true,
  41. "totalPages": 1,
  42. "totalElements": 4,
  43. "number": 0,
  44. "size": 10,
  45. "sort": {
  46. "sorted": true,
  47. "unsorted": false,
  48. "empty": false
  49. },
  50. "numberOfElements": 4,
  51. "first": true,
  52. "empty": false
  53. }

剩下可以自己测试。postman测试样例及源码