Spring Boot整合Mongo DB
跟着鸟哥学 Spring Boot整合Mongo DB
1. 简单增删查改
新建一个Spring Boot项目,版本为2.1.3.RELEASE,并引入如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
然后mongodb创建数据库,properties.yml配置
spring:
data:
mongodb:
host: localhost
port: 27017
database: user
创建实体User
@Document(collection = "user")
@Data
public class User {
@Id
private String id;
private String name;
private Integer age;
private String description;
// get set 略
}
@Document(collection = "user")
表明这是一个文档对象,名称为user
,对应Mongo DB里的user表。@Id
标注主键字段,String类型的主键值在插入的时候Mongo DB会帮我们自动生成。如果对象中的某个属性为非表字段,可以使用注解@Transient
进行排除。
准备好这些后,我们开始编写一些简单的增删改查样例
创建一个UserDao接口:
@Repository
public interface UserDao extends MongoRepository<User, String> {
}
接口继承自MongoRepository
,泛型分别为实体对象和主键类型。通过继承MongoRepository
,UserDao
包含了一些增删改查的方法,如下图所示:
接着编写UserService
@Service
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
public class UserService {
private final UserDao userDao;
private final MongoTemplate template;
public List<User> getUsers() {
return userDao.findAll();
}
public Optional<User> getUser(String id) {
return this.userDao.findById(id);
}
/**
* 新增和修改都是 save方法,
* id 存在为修改,id 不存在为新增
*/
public User createUser(User user) {
user.setId(null);
return userDao.save(user);
}
public void deleteUser(String id) {
this.userDao.findById(id)
.ifPresent(user -> this.userDao.delete(user));
}
public void updateUser(String id, User user) {
this.userDao.findById(id)
.ifPresent(
u -> {
u.setName(user.getName());
u.setAge(user.getAge());
u.setDescription(user.getDescription());
this.userDao.save(u);
}
);
}
}
上面我们编写了基本的增删改查样例,新增和修改都是通过save
方法完成的,当主键存在时则为修改,主键不存在则为新增。
最后编写一个RESTful的UserController(为了方便,没有对参数进行校验):
@RestController
@RequestMapping("user")
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
public class UserController {
private final UserService userService;
@GetMapping
public List<User> getUsers() {
return userService.getUsers();
}
@PostMapping
public User createUser(User user) {
return userService.createUser(user);
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable String id) {
userService.deleteUser(id);
}
@PutMapping("/{id}")
public void updateUser(@PathVariable String id, User user) {
userService.updateUser(id, user);
}
/**
* 根据用户 id查找
* 存在返回,不存在返回 null
*/
@GetMapping("/{id}")
public User getUser(@PathVariable String id) {
return userService.getUser(id).orElse(null);
}
}
启动项目,使用postman来测试接口的可用性。
2.多条件查询
修改userDao
其实UserDao
通过继承MongoRepository
已经具有了JPA的特性,我们可以通过方法名来构建多查询条件的SQL。比如通过用户的年龄段来查询和用户名和描述(模糊查询)查询用户的方法:
@Repository
public interface UserDao extends MongoRepository<User, String> {
/**
* 根据年龄段来查找
*
* @param from from
* @param to to
* @return List<User>
*/
List<User> findByAgeBetween(Integer from, Integer to);
/**
* 通过年龄段,用户名,描述(模糊查询)
*
* @param from from
* @param to to
* @param name name
* @param description description
* @return List<User>
*/
List<User> findByAgeBetweenAndNameEqualsAndDescriptionIsLike(Integer from, Integer to, String name, String description);
}
在输入findBy
后,IDEA会根据实体对象的属性和SQL的各种关键字自动组合提示:
修改userSerivce
userSerivce加入以下两个方法
public List<User> findByAgeBetween(Integer from, Integer to){
return this.userDao.findByAgeBetween(from,to);
}
public List<User> findByAgeBetweenAndNameEqualsAndDescriptionIsLike(Integer from, Integer to, String name, String description){
return this.userDao.findByAgeBetweenAndNameEqualsAndDescriptionIsLike(from,to,name,description);
}
修改userController
@GetMapping("/findByAgeBetween")
public List<User> findByAgeBetween(Integer from, Integer to){
return this.userService.findByAgeBetween(from,to);
}
@GetMapping("/findByAgeBetweenAndNameEqualsAndDescriptionIsLike")
public List<User> findByAgeBetweenAndNameEqualsAndDescriptionIsLike(Integer from, Integer to, String name, String description){
return this.userService.findByAgeBetweenAndNameEqualsAndDescriptionIsLike(from,to,name,description);
}
然后使用postMan测试
3. 排序与分页
排序和分页需要使用MongoTemplate
对象来完成,在UserService
里新增一个getUserByCondition
方法:
private final MongoTemplate template;
public Page<User> getUserByCondition(int size, int page, User user) {
Query query = new Query();
Criteria criteria = new Criteria();
//根据名字查找
if (!StringUtils.isEmpty(user.getName())) {
criteria.and("name").is(user.getName());
}
//根据描述查找
if (!StringUtils.isEmpty(user.getDescription())) {
criteria.and("description").regex(user.getDescription());
}
query.addCriteria(criteria);
//根据年龄降序
Sort sort =Sort.by(Sort.Direction.DESC,"age");
Pageable pageable = PageRequest.of(page, size, sort);
List<User> users = template.find(query.with(pageable), User.class);
return PageableExecutionUtils.getPage(users, pageable, () -> template.count(query, User.class));
}
size
表示每页显示的条数,page
表示当前页码数,0表示第一页。上面的方法通过name
和description
(模糊查询)来查询用户分页信息,并且查询结果使用age
字段降序排序。方法返回Page
对象。
在UserController
里添加:
@GetMapping("/condition")
public Page<User> getUserByCondition(int size, int page, User user) {
return userService.getUserByCondition(size, page, user);
}
4 .postman测试模版
{
"info": {
"_postman_id": "7516008d-d257-4f45-a8d1-0c56f6e45880",
"name": "MongoDB",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "createUser",
"request": {
"method": "POST",
"header": [],
"url": {
"raw": "127.0.0.1:8080/user?name=yz&description=mongodb&age=20",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8080",
"path": [
"user"
],
"query": [
{
"key": "name",
"value": "yz"
},
{
"key": "description",
"value": "mongodb"
},
{
"key": "age",
"value": "20"
}
]
}
},
"response": []
},
{
"name": "getUser",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "127.0.0.1:8080/user",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8080",
"path": [
"user"
]
}
},
"response": []
},
{
"name": "getUserById",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "127.0.0.1:8080/user/612122fb75da162aac4dee19",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8080",
"path": [
"user",
"612122fb75da162aac4dee19"
]
}
},
"response": []
},
{
"name": "updateUser",
"request": {
"method": "POST",
"header": [],
"url": {
"raw": "127.0.0.1:8080/user?name=ajiang&description=mongodb&age=19",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8080",
"path": [
"user"
],
"query": [
{
"key": "name",
"value": "ajiang"
},
{
"key": "description",
"value": "mongodb"
},
{
"key": "age",
"value": "19"
}
]
}
},
"response": []
},
{
"name": "deleteUserById",
"request": {
"method": "DELETE",
"header": [],
"url": {
"raw": "127.0.0.1:8080/user/612122fb75da162aac4dee19",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8080",
"path": [
"user",
"612122fb75da162aac4dee19"
]
}
},
"response": []
},
{
"name": "findByAgeBetween",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "127.0.0.1:8080/user/findByAgeBetween?from=12&to=20",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8080",
"path": [
"user",
"findByAgeBetween"
],
"query": [
{
"key": "from",
"value": "12"
},
{
"key": "to",
"value": "20"
}
]
}
},
"response": []
},
{
"name": "findByAgeBetweenAndNameEqualsAndDescriptionIsLike",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "127.0.0.1:8080/user/findByAgeBetweenAndNameEqualsAndDescriptionIsLike?from=12&to=20&name=ajiang&description=mongodb",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8080",
"path": [
"user",
"findByAgeBetweenAndNameEqualsAndDescriptionIsLike"
],
"query": [
{
"key": "from",
"value": "12"
},
{
"key": "to",
"value": "20"
},
{
"key": "name",
"value": "ajiang"
},
{
"key": "description",
"value": "mongodb"
}
]
}
},
"response": []
},
{
"name": "condition",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "127.0.0.1:8080/user/condition?size=10&page=0&name=yz",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8080",
"path": [
"user",
"condition"
],
"query": [
{
"key": "size",
"value": "10"
},
{
"key": "page",
"value": "0"
},
{
"key": "name",
"value": "yz"
},
{
"key": "",
"value": "",
"disabled": true
}
]
}
},
"response": []
}
]
}