Spring Boot 集成 MongoDB 完整指南

1. MongoDB 核心概念

1.1 什么是 MongoDB

MongoDB 是一个基于分布式文件存储的 NoSQL 数据库,采用文档型数据模型,使用 BSON(Binary JSON)格式存储数据。

1.2 核心名词解析

  • 文档(Document) :MongoDB 中的基本数据单元,类似 JSON 对象
  • 集合(Collection) :文档的容器,类似关系型数据库中的表
  • 数据库(Database) :集合的物理容器
  • _id:每个文档的唯一标识符
  • BSON:Binary JSON,MongoDB 的二进制存储格式

2. MongoDB 特点与优劣对比

2.1 主要特点

  • 文档型数据模型,灵活的数据结构
  • 高性能读写操作
  • 水平扩展能力强(分片)
  • 丰富的查询语言
  • 自动故障转移

2.2 vs 关系型数据库

特性MongoDB关系型数据库
数据模型文档模型表模型
schema动态固定
扩展方式水平扩展垂直扩展
事务支持4.0+ 支持多文档事务完全支持
关联查询有限强大
适用场景大数据、快速迭代复杂事务、强一致性

3. Spring Boot 集成 MongoDB

3.1 添加依赖

xml

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

3.2 配置文件

application.yml

yaml

spring:
  data:
    mongodb:
      uri: mongodb://localhost:27017/testdb
      # 或者使用以下格式
      # host: localhost
      # port: 27017
      # database: testdb
      # username: user
      # password: pass

3.3 实体类映射

java

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.time.LocalDateTime;
import java.util.List;

@Document(collection = "users")
public class User {
    @Id
    private String id;
    
    private String username;
    
    private Integer age;
    
    @Field("email_address")
    private String emailAddress;
    
    private List<String> hobbies;
    
    private LocalDateTime createTime;
    
    // 构造方法
    public User() {}
    
    public User(String username, Integer age, String emailAddress) {
        this.username = username;
        this.age = age;
        this.emailAddress = emailAddress;
        this.createTime = LocalDateTime.now();
    }
    
    // Getter 和 Setter
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
    
    public String getEmailAddress() { return emailAddress; }
    public void setEmailAddress(String emailAddress) { this.emailAddress = emailAddress; }
    
    public List<String> getHobbies() { return hobbies; }
    public void setHobbies(List<String> hobbies) { this.hobbies = hobbies; }
    
    public LocalDateTime getCreateTime() { return createTime; }
    public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; }
}

3.4 Repository 接口

java

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;

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

@Repository
public interface UserRepository extends MongoRepository<User, String> {
    
    // 方法名自动推导查询
    Optional<User> findByUsername(String username);
    
    List<User> findByAgeGreaterThan(Integer age);
    
    List<User> findByEmailAddressContaining(String domain);
    
    // 自定义查询
    @Query("{ 'age' : { $gte: ?0, $lte: ?1 } }")
    List<User> findUsersByAgeBetween(Integer minAge, Integer maxAge);
    
    @Query("{ 'hobbies' : { $in: ?0 } }")
    List<User> findByHobbiesIn(List<String> hobbies);
}

3.5 自定义 Repository 实现

java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class UserCustomRepositoryImpl implements UserCustomRepository {
    
    @Autowired
    private MongoTemplate mongoTemplate;
    
    @Override
    public List<User> findUsersByComplexCriteria(String username, Integer minAge, List<String> hobbies) {
        Query query = new Query();
        
        if (username != null) {
            query.addCriteria(Criteria.where("username").regex(username, "i"));
        }
        
        if (minAge != null) {
            query.addCriteria(Criteria.where("age").gte(minAge));
        }
        
        if (hobbies != null && !hobbies.isEmpty()) {
            query.addCriteria(Criteria.where("hobbies").in(hobbies));
        }
        
        return mongoTemplate.find(query, User.class);
    }
    
    @Override
    public void updateUserEmail(String userId, String newEmail) {
        Query query = new Query(Criteria.where("id").is(userId));
        Update update = new Update().set("emailAddress", newEmail);
        mongoTemplate.updateFirst(query, update, User.class);
    }
}

