Springboot项目配置MySQL与MongoDB两个数据源,默认数据源为MySQL,MongoDB创建TTL数据过期索引
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-mongodbartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-mongodb-reactiveartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>${druid.version}version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>dynamic-datasource-spring-boot-starterartifactId>
<version>${mybatis-plus-dynamic.version}version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plusartifactId>
<version>${mybatis-plus.version}version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>${mybatis-plus.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
spring:
thymeleaf:
cache: false
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
datasource:
master:
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2b8&allowPublicKeyRetrieval=true
mongodb:
host: localhost
port: 27017
database: test
# oracle:
# username: root
# password: 123456
# driver-class-name: oracle.jdbc.driver.OracleDriver
# url: jdbc:oracle:thin:@localhost:1521/company_project
# sqlServer:
# username: root
# password: liu2012313
# driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
# url: jdbc:sqlserver://localhost:1433;databaseName=company_project
redis:
host: 127.0.0.1 # Redis服务器地址
database: 0 # Redis数据库索引(默认为0)
port: 6379 # Redis服务器连接端口
password: # Redis服务器连接密码(默认为空)
jedis:
pool:
max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 8 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
timeout: 3000ms # 连接超时时间(毫秒
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class MongoConfig {
@Value("${spring.datasource.mongodb.host}")
private String host;
@Value("${spring.datasource.mongodb.port}")
private int port;
@Value("${spring.datasource.mongodb.database}")
private String database;
@Bean(name = "mongoDbFactory")
public MongoDbFactory mongoDbFactory() {
// 客户端
MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
builder.connectTimeout(10000);
builder.maxWaitTime(120000);
//数据库连接池其他参数,如最大连接数这些,可以参考着使用部分参数
//builder.connectionsPerHost();
//builder.minConnectionsPerHost();
//builder.requiredReplicaSetName();
//builder.threadsAllowedToBlockForConnectionMultiplier();
//builder.serverSelectionTimeout();
//builder.maxConnectionIdleTime();
//builder.maxConnectionLifeTime();
//builder.socketTimeout());
//builder.socketKeepAlive();
//builder.sslEnabled());
//builder.sslInvalidHostNameAllowed();
//builder.alwaysUseMBeans();
//builder.heartbeatFrequency();
//builder.minHeartbeatFrequency();
//builder.heartbeatConnectTimeout();
//builder.heartbeatSocketTimeout();
//builder.localThreshold();
MongoClientOptions mongoClientOptions = builder.build();
// MongoDB地址列表,如果有多个ip地址,那么配置文件里面可以用逗号分隔ip地址,这里再把每一个ip地址和端口号添加进list里面
List<ServerAddress> serverAddresses = new ArrayList<>();
ServerAddress serverAddress = new ServerAddress(host, port);
serverAddresses.add(serverAddress);
// 连接认证,如果设置了用户名和密码的话
// MongoCredential mongoCredential = null;
// mongoCredential = MongoCredential.createScramSha1Credential();
// 创建认证客户端(存在用户名和密码)
// MongoClient mongoClient = new MongoClient(serverAddresses, mongoCredential, mongoClientOptions);
// 创建非认证客户端(没有设置mongodb数据库的用户名和密码)
MongoClient mongoClient = new MongoClient(serverAddresses, mongoClientOptions);
// 创建MongoDbFactory
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClient, database);
return mongoDbFactory;
}
@Bean(name = "mongoTemplate")
@Autowired
public MongoTemplate getMongoTemplate(MongoDbFactory mongoDbFactory)
{
return new MongoTemplate(mongoDbFactory);
}
}
@RequestMapping("/mongodbTest")
@RestController
@Api(tags = "测试-Mongodb")
public class TestMongodbController {
@Autowired
private TestMongodbService testMongodbService;
@GetMapping("testMongodb")
public void testMongodb(){
testMongodbService.testInsert();
}
@GetMapping("query")
public DataResult query(){
return DataResult.success(testMongodbService.query());
}
@GetMapping("query1")
public List<TestMongodbEntity> query1(){
return testMongodbService.query1();
}
@GetMapping("query2")
public List<TestMongodbEntity> query2(){
return testMongodbService.query2();
}
@GetMapping("query3")
public TestMongodbEntity query3(){
return testMongodbService.query3();
}
}
public interface TestMongodbService {
void testInsert();
List<TestMongodbEntity> query();
List<TestMongodbEntity> query1();
List<TestMongodbEntity> query2();
TestMongodbEntity query3();
}
@Service
public class TestMongodbServiceImpl implements TestMongodbService {
@Autowired
private MongoTemplate mongoTemplate;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void testInsert() {
if(!mongoTemplate.collectionExists("testMongodbUser")){
mongoTemplate.createCollection("testMongodbUser");
}
for(int i=1 ; i<=10 ; i++ ){
TestMongodbEntity testMongodbEntity = new TestMongodbEntity();
testMongodbEntity.setDeptId("111");
// testMongodbEntity.setId(UUID.randomUUID().toString());
testMongodbEntity.setCreateTime(new Date());
testMongodbEntity.setUsername("张三"+i);
testMongodbEntity.setPassword("123456789");
testMongodbEntity.setPhone("12345678901");
testMongodbEntity.setDeptName("测试部"+i);
testMongodbEntity.setDeptNo(12);
testMongodbEntity.setRealName("张三"+i);
testMongodbEntity.setEmail("23rt45ygfe@qq.com");
testMongodbEntity.setUpdateTime(new Date());
List<String> roleIds = new ArrayList<>();
roleIds.add("swq21212");
roleIds.add("test0334");
roleIds.add("test0337");
roleIds.add("test0339");
roleIds.add("test0335");
testMongodbEntity.setRoleIds(roleIds);
testMongodbEntity.setTime1(new Date().getTime());
SysRole sysRole = new SysRole();
sysRole.setName("张三"+i);
sysRole.setCreateTime(new Date());
sysRole.setUpdateTime(new Date());
sysRole.setDeleted(0);
testMongodbEntity.setSysRole(sysRole);
mongoTemplate.save(testMongodbEntity,"testMongodbUser");
}
}
@Override
public List<TestMongodbEntity> query() {
Query query = new Query();
query.addCriteria(Criteria.where("username").regex(".*?张三.*"));
return mongoTemplate.find(query,TestMongodbEntity.class);
}
@Override
public List<TestMongodbEntity> query1() {
Query query = new Query();
query.addCriteria(Criteria.where("sysRole.name").is("张三"));
return mongoTemplate.find(query,TestMongodbEntity.class);
}
@Override
public List<TestMongodbEntity> query2() {
Query query = new Query();
try {
query.addCriteria(Criteria.where("createTime").gte(simpleDateFormat.parse("2022-11-30 14:41:20")));
} catch (ParseException e) {
e.printStackTrace();
}
return mongoTemplate.find(query,TestMongodbEntity.class);
}
@Override
public TestMongodbEntity query3() {
Query query = new Query();
query.addCriteria(Criteria.where("username").is("张三1"));
return mongoTemplate.findOne(query,TestMongodbEntity.class);
}
}
@Data
@Document(collection = "testMongodbUser")
public class TestMongodbEntity {
//指定使用MongoDB自动生成的_id
@Id
private String uid;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 手机号
*/
private String phone;
/**
* 部门ID
*/
private String deptId;
/**
* 部门名称
*/
private String deptName;
/**
* 部门编号
*/
private Integer deptNo;
/**
* 真实用户名
*/
private String realName;
/**
* 邮箱
*/
private String email;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 角色ID
*/
private List<String> roleIds;
/**
* 时间
*/
private Long time1;
/**
* 角色
*/
private SysRole sysRole;
}
在一般的应用系统中,并非所有的数据都需要永久存储。例如一些系统事件、用户消息等,这些数据随着时间的推移,其重要程度逐渐降低。更重要的是,存储这些大量的历史数据需要花费较高的成本,因此项目中通常会对过期且不再使用的数据进行老化处理。
对于数据老化,MongoDB提供了一种更加便捷的做法:TTL(Time To Live)索引。
TL索引需要声明在一个日期类型的字段中,TTL 索引是特殊的单字段索引。MongoDB 可以使用它在一定时间或特定时钟时间后自动从集合中删除文档。
对集合创建TTL索引之后,MongoDB会在周期性运行的后台线程中对该集合进行检查及数据清理工作。除了数据老化功能,TTL索引具有普通索引的功能,同样可以用于加速数据的查询。
TTL 索引不保证过期数据会在过期后立即被删除。文档过期和 MongoDB 从数据库中删除文档的时间之间可能存在延迟。删除过期文档的后台任务每 60 秒运行一次。因此,在文档到期和后台任务运行之间的时间段内,文档可能会保留在集合中。
语法
#创建 TTL 索引,TTL 值为3600秒
db.collection.createIndex(
{ "createTime": 1 },
{ expireAfterSeconds: 3600 }
)
TTL索引在创建之后,仍然可以对过期时间进行修改。这需要使用collMod命令对索引的定义进行变更
db.runCommand({collMod:"collection",index:{keyPattern:
{createTime:1},expireAfterSeconds:600}})
只支持对单个字段创建TTL索引,复合索引不支持expireAfterSeconds选项
_id列不支持TTL索引
固定集合(capped collection)不支持TTL索引
不支持用createIndex() 修改expireAfterSeconds属性,但可以用collMod命令修改,或者重建索引,但重建对于大集合成本较高,建议用collMod方式
一个列只能创建普通索引或TTL索引,不能同时对一个列创建这2种类型索引(实际TTL索引本身就是普通索引,只是多了一个过期属性)
如果一个列已经存在索引,则需要先将该索引drop后才能重建为TTL索引,不能直接转换
用于创建TTL索引的字段必须为时间类型:
Date() method which returns the current date as a string.
new Date() constructor which returns a Date object using the ISODate() wrapper.
ISODate() constructor which returns a Date object using the ISODate() wrapper.
链接: TTL索引官方文档