Skip to content

MongoDB Plugin

对应模块: io.gitee.lcgyl:lcgyl-mongo-plugin

基于 Reactive Streams 的 MongoDB 响应式数据访问层,提供类似于 JPA 的 Repository 编程体验。

✨ 特性

  • 响应式驱动 - 基于 mongodb-driver-reactivestreams 全异步非阻塞
  • Repository 模式 - 提供 ReactiveMongoRepository 接口
  • 动态数据源 - 支持多 MongoDB 实例动态切换
  • 审计功能 - 自动填充 @CreatedDate, @LastModifiedDate
  • 事务支持 - 支持 MongoDB 4.0+ 多文档事务

🚀 快速开始

依赖引入

gradle
implementation 'io.gitee.lcgyl:lcgyl-mongo-plugin:2.2.0'

配置

yaml
lcgyl:
  mongo:
    uri: mongodb://localhost:27017/mydb
    # 或详细配置
    host: localhost
    port: 27017
    database: mydb
    username: admin
    password: secret
    auth-database: admin

实体定义

java
@Document("users")
@Data
public class User {
    @Id
    private String id;
    
    @Indexed(unique = true)
    private String username;
    
    private String email;
    
    @Field("profile")
    private UserProfile profile;
    
    @CreatedDate
    private LocalDateTime createdAt;
    
    @LastModifiedDate
    private LocalDateTime updatedAt;
}

@Data
public class UserProfile {
    private String avatar;
    private String bio;
    private List<String> tags;
}

Repository 接口

java
public interface UserRepository extends ReactiveMongoRepository<User, String> {
    
    Flux<User> findByUsername(String username);
    
    Mono<User> findByEmail(String email);
    
    @Query("{ 'profile.tags': ?0 }")
    Flux<User> findByTag(String tag);
    
    Flux<User> findByCreatedAtBetween(LocalDateTime start, LocalDateTime end);
}

使用 Repository

java
@Service
public class UserService {
    
    @Inject
    private UserRepository userRepository;
    
    public Mono<User> createUser(CreateUserRequest request) {
        User user = new User();
        user.setUsername(request.getUsername());
        user.setEmail(request.getEmail());
        return userRepository.save(user);
    }
    
    public Flux<User> searchUsers(String tag) {
        return userRepository.findByTag(tag);
    }
    
    public Mono<Void> deleteUser(String id) {
        return userRepository.deleteById(id);
    }
}

MongoTemplate 高级查询

java
@Service
public class AdvancedQueryService {
    
    @Inject
    private ReactiveMongoTemplate mongoTemplate;
    
    // 复杂查询
    public Flux<User> searchUsers(UserSearchCriteria criteria) {
        Query query = new Query();
        
        if (criteria.getUsername() != null) {
            query.addCriteria(Criteria.where("username").regex(criteria.getUsername(), "i"));
        }
        if (criteria.getTags() != null) {
            query.addCriteria(Criteria.where("profile.tags").in(criteria.getTags()));
        }
        
        query.with(Sort.by(Sort.Direction.DESC, "createdAt"));
        query.skip(criteria.getOffset()).limit(criteria.getLimit());
        
        return mongoTemplate.find(query, User.class);
    }
    
    // 聚合查询
    public Flux<TagStats> getTagStats() {
        Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.unwind("profile.tags"),
            Aggregation.group("profile.tags").count().as("count"),
            Aggregation.sort(Sort.Direction.DESC, "count"),
            Aggregation.limit(10)
        );
        
        return mongoTemplate.aggregate(aggregation, "users", TagStats.class);
    }
    
    // 更新操作
    public Mono<UpdateResult> updateUserTags(String userId, List<String> tags) {
        Query query = Query.query(Criteria.where("_id").is(userId));
        Update update = new Update().set("profile.tags", tags);
        return mongoTemplate.updateFirst(query, update, User.class);
    }
}

事务支持

java
@Service
public class TransactionalService {
    
    @Inject
    private ReactiveMongoTemplate mongoTemplate;
    
    @Transactional
    public Mono<Void> transferCredits(String fromUserId, String toUserId, int amount) {
        return mongoTemplate.updateFirst(
                Query.query(Criteria.where("_id").is(fromUserId)),
                new Update().inc("credits", -amount),
                User.class)
            .then(mongoTemplate.updateFirst(
                Query.query(Criteria.where("_id").is(toUserId)),
                new Update().inc("credits", amount),
                User.class))
            .then();
    }
}

Released under the Apache License 2.0