Refactor: 数据库初始化以动态支持MySQL和SQLITE

将DataSourceConfig更新为:

- MySQL跳过架构初始化,需要手动设置。
- 使用schema.sql和data.sql初始化sqlite
- 更改上传文件创建时间持续到持续的时间戳处理。
- 添加日志记录以更好地调试数据源选择和初始化
This commit is contained in:
czhqwer
2025-03-29 01:35:57 +08:00
parent f29e64d3aa
commit f6deba2a41
10 changed files with 110 additions and 20 deletions

View File

@@ -36,7 +36,7 @@ CREATE TABLE `storage_config` (
-- ----------------------------
-- Records of storage_config
-- ----------------------------
INSERT INTO `storage_config` VALUES (1, 'local', 'http://localhost:10086', '', '', 'E:\\develop\\Java\\xxxxxx\\upload-file-backend\\data');
INSERT INTO `storage_config` VALUES (1, 'local', 'http://localhost:10086', '', '', 'E:\\data');
INSERT INTO `storage_config` VALUES (2, 'minio', 'http://localhost:9000', 'minio', 'minio123', 'upload-file');
INSERT INTO `storage_config` VALUES (3, 'oss', 'https://oss-cn-guangzhou.aliyuncs.com', 'ossAccessKeyID', 'ossAccessKeySecret', 'yourBucket');
@@ -57,7 +57,7 @@ CREATE TABLE `upload_file` (
`content_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '文件类型',
`access_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '访问地址',
`download_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '下载地址',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`create_time` varchar(255) DEFAULT NULL COMMENT '创建时间',
`storage_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '上传类型',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uq_file_identifier`(`file_identifier` ASC) USING BTREE,

View File

@@ -74,6 +74,11 @@
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.0</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.49.1.0</version>
</dependency>
</dependencies>
<build>

View File

@@ -2,11 +2,13 @@ package cn.czh.advice;
import cn.czh.base.BusinessException;
import cn.czh.base.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@@ -19,6 +21,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public Result<?> handleBusinessException(BusinessException e) {
log.error("业务异常: {}", e.getMessage(), e);
return Result.error(500, e.getMessage());
}
}

View File

@@ -0,0 +1,76 @@
package cn.czh.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Value("${spring.datasource.url:jdbc:sqlite:./upload-file.db}")
private String defaultUrl;
@Value("${spring.datasource.driver-class-name:org.sqlite.JDBC}")
private String defaultDriverClassName;
@Value("${mysql.datasource.url:}")
private String mysqlUrl;
@Value("${mysql.datasource.username:}")
private String mysqlUsername;
@Value("${mysql.datasource.password:}")
private String mysqlPassword;
@Value("${mysql.datasource.driver-class-name:com.mysql.cj.jdbc.Driver}")
private String mysqlDriverClassName;
@Bean
public DataSource dataSource() {
boolean useMySQL = !mysqlUrl.isEmpty() && !mysqlUsername.isEmpty() && !mysqlPassword.isEmpty();
if (useMySQL) {
return DataSourceBuilder.create()
.url(mysqlUrl)
.username(mysqlUsername)
.password(mysqlPassword)
.driverClassName(mysqlDriverClassName)
.build();
} else {
// 默认使用 SQLite无需 username 和 password
return DataSourceBuilder.create()
.url(defaultUrl)
.driverClassName(defaultDriverClassName)
.build();
}
}
@Bean
@DependsOn("dataSource")
public DataSourceInitializer dataSourceInitializer(DataSource dataSource) {
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
boolean useMySQL = !mysqlUrl.isEmpty() && !mysqlUsername.isEmpty() && !mysqlPassword.isEmpty();
if (useMySQL) {
initializer.setEnabled(false);
} else {
populator.addScript(new ClassPathResource("schema.sql"));
populator.addScript(new ClassPathResource("data.sql"));
initializer.setEnabled(true);
}
initializer.setDatabasePopulator(populator);
initializer.afterPropertiesSet();
return initializer;
}
}

View File

@@ -72,6 +72,6 @@ public class UploadFile implements Serializable {
/**
* 创建时间
*/
private Date createTime;
private String createTime;
}

View File

@@ -21,12 +21,12 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
@@ -50,7 +50,7 @@ public class LocalStorageService implements IStorageService {
private StorageConfig storageConfig;
@PostConstruct
@EventListener(ApplicationReadyEvent.class)
public void init() {
this.refreshConfig();
}
@@ -110,7 +110,7 @@ public class LocalStorageService implements IStorageService {
uploadFile.setChunkSize(file.getSize());
uploadFile.setFileIdentifier(md5);
uploadFile.setStorageType(StorageConfig.LOCAL);
uploadFile.setCreateTime(new Date());
uploadFile.setCreateTime(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
uploadFileMapper.insert(uploadFile);
FileRecordDTO fileRecord = new FileRecordDTO();
@@ -160,7 +160,7 @@ public class LocalStorageService implements IStorageService {
.setObjectKey(objectKey)
.setIsFinish(0)
.setStorageType(StorageConfig.LOCAL)
.setCreateTime(new Date())
.setCreateTime(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"))
.setContentType(param.getContentType());
uploadFileMapper.insert(uploadFile);

View File

@@ -34,6 +34,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.minio.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
@@ -41,7 +42,6 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -79,7 +79,7 @@ public class MinioStorageService implements IStorageService {
private MinioClient minioClient;
private AmazonS3 amazonS3;
@PostConstruct
@EventListener(ApplicationReadyEvent.class)
public void init() {
this.refreshConfig();
}
@@ -151,7 +151,7 @@ public class MinioStorageService implements IStorageService {
uploadFile.setContentType(file.getContentType());
uploadFile.setAccessUrl(getFileAccessUrl(objectName));
uploadFile.setDownloadUrl(getFileDownloadUrl(objectName));
uploadFile.setCreateTime(new Date());
uploadFile.setCreateTime(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
uploadFile.setIsFinish(1);
uploadFile.setTotalSize(file.getSize());
uploadFile.setChunkNum(1);
@@ -209,7 +209,7 @@ public class MinioStorageService implements IStorageService {
.setFileName(fileName)
.setObjectKey(key)
.setIsFinish(0)
.setCreateTime(currentDate)
.setCreateTime(DateUtil.format(currentDate, "yyyy-MM-dd HH:mm:ss"))
.setContentType(param.getContentType())
.setStorageType(StorageConfig.MINIO)
.setUploadId(getUploadId(key));

View File

@@ -23,12 +23,12 @@ import com.aliyun.oss.model.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
@@ -56,7 +56,7 @@ public class OssStorageService implements IStorageService {
/** 预签名 URL 过期时间10 分钟 */
private static final long PRE_SIGN_URL_EXPIRE = 10 * 60 * 1000;
@PostConstruct
@EventListener(ApplicationReadyEvent.class)
public void init() {
this.refreshConfig();
}
@@ -121,7 +121,7 @@ public class OssStorageService implements IStorageService {
uploadFile.setChunkNum(1);
uploadFile.setChunkSize(file.getSize());
uploadFile.setFileIdentifier(md5);
uploadFile.setCreateTime(new Date());
uploadFile.setCreateTime(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
uploadFile.setStorageType(StorageConfig.OSS);
uploadFileMapper.insert(uploadFile);
@@ -196,7 +196,7 @@ public class OssStorageService implements IStorageService {
.setObjectKey(objectKey)
.setIsFinish(0)
.setStorageType(StorageConfig.OSS)
.setCreateTime(new Date())
.setCreateTime(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"))
.setContentType(param.getContentType());
uploadFileMapper.insert(task);

View File

@@ -3,10 +3,8 @@ server:
spring:
datasource:
url: jdbc:mysql://localhost:3306/upload-file?useSSL=false&serverTimezone=Asia/Shanghai
username: ${MYSQL_USERNAME:root}
password: ${MYSQL_password:root}
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:sqlite:./upload-file.db
driver-class-name: org.sqlite.JDBC
servlet:
multipart:
max-file-size: 500MB
@@ -14,6 +12,14 @@ spring:
main:
allow-bean-definition-overriding: true
mysql:
datasource:
url: ${MYSQL_URL:} # jdbc:mysql://localhost:3306/upload-file?useSSL=false&serverTimezone=Asia/Shanghai
username: ${MYSQL_USERNAME:} # root
password: ${MYSQL_PASSWORD:} # root
driver-class-name: com.mysql.cj.jdbc.Driver
logging:
level:
cn.czh.mapper: debug
cn.czh.mapper: debug
org.springframework.jdbc: debug

Binary file not shown.