①逆向工程插件支持多数据源
②打包体积缩小
This commit is contained in:
@@ -32,12 +32,6 @@
|
|||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mybatis</groupId>
|
|
||||||
<artifactId>mybatis</artifactId>
|
|
||||||
<version>3.5.7</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- MyBatis Generator Core -->
|
<!-- MyBatis Generator Core -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mybatis.generator</groupId>
|
<groupId>org.mybatis.generator</groupId>
|
||||||
@@ -64,12 +58,6 @@
|
|||||||
<version>4.5</version>
|
<version>4.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>xerces</groupId>
|
|
||||||
<artifactId>xercesImpl</artifactId>
|
|
||||||
<version>2.12.2</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
@@ -100,53 +88,10 @@
|
|||||||
<version>2.11.0</version>
|
<version>2.11.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.dubbo</groupId>
|
|
||||||
<artifactId>dubbo</artifactId>
|
|
||||||
<version>2.7.12</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Apache Commons CSV for generating CSV files -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-csv</artifactId>
|
|
||||||
<version>1.9.0</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- JGit dependency -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jgit</groupId>
|
|
||||||
<artifactId>org.eclipse.jgit</artifactId>
|
|
||||||
<version>6.8.0.202311291450-r</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
</dependency>
|
<scope>provided</scope>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.guava</groupId>
|
|
||||||
<artifactId>guava</artifactId>
|
|
||||||
<version>33.0.0-jre</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.dom4j</groupId>
|
|
||||||
<artifactId>dom4j</artifactId>
|
|
||||||
<version>2.1.3</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>jaxen</groupId>
|
|
||||||
<artifactId>jaxen</artifactId>
|
|
||||||
<version>1.2.0</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba</groupId>
|
|
||||||
<artifactId>fastjson</artifactId>
|
|
||||||
<version>1.2.83</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -166,18 +111,6 @@
|
|||||||
<groupId>com.alibaba</groupId>
|
<groupId>com.alibaba</groupId>
|
||||||
<artifactId>easyexcel</artifactId>
|
<artifactId>easyexcel</artifactId>
|
||||||
<version>3.1.1</version>
|
<version>3.1.1</version>
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>redis.clients</groupId>
|
|
||||||
<artifactId>jedis</artifactId>
|
|
||||||
<version>3.7.0</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.poi</groupId>
|
|
||||||
<artifactId>poi-ooxml</artifactId>
|
|
||||||
<version>5.2.3</version>
|
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
@@ -217,6 +150,15 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>com.example.workutils.WorkUtilsApplication</mainClass>
|
||||||
|
<excludes>
|
||||||
|
<exclude>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|||||||
@@ -19,29 +19,29 @@ echo ========== WorkUtils 生产构建 ==========
|
|||||||
echo.
|
echo.
|
||||||
|
|
||||||
:: 1. 杀掉可能占用 target 的进程
|
:: 1. 杀掉可能占用 target 的进程
|
||||||
echo [1/4] 清理残留进程...
|
echo [1/4] Clean stale processes...
|
||||||
taskkill /f /im java.exe 2>nul
|
taskkill /f /im java.exe 2>nul
|
||||||
taskkill /f /im workutils.exe 2>nul
|
taskkill /f /im workutils.exe 2>nul
|
||||||
|
|
||||||
:: 2. Maven 打包
|
:: 2. Maven 打包
|
||||||
echo.
|
echo.
|
||||||
echo [2/4] Maven 编译打包...
|
echo [2/4] Maven build...
|
||||||
call "%PROJECT_DIR%mvnw.cmd" clean package -DskipTests -q
|
call "%PROJECT_DIR%\mvnw.cmd" clean package -DskipTests -q
|
||||||
if %errorlevel% neq 0 (
|
if %errorlevel% neq 0 (
|
||||||
echo [ERROR] Maven 打包失败!
|
echo [ERROR] Maven build failed!
|
||||||
pause
|
pause
|
||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
:: 3. 提取版本号
|
:: 3. 提取版本号
|
||||||
for /f "tokens=2 delims=>" %%i in ('findstr /c:"<version>" "%PROJECT_DIR%pom.xml" ^| findstr /v "xml" ^| findstr /n "1" ^| findstr "1:"') do (
|
for /f "tokens=2 delims=>" %%i in ('findstr /c:"<version>" "%PROJECT_DIR%\pom.xml" ^| findstr /v "xml" ^| findstr /n "1" ^| findstr "1:"') do (
|
||||||
for /f "tokens=1 delims=<" %%v in ("%%i") do set VERSION=%%v
|
for /f "tokens=1 delims=<" %%v in ("%%i") do set VERSION=%%v
|
||||||
)
|
)
|
||||||
if "%VERSION%"=="" set VERSION=0.0.1-SNAPSHOT
|
if "%VERSION%"=="" set VERSION=0.0.1-SNAPSHOT
|
||||||
|
|
||||||
:: 4. 准备发布目录
|
:: 4. 准备发布目录
|
||||||
echo.
|
echo.
|
||||||
echo [3/4] 组装发布包...
|
echo [3/4] Assemble distribution...
|
||||||
if exist "%DIST%" rd /s /q "%DIST%"
|
if exist "%DIST%" rd /s /q "%DIST%"
|
||||||
mkdir "%DIST%\workutils" 2>nul
|
mkdir "%DIST%\workutils" 2>nul
|
||||||
|
|
||||||
@@ -63,9 +63,9 @@ powershell -Command "Compress-Archive -Path '%DIST%\workutils' -DestinationPath
|
|||||||
|
|
||||||
:: 5. 完成
|
:: 5. 完成
|
||||||
echo.
|
echo.
|
||||||
echo [4/4] 构建完成!
|
echo [4/4] Build complete!
|
||||||
echo ============================================
|
echo ============================================
|
||||||
echo 产物位置:
|
echo Output:
|
||||||
echo exe : target\workutils.exe
|
echo exe : target\workutils.exe
|
||||||
echo jar : target\workutils-%VERSION%.jar
|
echo jar : target\workutils-%VERSION%.jar
|
||||||
echo zip : target\dist\%ZIPNAME%.zip
|
echo zip : target\dist\%ZIPNAME%.zip
|
||||||
|
|||||||
@@ -132,6 +132,18 @@ public class MyBatisGeneratorPlugin implements Plugin {
|
|||||||
public String generate(List<String> tables, String modelDir, String xmlDir, String mapperDir) throws Exception {
|
public String generate(List<String> tables, String modelDir, String xmlDir, String mapperDir) throws Exception {
|
||||||
return generatorService.generateByTableNames(tables, true, modelDir, xmlDir, mapperDir);
|
return generatorService.generateByTableNames(tables, true, modelDir, xmlDir, mapperDir);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public List<String> getDatasourceNames() {
|
||||||
|
return generatorService.getDatasourceNames();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void switchDatasource(String name) {
|
||||||
|
generatorService.switchDatasource(name);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getCurrentDatasourceName() {
|
||||||
|
return generatorService.getCurrentDatasourceName();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
javafx.application.Platform.runLater(() -> {
|
javafx.application.Platform.runLater(() -> {
|
||||||
|
|||||||
+65
-6
@@ -53,6 +53,9 @@ public class MyBatisGeneratorWindow {
|
|||||||
private TextField mapperDirField;
|
private TextField mapperDirField;
|
||||||
private TreeView<String> projectTree;
|
private TreeView<String> projectTree;
|
||||||
private ToggleGroup fillTargetGroup;
|
private ToggleGroup fillTargetGroup;
|
||||||
|
private ComboBox<String> datasourceCmb;
|
||||||
|
private Label dbUrlLabel;
|
||||||
|
private Label dbUserLabel;
|
||||||
|
|
||||||
/** 表项(含复选框) */
|
/** 表项(含复选框) */
|
||||||
public static class TableItem {
|
public static class TableItem {
|
||||||
@@ -79,6 +82,12 @@ public class MyBatisGeneratorWindow {
|
|||||||
String getDbUrl();
|
String getDbUrl();
|
||||||
String getDbUsername();
|
String getDbUsername();
|
||||||
String generate(List<String> tables, String modelDir, String xmlDir, String mapperDir) throws Exception;
|
String generate(List<String> tables, String modelDir, String xmlDir, String mapperDir) throws Exception;
|
||||||
|
/** 可用的数据源名称列表 */
|
||||||
|
List<String> getDatasourceNames();
|
||||||
|
/** 切换数据源 */
|
||||||
|
void switchDatasource(String name);
|
||||||
|
/** 当前选中的数据源名称 */
|
||||||
|
String getCurrentDatasourceName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MyBatisGeneratorWindow(GeneratorCallback callback, FileOperationHelper fileOperationHelper,
|
public MyBatisGeneratorWindow(GeneratorCallback callback, FileOperationHelper fileOperationHelper,
|
||||||
@@ -177,19 +186,69 @@ public class MyBatisGeneratorWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private HBox createDbInfoSection() {
|
private HBox createDbInfoSection() {
|
||||||
HBox box = new HBox(20);
|
HBox box = new HBox(15);
|
||||||
box.setPadding(new Insets(8, 12, 8, 12));
|
box.setPadding(new Insets(8, 12, 8, 12));
|
||||||
box.setStyle("-fx-background-color: #e8f0fe; -fx-background-radius: 4;");
|
box.setStyle("-fx-background-color: #e8f0fe; -fx-background-radius: 4;");
|
||||||
|
box.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|
||||||
Label urlLabel = new Label("数据库: " + callback.getDbUrl());
|
Label dsLabel = new Label("数据源:");
|
||||||
urlLabel.setFont(Font.font("Consolas", fsBody()));
|
dsLabel.setFont(Font.font("Microsoft YaHei", fsBody()));
|
||||||
Label userLabel = new Label("用户: " + callback.getDbUsername());
|
|
||||||
userLabel.setFont(Font.font("Microsoft YaHei", fsBody()));
|
|
||||||
|
|
||||||
box.getChildren().addAll(urlLabel, userLabel);
|
datasourceCmb = new ComboBox<>();
|
||||||
|
datasourceCmb.setPrefWidth(160);
|
||||||
|
datasourceCmb.setStyle("-fx-font-size: " + fsBody() + "px;");
|
||||||
|
|
||||||
|
// 加载数据源列表
|
||||||
|
refreshDatasourceList();
|
||||||
|
datasourceCmb.setOnAction(e -> {
|
||||||
|
String selected = datasourceCmb.getValue();
|
||||||
|
if (selected != null) {
|
||||||
|
callback.switchDatasource("默认配置".equals(selected) ? null : selected);
|
||||||
|
updateDbInfo();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dbUrlLabel = new Label();
|
||||||
|
dbUrlLabel.setFont(Font.font("Consolas", fsBody() - 1));
|
||||||
|
dbUserLabel = new Label();
|
||||||
|
dbUserLabel.setFont(Font.font("Microsoft YaHei", fsBody() - 1));
|
||||||
|
updateDbInfo();
|
||||||
|
|
||||||
|
Button refreshDsBtn = new Button("刷新");
|
||||||
|
refreshDsBtn.setStyle("-fx-font-size: " + (fsBody() - 1) + "px; -fx-padding: 2 8;");
|
||||||
|
refreshDsBtn.setOnAction(e -> {
|
||||||
|
refreshDatasourceList();
|
||||||
|
updateDbInfo();
|
||||||
|
});
|
||||||
|
|
||||||
|
VBox infoBox = new VBox(3, dbUrlLabel, dbUserLabel);
|
||||||
|
|
||||||
|
box.getChildren().addAll(dsLabel, datasourceCmb, refreshDsBtn, infoBox);
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void refreshDatasourceList() {
|
||||||
|
String current = datasourceCmb.getValue();
|
||||||
|
datasourceCmb.getItems().clear();
|
||||||
|
datasourceCmb.getItems().add("默认配置");
|
||||||
|
datasourceCmb.getItems().addAll(callback.getDatasourceNames());
|
||||||
|
if (current != null && datasourceCmb.getItems().contains(current)) {
|
||||||
|
datasourceCmb.setValue(current);
|
||||||
|
} else {
|
||||||
|
String dsName = callback.getCurrentDatasourceName();
|
||||||
|
if (dsName != null && datasourceCmb.getItems().contains(dsName)) {
|
||||||
|
datasourceCmb.setValue(dsName);
|
||||||
|
} else {
|
||||||
|
datasourceCmb.setValue("默认配置");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDbInfo() {
|
||||||
|
dbUrlLabel.setText("数据库: " + callback.getDbUrl());
|
||||||
|
dbUserLabel.setText("用户: " + callback.getDbUsername());
|
||||||
|
}
|
||||||
|
|
||||||
// ==================== 左侧:项目路径树 ====================
|
// ==================== 左侧:项目路径树 ====================
|
||||||
|
|
||||||
private VBox createProjectTreePanel() {
|
private VBox createProjectTreePanel() {
|
||||||
|
|||||||
+95
-55
@@ -1,5 +1,7 @@
|
|||||||
package com.example.workutils.biz.mybatisgenerator.service.generator;
|
package com.example.workutils.biz.mybatisgenerator.service.generator;
|
||||||
|
|
||||||
|
import com.example.workutils.system.config.DatasourceConfig;
|
||||||
|
import com.example.workutils.system.config.DatasourceConfigManager;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.mybatis.generator.api.MyBatisGenerator;
|
import org.mybatis.generator.api.MyBatisGenerator;
|
||||||
import org.mybatis.generator.config.Configuration;
|
import org.mybatis.generator.config.Configuration;
|
||||||
@@ -25,12 +27,40 @@ public class MyBatisGeneratorService {
|
|||||||
private static final String CONFIG_FILE = "mybatis-generator.xml";
|
private static final String CONFIG_FILE = "mybatis-generator.xml";
|
||||||
private static final String PROPERTIES_FILE = "mybatis-generator.properties";
|
private static final String PROPERTIES_FILE = "mybatis-generator.properties";
|
||||||
|
|
||||||
|
private final DatasourceConfigManager datasourceMgr;
|
||||||
|
/** 当前选中的数据源名称(null = 使用外部配置或内置默认配置) */
|
||||||
|
private String currentDatasourceName;
|
||||||
|
|
||||||
|
public MyBatisGeneratorService(DatasourceConfigManager datasourceMgr) {
|
||||||
|
this.datasourceMgr = datasourceMgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 数据源切换 ====================
|
||||||
|
|
||||||
|
public List<String> getDatasourceNames() {
|
||||||
|
return datasourceMgr.getDatasourceNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatasourceConfig getCurrentDatasource() {
|
||||||
|
if (currentDatasourceName != null) {
|
||||||
|
return datasourceMgr.findByName(currentDatasourceName);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrentDatasourceName() {
|
||||||
|
return currentDatasourceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void switchDatasource(String name) {
|
||||||
|
this.currentDatasourceName = name;
|
||||||
|
log.info("已切换数据源: {}", name != null ? name : "默认配置");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 生成入口 ====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据表名列表生成Mapper文件
|
* 根据表名列表生成Mapper文件
|
||||||
*
|
|
||||||
* @param tableNames 表名列表
|
|
||||||
* @param overwrite 是否覆盖已有文件
|
|
||||||
* @return 生成结果信息
|
|
||||||
*/
|
*/
|
||||||
public String generateByTableNames(List<String> tableNames, boolean overwrite) throws Exception {
|
public String generateByTableNames(List<String> tableNames, boolean overwrite) throws Exception {
|
||||||
return generateInternal(tableNames, overwrite, null, null, null);
|
return generateInternal(tableNames, overwrite, null, null, null);
|
||||||
@@ -46,40 +76,27 @@ public class MyBatisGeneratorService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据表名通配符生成Mapper文件
|
* 根据表名通配符生成Mapper文件
|
||||||
* 先查询数据库中匹配的表,再进行逆向工程
|
|
||||||
*
|
|
||||||
* @param pattern 表名通配符(如 user_%)
|
|
||||||
* @param overwrite 是否覆盖已有文件
|
|
||||||
* @return 生成结果信息
|
|
||||||
*/
|
*/
|
||||||
public String generateByPattern(String pattern, boolean overwrite) throws Exception {
|
public String generateByPattern(String pattern, boolean overwrite) throws Exception {
|
||||||
List<String> matchedTables = queryTablesByPattern(pattern);
|
List<String> matchedTables = queryTablesByPattern(pattern);
|
||||||
|
|
||||||
if (matchedTables.isEmpty()) {
|
if (matchedTables.isEmpty()) {
|
||||||
return "未找到匹配通配符 [" + pattern + "] 的表";
|
return "未找到匹配通配符 [" + pattern + "] 的表";
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("通配符 [{}] 匹配到 {} 张表: {}", pattern, matchedTables.size(), matchedTables);
|
log.info("通配符 [{}] 匹配到 {} 张表: {}", pattern, matchedTables.size(), matchedTables);
|
||||||
return generateInternal(matchedTables, overwrite, null, null, null);
|
return generateInternal(matchedTables, overwrite, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== 数据库查询 ====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据通配符查询数据库中的表
|
* 根据通配符查询数据库中的表
|
||||||
*
|
|
||||||
* @param pattern 表名通配符(支持 % 和 _ 通配符)
|
|
||||||
* @return 匹配的表名列表
|
|
||||||
*/
|
*/
|
||||||
public List<String> queryTablesByPattern(String pattern) throws Exception {
|
public List<String> queryTablesByPattern(String pattern) throws Exception {
|
||||||
List<String> tables = new ArrayList<>();
|
List<String> tables = new ArrayList<>();
|
||||||
Properties props = getConfigurationProperties();
|
DbConnection db = getDbConnection();
|
||||||
|
String dbName = extractDatabaseName(db.url);
|
||||||
|
|
||||||
String url = props.getProperty("db_url");
|
try (Connection conn = DriverManager.getConnection(db.url, db.username, db.password)) {
|
||||||
String username = props.getProperty("db_username");
|
|
||||||
String password = props.getProperty("db_password");
|
|
||||||
|
|
||||||
String dbName = extractDatabaseName(url);
|
|
||||||
|
|
||||||
try (Connection conn = DriverManager.getConnection(url, username, password)) {
|
|
||||||
String sql = "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME LIKE ?";
|
String sql = "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME LIKE ?";
|
||||||
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||||
ps.setString(1, dbName);
|
ps.setString(1, dbName);
|
||||||
@@ -91,26 +108,18 @@ public class MyBatisGeneratorService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tables;
|
return tables;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询数据库中所有表
|
* 查询数据库中所有表
|
||||||
*
|
|
||||||
* @return 所有表名列表
|
|
||||||
*/
|
*/
|
||||||
public List<String> queryAllTables() throws Exception {
|
public List<String> queryAllTables() throws Exception {
|
||||||
List<String> tables = new ArrayList<>();
|
List<String> tables = new ArrayList<>();
|
||||||
Properties props = getConfigurationProperties();
|
DbConnection db = getDbConnection();
|
||||||
|
String dbName = extractDatabaseName(db.url);
|
||||||
|
|
||||||
String url = props.getProperty("db_url");
|
try (Connection conn = DriverManager.getConnection(db.url, db.username, db.password)) {
|
||||||
String username = props.getProperty("db_username");
|
|
||||||
String password = props.getProperty("db_password");
|
|
||||||
|
|
||||||
String dbName = extractDatabaseName(url);
|
|
||||||
|
|
||||||
try (Connection conn = DriverManager.getConnection(url, username, password)) {
|
|
||||||
String sql = "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? ORDER BY TABLE_NAME";
|
String sql = "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? ORDER BY TABLE_NAME";
|
||||||
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||||
ps.setString(1, dbName);
|
ps.setString(1, dbName);
|
||||||
@@ -121,10 +130,39 @@ public class MyBatisGeneratorService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tables;
|
return tables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前生效的数据库连接信息
|
||||||
|
* 优先级: 选中的数据源 > 外部配置(workutils.config) > 内置classpath属性
|
||||||
|
*/
|
||||||
|
private DbConnection getDbConnection() {
|
||||||
|
DatasourceConfig ds = getCurrentDatasource();
|
||||||
|
if (ds != null) {
|
||||||
|
return new DbConnection(ds.getUrl(), ds.getUsername(), ds.getPassword());
|
||||||
|
}
|
||||||
|
// 回退 classpath 配置
|
||||||
|
Properties props = getClasspathProperties();
|
||||||
|
return new DbConnection(
|
||||||
|
props.getProperty("db_url", ""),
|
||||||
|
props.getProperty("db_username", ""),
|
||||||
|
props.getProperty("db_password", "")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 内部数据类:数据库连接信息 */
|
||||||
|
private static class DbConnection {
|
||||||
|
final String url;
|
||||||
|
final String username;
|
||||||
|
final String password;
|
||||||
|
DbConnection(String url, String username, String password) {
|
||||||
|
this.url = url;
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从JDBC URL中提取数据库名
|
* 从JDBC URL中提取数据库名
|
||||||
*/
|
*/
|
||||||
@@ -352,9 +390,22 @@ public class MyBatisGeneratorService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取配置属性
|
* 获取配置属性(优先使用选中的数据源,回退到classpath)
|
||||||
*/
|
*/
|
||||||
public Properties getConfigurationProperties() {
|
public Properties getConfigurationProperties() {
|
||||||
|
Properties props = getClasspathProperties();
|
||||||
|
// 如果选中了数据源,覆盖连接信息
|
||||||
|
DatasourceConfig ds = getCurrentDatasource();
|
||||||
|
if (ds != null) {
|
||||||
|
if (ds.getDriver() != null) props.setProperty("db_driver", ds.getDriver());
|
||||||
|
if (ds.getUrl() != null) props.setProperty("db_url", ds.getUrl());
|
||||||
|
if (ds.getUsername() != null) props.setProperty("db_username", ds.getUsername());
|
||||||
|
if (ds.getPassword() != null) props.setProperty("db_password", ds.getPassword());
|
||||||
|
}
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Properties getClasspathProperties() {
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
try {
|
try {
|
||||||
props.load(getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE));
|
props.load(getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE));
|
||||||
@@ -364,38 +415,27 @@ public class MyBatisGeneratorService {
|
|||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取数据库URL
|
|
||||||
*/
|
|
||||||
public String getDatabaseUrl() {
|
public String getDatabaseUrl() {
|
||||||
return getConfigurationProperties().getProperty("db_url", "");
|
DatasourceConfig ds = getCurrentDatasource();
|
||||||
|
if (ds != null) return ds.getUrl();
|
||||||
|
return getClasspathProperties().getProperty("db_url", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取数据库用户名
|
|
||||||
*/
|
|
||||||
public String getDatabaseUsername() {
|
public String getDatabaseUsername() {
|
||||||
return getConfigurationProperties().getProperty("db_username", "");
|
DatasourceConfig ds = getCurrentDatasource();
|
||||||
|
if (ds != null) return ds.getUsername();
|
||||||
|
return getClasspathProperties().getProperty("db_username", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取Model包路径
|
|
||||||
*/
|
|
||||||
public String getModelPackage() {
|
public String getModelPackage() {
|
||||||
return getConfigurationProperties().getProperty("model_package", "");
|
return getClasspathProperties().getProperty("model_package", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取Mapper包路径
|
|
||||||
*/
|
|
||||||
public String getMapperPackage() {
|
public String getMapperPackage() {
|
||||||
return getConfigurationProperties().getProperty("dao_package", "");
|
return getClasspathProperties().getProperty("dao_package", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取SQL Mapper包路径
|
|
||||||
*/
|
|
||||||
public String getSqlMapperPackage() {
|
public String getSqlMapperPackage() {
|
||||||
return getConfigurationProperties().getProperty("sqlmapper_package", "");
|
return getClasspathProperties().getProperty("sqlmapper_package", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.example.workutils.system.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单条数据源配置
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class DatasourceConfig {
|
||||||
|
|
||||||
|
/** 显示名称(如"开发环境"、"SIT环境") */
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/** JDBC 驱动类 */
|
||||||
|
private String driver = "com.mysql.jdbc.Driver";
|
||||||
|
|
||||||
|
/** JDBC URL */
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
/** 用户名 */
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
/** 密码 */
|
||||||
|
private String password;
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package com.example.workutils.system.config;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多数据源配置管理器
|
||||||
|
* <p>
|
||||||
|
* 从 data/datasources.json 加载数据源列表,供 MyBatis 逆向工程插件选择使用。
|
||||||
|
* 首次运行时自动从 classpath 模板复制到 data/ 目录。
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class DatasourceConfigManager {
|
||||||
|
|
||||||
|
private static final String DATASOURCE_FILE = "data/datasources.json";
|
||||||
|
private static final String TEMPLATE_PATH = "templates/datasources.json";
|
||||||
|
|
||||||
|
private final List<DatasourceConfig> datasources = new ArrayList<>();
|
||||||
|
private Path configFile;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
void init() {
|
||||||
|
configFile = Paths.get(System.getProperty("user.dir"), DATASOURCE_FILE);
|
||||||
|
ensureConfigExists();
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 确保数据源配置文件存在 */
|
||||||
|
private void ensureConfigExists() {
|
||||||
|
if (Files.exists(configFile)) return;
|
||||||
|
try {
|
||||||
|
Files.createDirectories(configFile.getParent());
|
||||||
|
try (InputStream is = getClass().getClassLoader().getResourceAsStream(TEMPLATE_PATH)) {
|
||||||
|
if (is != null) {
|
||||||
|
Files.copy(is, configFile);
|
||||||
|
log.info("已从模板复制数据源配置: {}", configFile.toAbsolutePath());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("复制数据源模板失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
// 兜底:创建空数组
|
||||||
|
try {
|
||||||
|
Files.write(configFile, "[]".getBytes(StandardCharsets.UTF_8));
|
||||||
|
log.info("已创建空数据源配置: {}", configFile.toAbsolutePath());
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("创建数据源配置文件失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重新加载数据源配置 */
|
||||||
|
public synchronized void reload() {
|
||||||
|
datasources.clear();
|
||||||
|
if (!Files.exists(configFile)) return;
|
||||||
|
try {
|
||||||
|
String json = new String(Files.readAllBytes(configFile), StandardCharsets.UTF_8);
|
||||||
|
List<DatasourceConfig> loaded = JSON.parseArray(json, DatasourceConfig.class);
|
||||||
|
if (loaded != null) {
|
||||||
|
datasources.addAll(loaded);
|
||||||
|
}
|
||||||
|
log.info("已加载 {} 套数据源配置", datasources.size());
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("解析数据源配置失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取所有数据源名称列表 */
|
||||||
|
public List<String> getDatasourceNames() {
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
for (DatasourceConfig ds : datasources) {
|
||||||
|
names.add(ds.getName());
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据名称查找数据源配置 */
|
||||||
|
public DatasourceConfig findByName(String name) {
|
||||||
|
return datasources.stream()
|
||||||
|
.filter(ds -> ds.getName().equals(name))
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取配置文件的路径(供设置窗口打开编辑) */
|
||||||
|
public Path getConfigFile() {
|
||||||
|
return configFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "开发环境",
|
||||||
|
"driver": "com.mysql.jdbc.Driver",
|
||||||
|
"url": "jdbc:mysql://localhost:3306/disburse?useUnicode=true&characterEncoding=utf8&useSSL=false",
|
||||||
|
"username": "root",
|
||||||
|
"password": "1Qaz@4772"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SIT环境",
|
||||||
|
"driver": "com.mysql.jdbc.Driver",
|
||||||
|
"url": "jdbc:mysql://sit-server:3306/disburse?useUnicode=true&characterEncoding=utf8&useSSL=false",
|
||||||
|
"username": "sit_user",
|
||||||
|
"password": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "生产环境(只读)",
|
||||||
|
"driver": "com.mysql.jdbc.Driver",
|
||||||
|
"url": "jdbc:mysql://prod-server:3306/disburse?useUnicode=true&characterEncoding=utf8&useSSL=false",
|
||||||
|
"username": "readonly",
|
||||||
|
"password": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user