Spring Boot MongoDB 使用技巧

2025-12-12 0 164

Spring Boot MongoDB 使用技巧

1. 基础配置

1.1 依赖配置


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

1.2 连接配置

# application.yml 配置示例
spring:
  data:
    mongodb:
      uri: mongodb://username:password@host:port/database?authSource=admin
      # 或者使用分开的配置
      # host: localhost
      # port: 27017
      # database: testdb
      # username: admin
      # password: password
      # authentication-database: admin

1.3 多数据源配置

@Configuration
public class MultipleMongoConfig {

    @Bean(name = \"mongoTemplate1\")
    @Primary
    public MongoTemplate mongoTemplate1(MongoDatabaseFactory factory1) {
        return new MongoTemplate(factory1);
    }

    @Bean(name = \"mongoTemplate2\")
    public MongoTemplate mongoTemplate2(@Qualifier(\"mongoDbFactory2\") MongoDatabaseFactory factory2) {
        return new MongoTemplate(factory2);
    }

    // 配置多个MongoDatabaseFactory
}

2. 实体映射技巧

2.1 基础映射注解

@Document(collection = \"users\")  // 指定集合名
public class User {
    @Id  // 主键
    private String id;
    
    @Field(\"user_name\")  // 自定义字段名
    private String username;
    
    @Indexed(unique = true)  // 索引配置
    private String email;
    
    @Transient  // 不持久化到数据库
    private String tempField;
    
    // getters and setters
}

2.2 复杂对象映射

@Document
public class Order {
    @Id
    private String id;
    
    private User user;  // 嵌入文档
    
    private List items;  // 数组/列表
    
    @DBRef  // 引用其他集合的文档
    private Customer customer;
    
    // getters and setters
}

2.3 时间处理

@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime createdAt;

// 自动填充时间
@PrePersist
public void prePersist() {
    createdAt = LocalDateTime.now();
}

3. 数据访问层设计

3.1 Repository接口方式

// 基础Repository
public interface UserRepository extends MongoRepository {
    // 自动生成查询方法
    Optional findByUsername(String username);
    List findByAgeGreaterThan(int age);
    
    // 自定义查询
    @Query(\"{ \'email\' : ?0, \'status\' : ?1 }\")
    List findByEmailAndStatus(String email, String status);
}

3.2 MongoTemplate方式

@Service
public class UserService {
    
    @Autowired
    private MongoTemplate mongoTemplate;
    
    public User findUserByUsername(String username) {
        Query query = new Query(Criteria.where(\"username\").is(username));
        return mongoTemplate.findOne(query, User.class);
    }
    
    public void saveUser(User user) {
        mongoTemplate.save(user);
    }
}

4. 高级查询技巧

4.1 复杂条件查询

// 使用Criteria构建复杂查询
Criteria criteria = new Criteria();
criteria.and(\"age\").gt(18).lte(60);
criteria.and(\"status\").is(\"active\");
criteria.orOperator(
    Criteria.where(\"role\").is(\"admin\"),
    Criteria.where(\"permissions\").in(\"WRITE\", \"DELETE\")
);
Query query = Query.query(criteria);
List users = mongoTemplate.find(query, User.class);

4.2 聚合查询

Aggregation aggregation = Aggregation.newAggregation(
    Aggregation.match(Criteria.where(\"status\").is(\"active\")),
    Aggregation.group(\"department\").count().as(\"employeeCount\"),
    Aggregation.sort(Sort.Direction.DESC, \"employeeCount\")
);

AggregationResults results = mongoTemplate.aggregate(
    aggregation, \"employees\", DepartmentStats.class);

4.3 分页查询

Pageable pageable = PageRequest.of(0, 10, Sort.by(\"createdAt\").descending());
Query query = new Query().with(pageable);
long count = mongoTemplate.count(query, User.class);
List users = mongoTemplate.find(query, User.class);
Page userPage = new PageImpl(users, pageable, count);

5. 索引优化

5.1 索引注解配置

@Document
@CompoundIndex(name = \"idx_name_age\", def = \"{ \'name\': 1, \'age\': -1 }\")
public class User {
    @Indexed(unique = true, sparse = true)  // 唯一索引,稀疏索引
    private String email;
    
    @Indexed(expireAfterSeconds = 3600)  // TTL索引,1小时后过期
    private Date lastLoginTime;
}

5.2 运行时索引管理

// 创建索引
mongoTemplate.indexOps(User.class).ensureIndex(
    new Index().on(\"username\", Direction.ASC).unique()
);

// 删除索引
mongoTemplate.indexOps(User.class).dropIndex(\"idx_name_age\");

// 查看所有索引
List indexes = mongoTemplate.indexOps(User.class).getIndexInfo();

6. 事务支持

6.1 启用事务

@Configuration
@EnableMongoRepositories
public class MongoConfig extends AbstractMongoClientConfiguration {
    
    @Bean
    @Override
    public MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
        return new MongoTransactionManager(dbFactory);
    }
}

6.2 使用事务

@Service
public class OrderService {
    
    @Autowired
    private OrderRepository orderRepository;
    
    @Autowired
    private InventoryService inventoryService;
    
    @Transactional  // Spring事务注解
    public void createOrder(Order order) {
        // 保存订单
        orderRepository.save(order);
        
        // 更新库存
        inventoryService.reduceInventory(order.getItems());
    }
}

7. 性能优化技巧

7.1 字段投影

// 只返回需要的字段
Query query = new Query(Criteria.where(\"status\").is(\"active\"));
query.fields().include(\"username\").include(\"email\").exclude(\"password\");
List users = mongoTemplate.find(query, User.class);

7.2 批量操作

// 批量插入
List users = new ArrayList();
// 添加用户...
mongoTemplate.insert(users, User.class);

// 批量更新
BulkOperations operations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, User.class);
for (User user : usersToUpdate) {
    Update update = new Update().set(\"status\", user.getStatus());
    operations.updateOne(Query.query(Criteria.where(\"_id\").is(user.getId())), update);
}
operations.execute();

7.3 缓存查询结果

@Service
public class CacheUserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Cacheable(value = \"users\", key = \"#username\")
    public User findByUsername(String username) {
        return userRepository.findByUsername(username).orElse(null);
    }
}

8. 错误处理与日志

8.1 异常处理

@ControllerAdvice
public class MongoExceptionHandler {
    
    @ExceptionHandler(DuplicateKeyException.class)
    public ResponseEntity handleDuplicateKey(DuplicateKeyException ex) {
        ErrorResponse error = new ErrorResponse(\"Duplicate key error\", ex.getMessage());
        return new ResponseEntity(error, HttpStatus.CONFLICT);
    }
    
    @ExceptionHandler(MongoException.class)
    public ResponseEntity handleMongoException(MongoException ex) {
        ErrorResponse error = new ErrorResponse(\"MongoDB error\", ex.getMessage());
        return new ResponseEntity(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

8.2 慢查询日志配置

logging:
  level:
    org.springframework.data.mongodb.core.MongoTemplate: DEBUG  # 开启MongoTemplate日志

9. 测试技巧

9.1 集成测试

@SpringBootTest
@DataMongoTest  // 只加载MongoDB相关配置
public class UserRepositoryTest {
    
    @Autowired
    private UserRepository userRepository;
    
    @MockBean  // 模拟其他依赖
    private EmailService emailService;
    
    @Test
    public void testFindByUsername() {
        // 测试代码
    }
}

9.2 使用嵌入式MongoDB

<dependency>
    <groupId>de.flapdoodle.embed</groupId>
    <artifactId>de.flapdoodle.embed.mongo</artifactId>
    <scope>test</scope>
</dependency>

10. 最佳实践总结

  1. 合理设计文档结构:优先使用嵌入文档,避免过度使用DBRef
  2. 索引策略:为常用查询字段添加索引,但不要过度索引
  3. 事务使用:仅在必要时使用事务,因为会影响性能
  4. 连接池配置:根据应用规模调整连接池参数
  5. 分页查询:避免深度分页,考虑使用游标或时间戳分页
  6. 监控与调优:使用MongoDB Compass等工具监控查询性能
  7. 安全配置:生产环境启用认证、TLS加密
  8. 备份策略:定期备份数据,配置适当的复制集

这些技巧涵盖了Spring Boot与MongoDB集成的各个方面,从基础配置到高级用法和性能优化,希望对你有所帮助!

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 编程相关 Spring Boot MongoDB 使用技巧 https://www.zuozi.net/35615.html

常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务