赞
踩
最近项目中有使用到Mongodb,通过学习相关API了解,Spring boot中提供了 `MongoTemplate`操作数据,可以实现大部分的业务场景,但每增加一个Collection业务对象就要增加对应的 `MongoTemplate`及对应的方法,例如分页这种通用的操作,基于提高代码复用效率(懒~)考虑,自己封装一个通用的Repository。
- 添加依赖,使用的Springboot 2.7.10
<!-- Mongodb 依赖 MongoTemplate --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- hutool--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.16</version> </dependency>
- Mongodb基础配置,去除插入数据时保存的_class字段
@Configuration public class MongoConfig { @Resource private MongoDatabaseFactory mongoDatabaseFactory; @Resource private MongoMappingContext mongoMappingContext; @Bean public MappingMongoConverter mappingMongoConverter() { mongoMappingContext.setAutoIndexCreation(true); mongoMappingContext.afterPropertiesSet(); DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDatabaseFactory); MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext); // 此处是去除插入数据库的 _class 字段 converter.setTypeMapper(new DefaultMongoTypeMapper(null)); return converter; } }
- 定义IMongoRepository公共接口,使用@NoRepositoryBean表示不需要在初始时创建实例。
@NoRepositoryBean public interface IMongoRepository<T, ID extends Serializable> extends MongoRepository<T,ID> { /** * 创建 * * @param entity 新增内容 * @return 已创建的内容 */ public T create(T entity); /** * 编辑 * * @param id ID * @param entity 编辑的内容 * @return 编辑后的内容 */ public T update(ID id, T entity); /** * 删除 * * @param ids 待删除的ID * @return 删除的组件ID集合 */ public List<ID> delete(Collection<ID> ids); /** * 根据ID查询 * * @param id id * @return 组件 */ public T getOne(ID id); /** * 分页查询 * * @param entity 查询条件 * @param pageRequest 分页信息 * @return 分页列表 */ public Page<T> pageList(T entity, PageRequest pageRequest); }
- 定义IMongoRepository的实现类
public class BaseMongoRepository<T, ID extends Serializable> extends SimpleMongoRepository<T, ID> implements IMongoRepository<T, ID> { protected final MongoOperations mongoOperations; protected final MongoEntityInformation<T, ID> entityInformation; public BaseMongoRepository(MongoEntityInformation<T, ID> metadata, MongoOperations mongoOperations) { super(metadata, mongoOperations); this.mongoOperations = mongoOperations; this.entityInformation = metadata; } protected Class<T> getEntityClass() { return entityInformation.getJavaType(); } @Override public T create(T entity) { return this.save(entity); } @Override public T update(ID id, T entity) { T t1 = this.getOne(id); BeanUtil.copyProperties(entity, t1, CopyOptions.create().ignoreNullValue()); return this.save(t1); } @Override public List<ID> delete(Collection<ID> ids) { ids.forEach(id -> { T t = this.getOne(id); this.delete(t); }); return (List<ID>) ids; } @SneakyThrows @Override public T getOne(ID id) { return this.findById(id) .orElseThrow(() -> new Exception("未找到记录:" + id)); } @Override public Page<T> pageList(T entity, PageRequest pageRequest) { return this.findAll(Example.of(entity), pageRequest); } }
- 在MongoConfig类上使用@EnableMongoRepositories将自定义的BaseMongoRepository替换原有SimpleMongoRepository
@EnableMongoRepositories(repositoryBaseClass = BaseMongoRepository.class, basePackages = {"com.learning.mongodb.crud.repository"})
@Configuration
public class MongoConfig {...}
- 验证
Book.java
@Document(collection = "Books")
@Data
public class Book {
@Id
private ObjectId id;
private String name;
private Double price;
}
BookRepository.java
public interface BookRepository extends IMongoRepository<Book, ObjectId> {
}
BookController.java
@Resource
private BookRepository bookRepository;
@PostMapping
public Book add(@RequestBody Book book) {
return this.bookRepository.save(book);
}
@GetMapping
public List<Book> books() {
return bookRepository.findAll();
}
@GetMapping(value = "/{id}")
public Book book(@PathVariable(name = "id") String id) {
return bookRepository.getOne(new ObjectId(id));
}
curl测试用例
添加书籍
curl --location 'http://localhost:8080/book' \
--header 'Content-Type: application/json' \
--data '{
"name":"C Primer Plus 第6版",
"price":53.9
}'
获取书籍
curl http://localhost:8080/book
总结
虽然Spring boot也提供了Mongodb JPA的操作类MongoRepository,但面对复杂操作时,没有MongoTemplate操作灵活,两个可以配合使用,取长补短。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。