Spring整合MongoDB
官方文档地址:https://docs.spring.io/spring-data/mongodb/docs/3.1.3/reference/html/#introduction
一、 Spring整合MongoDB
1、依赖
<!--mongo-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.1.1</version>
</dependency>
将Spring的版本更改为 5.3.3: <spring.framework.version>5.3.3</spring.framework.version>
若springboot版本为2.4.2,则Spring版本就是 5.3.3
2、将MongoClient交给Spring IOC容器管理
MongoConfig.java:
@Configuration
public class MongoConfig {
@Bean
public MongoClient mongoClient() {
// 使用更高级的配置MongoClientSettings(请注意,这些不是建议值)
// MongoClientSettings settings = MongoClientSettings.builder()
// .applyConnectionString(new ConnectionString("mongodb://127.0.0.1:37017/db_name"))
// .applyToConnectionPoolSettings(builder -> ConnectionPoolSettings.builder()
// .maxConnectionLifeTime(10, TimeUnit.SECONDS)
// .maxWaitTime(15, TimeUnit.SECONDS)
// .maxConnectionIdleTime(30, TimeUnit.SECONDS)
// .maintenanceFrequency(10, TimeUnit.SECONDS)
// .maintenanceInitialDelay(11, TimeUnit.SECONDS)
// .minSize(10)
// .maxSize(20)
// .build())
// .build();
// return MongoClients.create(settings);
return MongoClients.create("mongodb://127.0.0.1:37017/db_name");
}
// @Bean
// public MongoDatabaseFactory mongoDatabaseFactory() {
// return new SimpleMongoClientDatabaseFactory(mongoClient(), "db_name");
// }
// @Bean
// public MongoTemplate mongoTemplate() {
// return new MongoTemplate(mongoDatabaseFactory());
// }
@Bean
public MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoClient(),"db_name");
}
}
3、简单使用示例
@Autowired
private MongoTemplate mongoTemplate;
@Test
void mongoTest() {
Map<String, Object> record = new HashMap<>(4);
record.put("_id", "1");
record.put("name", "hello mongo");
// 插入
Map<String, Object> result = mongoTemplate.insert(record, "cf_products");
// 查询
List<Map> cfProductsMapList = mongoTemplate.findAll(Map.class,"cf_products");
}
数据:
> db.cf_products.find().pretty()
{ "_id" : "1", "name" : "hello mongo" }
二、SpringBoot整合MongoDB
Springboot版本为2.4.2
1、依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.4.2</version>
</dependency>
2、application.properties中配置连接信息
#mongodb://user:pwd@ip1:port1,ip2:port2/database
spring.data.mongodb.uri=mongodb://127.0.0.1:37017/db_name
3、简单使用示例
@Autowired
private MongoTemplate mongoTemplate;
@Test
void mongoTest() {
Map<String, Object> record = new HashMap<>(4);
record.put("_id", "1");
record.put("name", "hello mongo");
// 插入
Map<String, Object> result = mongoTemplate.insert(record, "cf_products");
// 查询
List<Map> cfProductsMapList = mongoTemplate.findAll(Map.class,"cf_products");
}
MongoTeplate简介
org.springframework.data.mongodb.core.MongoTemplate
MongoTemplate是Spring对MongoDB支持的核心,并且是线程安全的,可以在多个实例之间复用。
提供了创建,更新,删除和查询MongoDB的快捷操作,并提供了 domain 对象和 mongoDB document之间的映射。
MongoDB文档和域类之间的映射是通过委托MongoConverter接口的实现来完成的。Spring提供了MappingMongoConverter实现,但您也可以编写自己的转换器
MongoTemplate进行CRUD操作:
1、插入
// 保存对象到mongodb
mongoTemplate.save(user);
mongoTemplate.insert(user);
// 根据集合名称保存list到mongodb
mongoTemplate.save(list,"mongodb_user");
mongoTemplate.insert(list,"mongodb_user");
2、查询
Query query = Query.query(Criteria.where("name").is("yang"));
mongoTemplate.find(query,User.class,"mongodb_user");
// 查询全部
mongoTemplate.findAll(User.class,"mongodb_user");
// 分页查询
Pageable pageable = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("date")));
Query query = new Query().with(pageable);
mongoTemplate.find(query, User.class,"mongodb_user");
3、更新
// 查询不存在则插入,存在则更新
Query query = Query.query(Criteria.where("video_id").is(albumId));
Update update = Update.update("trace_id", MDCUtil.getTraceId())
.set("update_time", new Date())
.set("album_id", albumId)
.set("video_id", videoId)
.set("origin_data", originData);
mongoTemplate.upsert(query, update, collectionName);
4、删除
// 根据条件删除
mongoTemplate.remove(query);
批处理
注意:查询使用 _id,或者给查询条件字段创建索引
批处理模式:
/**
* Mode for bulk operation.
**/
enum BulkMode {
/** 按顺序执行批量操作。第一个错误出现时将取消处理. */
ORDERED,
/** 并行执行批量操作,出现错误将继续处理. */
UNORDERED
};
批量upset:
List<Pair<Query, Update>> pairList = new ArrayList<>();
// 入MongoDB临时库
for (AlbumContent albumContent : albumContents) {
String albumId = albumContent.getCover_id();
String originData = JacksonUtil.toString(albumContent);
// 查询不存在则插入,存在则更新
Query query = Query.query(Criteria.where("_id").is(albumId));
Update update = Update.update("trace_id", MDCUtil.getTraceId())
.set("_id", albumId)
.set("album_id", albumId)
.set("origin_data", originData);
.set("update_time", new Date())
Pair<Query, Update> pair = Pair.of(query, update);
pairList.add(pair);
}
// 批量upset
BulkOperations bulkOperations = mongoTemplate.bulkOps(BulkOperations.BulkMode.ORDERED, collectionName);
bulkOperations.upsert(pairList);
BulkWriteResult bulkWriteResult = bulkOperations.execute();
分页查询:
Query query = new Query();
query.addCriteria(new Criteria());
long count = mongoTemplate.count(query, collName);
// 每页查询20条
int pageSize = 20;
// 总页数
long num = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
// 执行分页查询
int pageNum = 1;
while (pageNum <= num) {
query.skip((pageNum - 1) * pageSize);
query.limit(pageSize);
pageNum++;
List<Map> datas = mongoTemplate.find(query, Map.class, ablumCollName);
for (Map<String, Object> data : datas) {
// 数据业务处理
...
}
}
如何_id在映射层中处理字段
MongoDB要求您有一个_id用于所有文档的字段。如果不提供,驱动程序将为分配ObjectId一个生成的值。
当您使用时MappingMongoConverter,某些规则将控制Java类中的属性如何映射到此_id字段:
① 用@Id(org.springframework.data.annotation.Id)注释的属性或字段映射到该_id字段。
② 没有注释但已命名的属性或字段id映射到该_id字段
问题总结:
1、Exception authenticating MongoCredential
Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='crawler_rw', source='admin', password=<hidden>, mechanismProperties=<hidden>};
nested exception is com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='crawler_rw', source='admin', password=<hidden>, mechanismProperties=<hidden>}
原因,mongo.url没有指定数据库,导致使用默认的数据库admin
解决方案:
mongo.url带上数据库名称 :mongodb://user:pwd@ip1:port1,ip2:port2/database
END.