spring:
mongodb:
maxSize: 100 # 允许的最大连接数。这些连接在空闲时将保留在池中。一旦池耗尽,任何需要连接的操作都将阻塞等待可用连接 默认: 100
minSize: 10 # 最小连接数。这些连接在空闲时将保留在池中,并且池将确保它至少包含这个最小数量 默认: 0
maxConnectionLifeTime: 0 # 池连接可以存活的最长时间。零值表示寿命没有限制。超过其生命周期的池连接将被关闭并在必要时由新连接替换
maxConnectionIdleTime: 5 # 池连接的最大空闲时间。零值表示对空闲时间没有限制。超过其空闲时间的池连接将被关闭并在必要时由新连接替换
maxWaitTime: 60000 # 默认最大连接时间120s;
one:
uri: mongodb://root:xx.12323@192.168.112.179:27072/${spring.mongodb.one.database}?authSource=admin&authMechanism=SCRAM-SHA-256
database: hc_test
# 上方为明确指定某个数据的用户进行连接
# 也可以使用admin 数据库中的用户进行连接 统一到admin 数据库进行认证
# admin 用户认证 url 写法: mongodb://账户:密码%40@ip:端口/数据库名?authSource=admin&authMechanism=SCRAM-SHA-1
two:
uri: mongodb://root:sx.123@192.168.118.179:27072/${spring.mongodb.two.database}?authSource=admin&authMechanism=SCRAM-SHA-256
database: nxyxx_qt_test
# 上方为明确指定某个数据的用户进行连接
# 也可以使用admin 数据库中的用户进行连接 统一到admin 数据库进行认证
# admin 用户认证 url 写法: mongodb://账户:密码%40@ip:端口/数据库名?authSource=admin&authMechanism=SCRAM-SHA-1
package org.example.config;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
* @program: sxsoft_operation_admin
* @ClassName DataSourceConfig
* @description:monogodb多数据源配置 非关系型数据库
* @author: 黄涛
* @create: 2022-10-08 15:41
* @Version 1.0
**/
@Configuration
public class MongoDBConfig {
/**
* 获取默认数据库属性配置
* @return
*/
@Primary
@Bean(name = "oneMongoProperties")
@ConfigurationProperties(prefix = "spring.mongodb.one")
public MongoProperties oneMongoProperties() {
return new MongoProperties();
}
/**
* 获取第二数据库属性配置
* @return
*/
@Bean(name = "twoMongoProperties")
@ConfigurationProperties(prefix = "spring.mongodb.two")
public MongoProperties twoMongoProperties() {
return new MongoProperties();
}
}
package org.example.config;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.SpringDataMongoDB;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import java.util.concurrent.TimeUnit;
/**
* 使用说明:
* 1、配置属性参数
* 2、配置模板
* 3、配置连接池
*/
@Configuration
@EnableMongoRepositories
public class MongoTemplateConfig {
//region 参数注入
@Value("${spring.mongodb.maxSize}")
private int maxSize;
@Value("${spring.mongodb.minSize}")
private int minSize;
@Value("${spring.mongodb.maxConnectionLifeTime}")
private int maxConnectionLifeTime;
@Value("${spring.mongodb.maxConnectionIdleTime}")
private int maxConnectionIdleTime;
@Value("${spring.mongodb.maxWaitTime}")
private int maxWaitTime;
//endregion
//region 1、属性参数配置
//默认数据库属性配置
private final MongoProperties oneMongoProperties;
//第二数据库属性配置
private final MongoProperties twoMongoProperties;
public MongoTemplateConfig(@Qualifier("oneMongoProperties") MongoProperties oneMongoProperties,
@Qualifier("twoMongoProperties") MongoProperties twoMongoProperties) {
this.oneMongoProperties = oneMongoProperties;
this.twoMongoProperties = twoMongoProperties;
}
//endregion
//region 2、模板配置
/**
* @Primary默认数据库模板/第一个数据库模板
* @return
*/
@Primary
@Bean(name = "oneMongotemplate")
public MongoTemplate oneMongotemplate(@Qualifier("oneMongoDatabaseFactory") MongoDatabaseFactory mongoDatabaseFactory) {
return getMongoTemplate(mongoDatabaseFactory);
// MongoDatabaseFactory mongoDatabaseFactory = new SimpleMongoClientDatabaseFactory(oneMongoProperties.getUri());
// return new MongoTemplate(mongoDatabaseFactory);
}
/**
* 第二数据库模板
* @return
*/
@Bean(name = "twoMongotemplate")
public MongoTemplate twoMongotemplate(@Qualifier("twoMongoDatabaseFactory") MongoDatabaseFactory mongoDatabaseFactory) {
return getMongoTemplate(mongoDatabaseFactory);
}
//endregion
//region 3、连接池配置
/**
* 第一数据库连接池配置
* @return
*/
@Bean
@Primary
public MongoDatabaseFactory oneMongoDatabaseFactory() {
return getSimpleMongoClientDatabaseFactory(oneMongoProperties);
}
/**
* 第二数据库连接池配置
* @return
*/
@Bean
public MongoDatabaseFactory twoMongoDatabaseFactory() {
return getSimpleMongoClientDatabaseFactory(twoMongoProperties);
}
/**
* 连接池工厂
* @param properties
* @return
*/
private SimpleMongoClientDatabaseFactory getSimpleMongoClientDatabaseFactory(MongoProperties properties){
MongoClientSettings.Builder builder = MongoClientSettings.builder();
builder.applyConnectionString(new ConnectionString(properties.getUri()));
builder.applyToConnectionPoolSettings(b -> {
b.maxSize(maxSize);
b.minSize(minSize);
b.maxConnectionLifeTime(maxConnectionLifeTime, TimeUnit.SECONDS);
b.maxConnectionIdleTime(maxConnectionIdleTime, TimeUnit.MINUTES);
b.maxWaitTime(maxWaitTime, TimeUnit.MILLISECONDS);
});
MongoClient mongoClient = MongoClients.create(builder.build(), SpringDataMongoDB.driverInformation());
return new SimpleMongoClientDatabaseFactory(mongoClient, properties.getDatabase());
}
/**
* 模板工厂
* @param mongoDatabaseFactory
* @return
*/
private MongoTemplate getMongoTemplate(MongoDatabaseFactory mongoDatabaseFactory){
MongoTemplate mongoTemplate = new MongoTemplate(mongoDatabaseFactory);
//去除保存实体时,spring data mongodb 自动添加的_class字段
MappingMongoConverter mongoMapping = (MappingMongoConverter) mongoTemplate.getConverter();
mongoMapping.setTypeMapper(new DefaultMongoTypeMapper(null));
mongoMapping.afterPropertiesSet();
return mongoTemplate;
}
//endregion
}
package org.example.controller;
import cn.hutool.core.util.StrUtil;
import com.mongodb.bulk.BulkWriteResult;
import com.mongodb.client.result.UpdateResult;
import org.bson.types.ObjectId;
import org.example.common.R;
import lombok.extern.slf4j.Slf4j;
import org.example.entity.TenderProject;
import org.example.utils.MongoUtil;
import org.example.utils.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.BulkOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.GroupOperation;
import org.springframework.data.mongodb.core.aggregation.MatchOperation;
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.data.util.Pair;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* @program: plus
* @ClassName WelcomeController
* @description:欢迎窗口
* @author: AI
* @create: 2023-10-31 15:10
* @Version 1.0
**/
@RestController
@RequestMapping("/api/welcome")
@Slf4j
public class WelcomeController {
private MongoTemplate mongoTemplate;
private MongoTemplate mongoTemplate2;
/**
* @Qualifier使用非默认数据库时必须加上
* 方法或者属性注入时使用 @Qualifier(name = "xx")
* 参数上使用 @Qualifier("xx")
* @param mongoTemplate
* @param mongoTemplate2
*/
@Autowired
public void setMongoTemplate(MongoTemplate mongoTemplate,
@Qualifier("twoMongotemplate") MongoTemplate mongoTemplate2){
this.mongoTemplate = mongoTemplate;
this.mongoTemplate2 = mongoTemplate2;
}
@Resource
private MongoUtil mongoUtil;
/**
* 普通查询
* @return
*/
@GetMapping("/hello")
public R Hello() {
Query query = new Query();
//query.fields().include("id");//查询指定字段
boolean flag = ObjectId.isValid("656e99610307387d9fc10797");//判断是否是16进制字符串,否则无法转化为objectId
ObjectId objectId = new ObjectId("656e99610307387d9fc10797");
query.addCriteria(Criteria.where("Tender.Ref._id").is(objectId));
TenderProject projectList = mongoTemplate.findOne(query, TenderProject.class);
Query query2 = new Query();
boolean flag2 = ObjectId.isValid("656e99610307387d9fc10797");//判断是否是16进制字符串,否则无法转化为objectId
ObjectId objectId2 = new ObjectId("5aceb7d88434881f541ba9a9");
query2.addCriteria(Criteria.where("Tender.Ref._id").is(objectId2));
TenderProject projectList2 = mongoTemplate2.findOne(query2, TenderProject.class);
return R.data("您好,欢迎使用脚手架!");
}
/**
* 统计查询
* @return
*/
@GetMapping("/query")
public R query() {
// 查询条件
Criteria criteria = new Criteria();
criteria.and("id").is("123");
criteria.and("author").is("321");
// 查询条件
MatchOperation match = Aggregation.match(criteria);
// 分组统计
GroupOperation group = Aggregation.group()
.count().as("totalBlog")
.sum("countRead").as("totalRead")
.avg("countRead").as("aveRead")
.sum("countLike").as("totalLike")
.avg("countLike").as("aveLike");
// 查询结果
AggregationResults<TenderProject> results = mongoTemplate.aggregate(Aggregation.newAggregation(TenderProject.class,
match, group), TenderProject.class);
return R.data("您好,欢迎使用脚手架!");
}
/**
* 分页
* @return
*/
@GetMapping("/list")
public R<PageHelper> list() {
Query query = new Query();
//query.addCriteria(Criteria.where("Tender.Ref._id").is(new ObjectId("656e99610307387d9fc10797")));
query.with(Sort.by(Sort.Direction.DESC,"OpeningTime"));//排序降序
mongoUtil.start(1, 10, query);
List<TenderProject> list = mongoTemplate.find(query, TenderProject.class);
long count = mongoTemplate.count(query, TenderProject.class);
PageHelper pageHelper = mongoUtil.pageHelper(count, list);
return R.data(pageHelper);
}
/**
* 更新
* @return
*/
@GetMapping("/update")
public R update() {
Query query = new Query();
query.addCriteria(Criteria.where("Tender.Ref._id").is(new ObjectId("656e99610307387d9fc10797")));
Update update = new Update();
//自主招标-园林绿化-20231205
// //直接更新
// update.set("Title", "自主招标-园林绿化-20231205");
// //加入到一个集合中,不会重复
// update.addToSet("students", "我是新加的键");
// //移除这个键
// update.unset("students");
// //需要传值,会清空其他属性
// update.addToSet("students");
// //文档不存在的话会插入一条新的记录
// update.setOnInsert("students", "我是新加的键");
UpdateResult updateResult = mongoTemplate.updateFirst(query, update, TenderProject.class);
if( updateResult.getModifiedCount() > 0){
return R.data("修改成功");
}else {
return R.data("500",null,"更新失败");
}
}
/**
* 批量操作
* @return
*/
@GetMapping("/bulk")
public R bulk() {
// //批量插入示例
// String collectionName = "";
// List<TenderProject> insertDataList = new ArrayList<>();
// BulkOperations operations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, collectionName);
// operations.insert(insertDataList);
// BulkWriteResult result = operations.execute();
//批量修改
// String collectionName = "";
// List<TenderProject> updateDataList = new ArrayList<>();
// BulkOperations operations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, collectionName);
// updateDataList.forEach(data -> {
// Query queryUpdate = new Query();
// queryUpdate.addCriteria(Criteria.where("_id").is("id"));
// Update update = new Update();
// update.set("field1", "value1").set("field2", "value2");
// operations.updateOne(queryUpdate, update);
// });
// BulkWriteResult result = operations.execute();
// //利用BulkOperations的upsert方法可以同时支持插入和更新操作
// //备注:BulkOperations.BulkMode.UNORDERED 和 BulkOperations.BulkMode.ORDERED的区别:
// //UNORDERED是平行处理,即使某条记录出错了,其余的也会继续处理;
// //ORDERED是队列排序处理,只要中途有个失败了,那么后续的操作流程就会终止了。
// String collectionName = "";
// List<TenderProject> dataList = new ArrayList<>();
// List<Pair<Query, Update>> updateList = new ArrayList<>(dataList.size());
// BulkOperations operations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, collectionName);
// dataList.forEach(data -> {
// Query query = new Query(new
// Criteria("field1").is("value1")).addCriteria(new Criteria("field2").is("value2"));
// Update update = new Update();
// for (int index = 0; index < dataList.size(); index++) {
// TenderProject tp = dataList.get(index);
// update.set(tp.get_IsDelete(), "value1").set(tp.getDOC_PRICE(), "value2");
// }
// Pair<Query, Update> updatePair = Pair.of(query, update);
// updateList.add(updatePair);
// });
// operations.upsert(updateList);
// BulkWriteResult result = operations.execute();
return R.data("修改成功");
}
}