1.单数据源(单节点)
引入依赖
<!--mongodb依赖--><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>
也可以在创建boot项目时,在noSql中选择Mongo即可
添加配置
在yml下添加如下内容,如果没有权限控制,那么不写用户名和密码即可
spring:data:mongodb:host: 120.48.107.224port: 27017username: "ftc"password: "1213456"database: java_test
也可以通过url形式进行链接
spring:data:mongodb:username: "ftc"password: "1213456"uri: mongodb://120.48.107.224:27017/java_test
添加监听器
如果不创建监听器的话,spring-data-mongo会默认为每个文档添加名为_class的键,值为文档对应类的包路径
添加监听器后,就不会创建默认列了,如图:
监听器代码如下
import org.springframework.context.ApplicationListener;import org.springframework.context.annotation.Configuration;import org.springframework.context.event.ContextRefreshedEvent;import org.springframework.data.mongodb.core.MongoTemplate;import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;import org.springframework.data.mongodb.core.convert.MappingMongoConverter;import org.springframework.data.mongodb.core.convert.MongoConverter;import javax.annotation.Resource;/*** @author 冯铁城 [17615007230@163.com]* @date 2022-07-20 19:26:10* @describe: mongodb监听器*/@Configurationpublic class MongoReadyListener implements ApplicationListener<ContextRefreshedEvent> {/*** spring-data-mongo会默认为每个文档添加的键,值为文档对应类的包路径,例如:com.ftc.redistry.mongo.Student*/private static final String TYPEKEY = "_class";@ResourceMongoTemplate oneMongoTemplate;@Overridepublic void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {MongoConverter converter = oneMongoTemplate.getConverter();if (converter.getTypeMapper().isTypeKey(TYPEKEY)) {((MappingMongoConverter) converter).setTypeMapper(new DefaultMongoTypeMapper(null));}}}
创建对应文档类
注意点如下:
- 如果不创建格式规范的文档类,自由存储数据类型,那么就会创建对应的数据类型集合,例如存入一个JSONObject对象,就会创建一个名为JSONObject的集合
- 通过@Document注解加在类上,声明一个实体类对应的集合是哪个集合。例如@Document(collection = “student”),那么该实体类对应的集合为student
- 主键ID字段最好设置为String类型,因为mongo自动生成的主键ID长达24位,其他数据类型不好承接,String类型比较方便
文档类具体代码如下
import lombok.Data;import org.springframework.data.mongodb.core.mapping.Document;/*** @author 冯铁城 [17615007230@163.com]* @date 2022-07-20 19:12:01* @describe: MongoDB实体类* <p>* “@Document(collection = "student")” 用于指定对应哪个集合*/@Data@Document(collection = "student")public class Student {private String id;private String name;private int age;}
操作示例
通过mongoTemplate操作即可
import cn.hutool.core.lang.Console;import com.ftc.redistry.mongo.Student;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.data.mongodb.core.MongoTemplate;/*** @author 冯铁城 [17615007230@163.com]* @date 2022-07-20 19:18:24* @describe:*/@SpringBootTestpublic class MongoDbTest {@Autowiredprivate MongoTemplate mongoTemplate;@Testvoid testInsert() {//1.创建对象指定IDStudent student = new Student();student.setId("2222");student.setName("ftc1111");student.setAge(13);Student insert = mongoTemplate.insert(student);Console.log(insert);//2.创建对象不指定IDStudent student1 = new Student();student1.setName("ftc1111");student1.setAge(13);Student insert1 = mongoTemplate.insert(student1);Console.log(insert1);}}
2.多数据源(单节点)
引入依赖
<!--mongodb依赖--><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.4</version></dependency>
也可以在创建boot项目时,在noSql中选择Mongo即可
添加配置
数据的配置格式可自定义,下文只提供参考,当然也可以直接借鉴获取
还有其他参数,例如链接时间等,这些可以具体情况具体安排
spring:data:mongodb:#主数据源primary:address:- 120.48.107.224:27017- 120.48.107.224:27018username: "java_test"password: "java_test"database: java_test#备数据源secondary:address:- 120.48.107.224:27017- 120.48.107.224:27018username: "java_test_bak"password: "java_test_bak"database: java_test_bak
添加配置类
import lombok.Data;import java.util.List;/*** @author: 冯铁城 [17615007230@163.com]* @date: 2022-07-29 15:40:07* @describe: mongo配置属性*/@Datapublic class MongoConfigProperties {/*** 数据源地址集合 格式{host}:{port}*/private List<String> address;/*** 用户名*/private String username;/*** 密码*/private String password;/*** 数据库名称*/private String database;}
添加不同数据源自定义配置
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;/*** @author: 冯铁城 [17615007230@163.com]* @date: 2022-07-29 15:41:02* @describe: mongo配置类*/@Configurationpublic class MongoConfig {@Primary@Bean(name = "primaryMongoProperties")@ConfigurationProperties(prefix = "spring.data.mongodb.primary")public MongoConfigProperties primaryMongoProperties() {return new MongoConfigProperties();}@Bean(name = "secondaryMongoProperties")@ConfigurationProperties(prefix = "spring.data.mongodb.secondary")public MongoConfigProperties secondaryMongoProperties() {return new MongoConfigProperties();}}
添加主数据源配置
import cn.hutool.core.util.StrUtil;import com.mongodb.MongoClientSettings;import com.mongodb.MongoCredential;import com.mongodb.ReadPreference;import com.mongodb.ServerAddress;import com.mongodb.client.MongoClients;import com.mongodb.connection.ConnectionPoolSettings;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import org.springframework.data.mongodb.MongoTransactionManager;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.core.convert.MongoConverter;import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;import javax.annotation.Resource;import java.util.ArrayList;import java.util.List;import java.util.concurrent.TimeUnit;/*** @author: 冯铁城 [17615007230@163.com]* @date: 2022-07-29 15:44:02* @describe: mongo主数据源各种配置类*/@Configuration@EnableMongoRepositories(basePackages = "com.ftc.mongotest", mongoTemplateRef = "primaryTemplate")public class PrimaryMongoTemplate {@Resource@Qualifier("primaryMongoProperties")private MongoConfigProperties primaryProperties;@Primary@Bean(name = "primaryTemplate")public MongoTemplate primaryTemplate() {//1.获取primaryTemplateSimpleMongoClientDatabaseFactory primaryFactory = getFactory(this.primaryProperties);MongoTemplate primaryTemplate = new MongoTemplate(primaryFactory);//2.默认数据源监听处理String type = "_class";MongoConverter converter = primaryTemplate.getConverter();if (converter.getTypeMapper().isTypeKey(type)) {((MappingMongoConverter) converter).setTypeMapper(new DefaultMongoTypeMapper(null));}//3.返回return primaryTemplate;}@Bean(name = "primaryMongoTransactionManager")public MongoTransactionManager userTransactionManager() {SimpleMongoClientDatabaseFactory factory = getFactory(this.primaryProperties);return new MongoTransactionManager(factory);}@Primary@Bean("primaryFactory")public SimpleMongoClientDatabaseFactory getFactory(MongoConfigProperties properties) {//1.设置链接地址List<ServerAddress> hosts = new ArrayList<>();properties.getAddress().forEach(address -> {List<String> addressInfos = StrUtil.split(address, StrUtil.COLON);hosts.add(new ServerAddress(addressInfos.get(0), Integer.parseInt(addressInfos.get(1))));});//2.初始化连接池参数ConnectionPoolSettings poolSetting = ConnectionPoolSettings.builder().maxWaitTime(10000, TimeUnit.MILLISECONDS).build();//3.构造基础链接参数MongoClientSettings.Builder settingBuilder = MongoClientSettings.builder().applyToConnectionPoolSettings(builder -> builder.applySettings(poolSetting)).applyToClusterSettings(builder -> builder.hosts(hosts));//4.初始链接参数以及连接池参数MongoClientSettings settings;//5.根据用户名是否为空判定是否鉴权if (StrUtil.isNotBlank(properties.getUsername())) {//6.添加授权参数MongoCredential credential = MongoCredential.createScramSha1Credential(properties.getUsername(), properties.getDatabase(), properties.getPassword().toCharArray());//7.添加链接参数settings = settingBuilder.credential(credential).build();} else {//7.添加链接参数settings = settingBuilder.build();}//8.创建工厂返回return new SimpleMongoClientDatabaseFactory(MongoClients.create(settings), properties.getDatabase());}}
添加备数据源配置
import cn.hutool.core.util.StrUtil;import com.mongodb.MongoClientSettings;import com.mongodb.MongoCredential;import com.mongodb.ReadPreference;import com.mongodb.ServerAddress;import com.mongodb.client.MongoClients;import com.mongodb.connection.ConnectionPoolSettings;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.mongodb.MongoTransactionManager;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.core.convert.MongoConverter;import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;import javax.annotation.Resource;import java.util.ArrayList;import java.util.List;import java.util.concurrent.TimeUnit;/*** @author: 冯铁城 [17615007230@163.com]* @date: 2022-07-29 15:44:02* @describe: mongo主数据源各种配置类*/@Configuration@EnableMongoRepositories(basePackages = "com.ftc.mongotest", mongoTemplateRef = "secondaryTemplate")public class SecondaryMongoTemplate {@Resource@Qualifier("secondaryMongoProperties")private MongoConfigProperties secondaryProperties;@Bean(name = "secondaryTemplate")public MongoTemplate secondaryTemplate() {//1.获取primaryTemplateSimpleMongoClientDatabaseFactory primaryFactory = getFactory(this.secondaryProperties);MongoTemplate primaryTemplate = new MongoTemplate(primaryFactory);//2.默认数据源监听处理String type = "_class";MongoConverter converter = primaryTemplate.getConverter();if (converter.getTypeMapper().isTypeKey(type)) {((MappingMongoConverter) converter).setTypeMapper(new DefaultMongoTypeMapper(null));}//3.返回return primaryTemplate;}@Bean(name = "secondaryMongoTransactionManager")public MongoTransactionManager userTransactionManager() {SimpleMongoClientDatabaseFactory factory = getFactory(this.secondaryProperties);return new MongoTransactionManager(factory);}@Bean("secondaryFactory")public SimpleMongoClientDatabaseFactory getFactory(MongoConfigProperties properties) {//1.设置链接地址List<ServerAddress> hosts = new ArrayList<>();properties.getAddress().forEach(address -> {List<String> addressInfos = StrUtil.split(address, StrUtil.COLON);hosts.add(new ServerAddress(addressInfos.get(0), Integer.parseInt(addressInfos.get(1))));});//2.初始化连接池参数ConnectionPoolSettings poolSetting = ConnectionPoolSettings.builder().maxWaitTime(10000, TimeUnit.MILLISECONDS).build();//3.构造基础链接参数MongoClientSettings.Builder settingBuilder = MongoClientSettings.builder().applyToConnectionPoolSettings(builder -> builder.applySettings(poolSetting)).applyToClusterSettings(builder -> builder.hosts(hosts));//4.初始链接参数以及连接池参数MongoClientSettings settings;//5.根据用户名是否为空判定是否鉴权if (StrUtil.isNotBlank(properties.getUsername())) {//6.添加授权参数MongoCredential credential = MongoCredential.createScramSha1Credential(properties.getUsername(), properties.getDatabase(), properties.getPassword().toCharArray());//7.添加链接参数settings = settingBuilder.credential(credential).build();} else {//7.添加链接参数settings = settingBuilder.build();}//8.创建工厂返回return new SimpleMongoClientDatabaseFactory(MongoClients.create(settings), properties.getDatabase());}}
创建对应文档类
操作示例
使用@Qualifier进行不同mongo的注入,具体代码如下
@Resource@Qualifier(value = "primaryTemplate")private MongoTemplate primaryTemplate;@Resource@Qualifier(value = "secondaryTemplate")private MongoTemplate secondaryTemplate;@BeforeEachvoid beforeAll() {primaryTemplate.remove(new Query(), Student.class);secondaryTemplate.remove(new Query(), Student.class);}@Testvoid testInsert() {//1.创建主数据源对象Student student = new Student();student.setId(1);student.setName("主数据源数据");//2.主数据源保存primaryTemplate.insert(student);//3.创建从数据源对象student = new Student();student.setId(1);student.setName("从数据源数据");//4.从数据源保存secondaryTemplate.insert(student);}
3.单数据源(副本集)
添加配置
在yml下添加如下内容
spring:data:mongodb:uri: mongodb://java_test:java_test@120.48.107.224:27017,120.48.107.224:27018/java_test?replicaSet=ftc&authSource=java_test&readPreference=secondaryPreferred&connectTimeoutMS=60000
链接参数介绍:
- replicaSet:集群名称
- authSource:当前用户名密码授权的数据库
- readPreference:读偏好,具体参考链接。需要注意的是,mongo目前在事务中,只允许主节点读取数据,从节点读取数据会报错!!!!!!!!所以具体的参数配置要好好考虑一下
- connectTimeoutMS:链接超时毫秒
其他步骤都与单数据源(单节点)一致
4.多数据源(副本集)
添加主数据源配置
这里只做示例,副本集需要配置写关注,读关注,读偏好等参数 ```java package com.ftc.mongotest.config;
import cn.hutool.core.util.StrUtil; import com.mongodb.MongoClientSettings; import com.mongodb.MongoCredential; import com.mongodb.ReadPreference; import com.mongodb.ServerAddress; import com.mongodb.client.MongoClients; import com.mongodb.connection.ConnectionPoolSettings; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.mongodb.MongoTransactionManager; 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.core.convert.MongoConverter; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit;
/**
- @author: 冯铁城 [17615007230@163.com]
- @date: 2022-07-29 15:44:02
@describe: mongo主数据源各种配置类 */ @Configuration @EnableMongoRepositories(basePackages = “com.ftc.mongotest”, mongoTemplateRef = “primaryTemplate”) public class PrimaryMongoTemplate {
@Resource @Qualifier(“primaryMongoProperties”) private MongoConfigProperties primaryProperties;
@Primary @Bean(name = “primaryTemplate”) public MongoTemplate primaryTemplate() {
//1.获取primaryTemplateSimpleMongoClientDatabaseFactory primaryFactory = getFactory(this.primaryProperties);MongoTemplate primaryTemplate = new MongoTemplate(primaryFactory);//2.默认数据源监听处理String type = "_class";MongoConverter converter = primaryTemplate.getConverter();if (converter.getTypeMapper().isTypeKey(type)) {((MappingMongoConverter) converter).setTypeMapper(new DefaultMongoTypeMapper(null));}//3.返回return primaryTemplate;
}
@Bean(name = “primaryMongoTransactionManager”) public MongoTransactionManager primaryTransactionManager() {
SimpleMongoClientDatabaseFactory factory = getFactory(this.primaryProperties);return new MongoTransactionManager(factory);
}
@Primary @Bean(name = “primaryGridFsTemplate”) public GridFsTemplate primaryGridFsTemplate() {
SimpleMongoClientDatabaseFactory factory = getFactory(this.primaryProperties);MappingMongoConverter converter = new MappingMongoConverter(factory, new MongoMappingContext());return new GridFsTemplate(factory, converter);
}
@Primary @Bean(“primaryFactory”) public SimpleMongoClientDatabaseFactory getFactory(MongoConfigProperties properties) {
//1.设置链接地址List<ServerAddress> hosts = new ArrayList<>();properties.getAddress().forEach(address -> {List<String> addressInfos = StrUtil.split(address, StrUtil.COLON);hosts.add(new ServerAddress(addressInfos.get(0), Integer.parseInt(addressInfos.get(1))));});//2.初始化连接池参数ConnectionPoolSettings poolSetting = ConnectionPoolSettings.builder().maxWaitTime(10000, TimeUnit.MILLISECONDS).build();//3.构造基础链接参数MongoClientSettings.Builder settingBuilder = MongoClientSettings.builder().applyToConnectionPoolSettings(builder -> builder.applySettings(poolSetting)).applyToClusterSettings(builder -> builder.hosts(hosts)).readPreference(ReadPreference.secondaryPreferred());//4.初始链接参数以及连接池参数MongoClientSettings settings;//5.根据用户名是否为空判定是否鉴权if (StrUtil.isNotBlank(properties.getUsername())) {//6.添加授权参数MongoCredential credential = MongoCredential.createScramSha1Credential(properties.getUsername(), properties.getDatabase(), properties.getPassword().toCharArray());//7.添加链接参数settings = settingBuilder.credential(credential).build();} else {//7.添加链接参数settings = settingBuilder.build();}//8.创建工厂返回return new SimpleMongoClientDatabaseFactory(MongoClients.create(settings), properties.getDatabase());
添加备数据源配置
这里只做示例,副本集需要配置写关注,读关注,读偏好等参数 ```java package com.ftc.mongotest.config;
import cn.hutool.core.util.StrUtil; import com.mongodb.MongoClientSettings; import com.mongodb.MongoCredential; import com.mongodb.ReadPreference; import com.mongodb.ServerAddress; import com.mongodb.client.MongoClients; import com.mongodb.connection.ConnectionPoolSettings; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.MongoTransactionManager; 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.core.convert.MongoConverter; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit;
/**
- @author: 冯铁城 [17615007230@163.com]
- @date: 2022-07-29 15:44:02
@describe: mongo主数据源各种配置类 */ @Configuration @EnableMongoRepositories(basePackages = “com.ftc.mongotest”, mongoTemplateRef = “secondaryTemplate”) public class SecondaryMongoTemplate {
@Resource @Qualifier(“secondaryMongoProperties”) private MongoConfigProperties secondaryProperties;
@Bean(name = “secondaryTemplate”) public MongoTemplate secondaryTemplate() {
//1.获取secondaryTemplateSimpleMongoClientDatabaseFactory secondaryFactory = getFactory(this.secondaryProperties);MongoTemplate secondaryTemplate = new MongoTemplate(secondaryFactory);//2.默认数据源监听处理String type = "_class";MongoConverter converter = secondaryTemplate.getConverter();if (converter.getTypeMapper().isTypeKey(type)) {((MappingMongoConverter) converter).setTypeMapper(new DefaultMongoTypeMapper(null));}//3.返回return secondaryTemplate;
}
@Bean(name = “secondaryMongoTransactionManager”) public MongoTransactionManager secondaryTransactionManager() {
SimpleMongoClientDatabaseFactory factory = getFactory(this.secondaryProperties);return new MongoTransactionManager(factory);
}
@Bean(name = “secondaryGridFsTemplate”) public GridFsTemplate secondaryGridFsTemplate() {
SimpleMongoClientDatabaseFactory factory = getFactory(this.secondaryProperties);MappingMongoConverter converter = new MappingMongoConverter(factory, new MongoMappingContext());return new GridFsTemplate(factory, converter);
}
@Bean(“secondaryFactory”) public SimpleMongoClientDatabaseFactory getFactory(MongoConfigProperties properties) {
//1.设置链接地址List<ServerAddress> hosts = new ArrayList<>();properties.getAddress().forEach(address -> {List<String> addressInfos = StrUtil.split(address, StrUtil.COLON);hosts.add(new ServerAddress(addressInfos.get(0), Integer.parseInt(addressInfos.get(1))));});//2.初始化连接池参数ConnectionPoolSettings poolSetting = ConnectionPoolSettings.builder().maxWaitTime(10000, TimeUnit.MILLISECONDS).build();//3.构造基础链接参数MongoClientSettings.Builder settingBuilder = MongoClientSettings.builder().applyToConnectionPoolSettings(builder -> builder.applySettings(poolSetting)).applyToClusterSettings(builder -> builder.hosts(hosts)).readPreference(ReadPreference.secondaryPreferred());//4.初始链接参数以及连接池参数MongoClientSettings settings;//5.根据用户名是否为空判定是否鉴权if (StrUtil.isNotBlank(properties.getUsername())) {//6.添加授权参数MongoCredential credential = MongoCredential.createScramSha1Credential(properties.getUsername(), properties.getDatabase(), properties.getPassword().toCharArray());//7.添加链接参数settings = settingBuilder.credential(credential).build();} else {//7.添加链接参数settings = settingBuilder.build();}//8.创建工厂返回return new SimpleMongoClientDatabaseFactory(MongoClients.create(settings), properties.getDatabase());
其他步骤都与多数据源(单节点)一致