// 自定义 Repository 接口
public interface UserCustomRepository {
    List<User> findUsersByComplexCriteria(String username, Integer minAge, List<String> hobbies);
    void updateUserEmail(String userId, String newEmail);
}

// 扩展主 Repository 接口
public interface UserRepository extends MongoRepository<User, String>, UserCustomRepository {
    // 原有方法...
}

3.6 Service 层

java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    public User createUser(User user) {
        return userRepository.save(user);
    }
    
    public Optional<User> getUserById(String id) {
        return userRepository.findById(id);
    }
    
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
    
    public List<User> getUsersByAgeRange(Integer minAge, Integer maxAge) {
        return userRepository.findUsersByAgeBetween(minAge, maxAge);
    }
    
    public User updateUser(User user) {
        return userRepository.save(user);
    }
    
    public void deleteUser(String id) {
        userRepository.deleteById(id);
    }
    
    public List<User> searchUsers(String username, Integer minAge, List<String> hobbies) {
        return userRepository.findUsersByComplexCriteria(username, minAge, hobbies);
    }
}

3.7 Controller 层

java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

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

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User savedUser = userService.createUser(user);
        return ResponseEntity.ok(savedUser);
    }
    
    @GetMapping
    public ResponseEntity<List<User>> getAllUsers() {
        List<User> users = userService.getAllUsers();
        return ResponseEntity.ok(users);
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable String id) {
        Optional<User> user = userService.getUserById(id);
        return user.map(ResponseEntity::ok)
                  .orElse(ResponseEntity.notFound().build());
    }
    
    @GetMapping("/search")
    public ResponseEntity<List<User>> searchUsers(
            @RequestParam(required = false) String username,
            @RequestParam(required = false) Integer minAge,
            @RequestParam(required = false) List<String> hobbies) {
        
        List<User> users = userService.searchUsers(username, minAge, hobbies);
        return ResponseEntity.ok(users);
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable String id, @RequestBody User user) {
        user.setId(id);
        User updatedUser = userService.updateUser(user);
        return ResponseEntity.ok(updatedUser);
    }
    
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable String id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
}

3.8 配置类(可选)

java

import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.EnableMongoAuditing;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@Configuration
@EnableMongoRepositories(basePackages = "com.example.repository")
@EnableMongoAuditing
public class MongoConfig {
    // 启用审计功能,自动填充创建时间、更新时间等字段
}

4. 高级特性

4.1 审计功能

java

import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.mongodb.core.mapping.Document;

import java.time.LocalDateTime;

@Document
public class AuditableEntity {
    
    @CreatedDate
    private LocalDateTime createdDate;
    
    @LastModifiedDate
    private LocalDateTime lastModifiedDate;
    
    // getter and setter...
}

4.2 索引配置

java

import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.index.CompoundIndex;

// 在实体类上添加索引注解
@Document(collection = "users")
@CompoundIndex(name = "username_email", def = "{'username': 1, 'emailAddress': 1}")
public class User {
    
    @Indexed(unique = true)
    private String username;
    
    @Indexed
    private String emailAddress;
    
    // 其他字段...
}

5. 事务支持(MongoDB 4.0+)

java

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class TransactionalUserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Transactional
    public void transferData(String fromUserId, String toUserId) {
        // 这里可以执行多个 MongoDB 操作,它们将在同一个事务中
        User fromUser = userRepository.findById(fromUserId).orElseThrow();
        User toUser = userRepository.findById(toUserId).orElseThrow();
        
        // 业务逻辑...
        
        userRepository.save(fromUser);
        userRepository.save(toUser);
    }
}

6. 总结

Spring Boot 集成 MongoDB 提供了简洁而强大的数据访问能力:

  • 简单配置:通过配置文件快速连接 MongoDB
  • 自动映射:注解驱动的实体映射
  • 灵活查询:方法名推导、@Query 注解、MongoTemplate
  • 事务支持:MongoDB 4.0+ 支持多文档事务
  • 扩展性强:易于集成复杂查询和业务逻辑
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

andywangzhen_ai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值