文章目录
- 代码结构概述
- 详细解释
- 1. 主方法 (`main` 方法)
- 2. 执行SQL脚本的方法 (`executeSqlScript` 方法)
- 3. 执行SQL命令的方法 (`executeSqlCommand` 方法)
- 注意事项
课程提供了项目的初始化脚本。
但是要手动逐个建库,执行脚本,还是比较费时间的。
特别是因为虚拟机或者其他原因,学习过程中需要多次初始化数据库,逐个手动执行,很影响效率。
所以,这里写了个Java脚本,一键完成建库、建表、插入初始化数据的工作。
package com.lcy.exercise.mysql;
import cn.hutool.core.util.StrUtil;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
public class SqlScriptExecutor {
private static final String DB_URL = "jdbc:mysql://47.11.7.59:3306/";
private static final String USER = "root"; // 请替换为实际的用户名
private static final String PASS = "68bed551"; // 请替换为实际的密码
public static void main(String[] args) {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
File folder = new File("D:\\BaiduNetdiskDownload\\GuliMall_Resources\\GuliMall\\gulimall\\db");
for (File file : folder.listFiles()) {
if (file.isFile() && file.getName().endsWith(".sql")) {
executeSqlScript(file);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void executeSqlScript(File file) throws Exception {
String dbName = file.getName().replace(".sql", "");
System.out.println(StrUtil.format("当前数据库:{}", dbName));
boolean dbExists = checkIfDatabaseExists(dbName);
Connection conn = null;
try {
// 如果数据库不存在,则创建它
if (!dbExists) {
conn = DriverManager.getConnection(StrUtil.format("{}?useSSL=false",DB_URL), USER, PASS);
Statement stmt = conn.createStatement();
stmt.executeUpdate("CREATE DATABASE " + dbName);
stmt.close();
}
// 连接到数据库
conn = DriverManager.getConnection(StrUtil.format("{}{}?useSSL=false",DB_URL, dbName), USER, PASS);
Statement stmt = conn.createStatement();
// 读取SQL脚本文件
// Read SQL script file
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
StringBuilder sqlCommand = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sqlCommand.append(line).append('\n');
if (line.trim().endsWith(";")) {
executeSqlCommand(stmt, sqlCommand.toString());
sqlCommand.setLength(0); // Reset StringBuilder
}
}
} catch (IOException e) {
System.out.println("Error reading file: " + e.getMessage());
}
} finally {
if (conn != null) {
conn.close();
}
}
}
private static boolean checkIfDatabaseExists(String dbName) throws Exception {
Connection conn = DriverManager.getConnection(StrUtil.format("{}?useSSL=false",DB_URL), USER, PASS);
Statement stmt = conn.createStatement();
String query = "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '" + dbName + "'";
ResultSet rs = stmt.executeQuery(query);
boolean exists = rs.next();
rs.close();
stmt.close();
conn.close();
return exists;
}
private static void executeSqlCommand(Statement stmt, String sqlCommand) {
try {
stmt.execute(sqlCommand);
// System.out.println("Executed: " + sqlCommand);
} catch (Exception e) {
System.out.println("Error executing SQL command: " + sqlCommand);
e.printStackTrace();
}
}
}
下面详细地分析一下上面提供的Java代码。
代码结构概述
- 主类定义 - 定义了一个名为
SqlScriptExecutor
的公共类。 - 主方法 (
main
方法) - 这是程序的入口点,它遍历指定目录下的所有文件。 - 执行SQL脚本的方法 (
executeSqlScript
) - 这个方法负责连接到数据库、创建数据库(如果不存在)、读取并执行SQL脚本文件中的命令。 - 执行SQL命令的方法 (
executeSqlCommand
) - 这个方法用于执行单条SQL命令,并捕获可能发生的异常。
详细解释
1. 主方法 (main
方法)
public static void main(String[] args) {
String path = "D:\\BaiduNetdiskDownload\\GuliMall_Resources\\GuliMall\\gulimall\\db";
File directory = new File(path);
if (!directory.exists() || !directory.isDirectory()) {
System.out.println("Directory does not exist or is not a directory.");
return;
}
for (File file : directory.listFiles()) {
if (file.isFile() && file.getName().endsWith(".sql")) {
String dbName = file.getName().substring(0, file.getName().indexOf('.'));
executeSqlScript(file, dbName);
}
}
}
path
变量存储了要读取的目录路径。- 创建一个
File
对象directory
来表示该目录。 - 检查该路径是否存在并且确实是一个目录。如果不是,打印一条消息并退出程序。
- 使用
listFiles()
方法获取目录下的所有文件,并遍历它们。 - 对于每一个文件,检查它是否是一个
.sql
文件,如果是,则获取文件名(不包括扩展名),这通常会被认为是数据库的名称,并调用executeSqlScript
方法来处理该文件。
2. 执行SQL脚本的方法 (executeSqlScript
方法)
private static void executeSqlScript(File file, String dbName) {
try (Connection conn = DriverManager.getConnection(DB_URL + dbName, USER, PASS)) {
// Check if the database exists and create it if necessary
Statement stmt = conn.createStatement();
String checkDbQuery = "CREATE DATABASE IF NOT EXISTS `" + dbName + "`";
stmt.executeUpdate(checkDbQuery);
// Read SQL script file
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
StringBuilder sqlCommand = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sqlCommand.append(line).append('\n');
if (line.trim().endsWith(";")) {
executeSqlCommand(stmt, sqlCommand.toString());
sqlCommand.setLength(0); // Reset StringBuilder
}
}
} catch (IOException e) {
System.out.println("Error reading file: " + e.getMessage());
}
} catch (Exception e) {
e.printStackTrace();
}
}
- 使用
DriverManager.getConnection()
方法建立与数据库的连接。 - 使用
createStatement()
方法创建一个Statement
对象。 - 执行
CREATE DATABASE IF NOT EXISTS
语句来确保数据库存在。 - 使用
BufferedReader
从文件中逐行读取内容。 - 将读取的内容追加到
StringBuilder
中,直到遇到分号;
结束符。 - 当遇到分号时,调用
executeSqlCommand
方法执行SQL命令,并清空StringBuilder
准备接收下一个SQL命令。
3. 执行SQL命令的方法 (executeSqlCommand
方法)
private static void executeSqlCommand(Statement stmt, String sqlCommand) {
try {
stmt.execute(sqlCommand);
System.out.println("Executed: " + sqlCommand);
} catch (Exception e) {
System.out.println("Error executing SQL command: " + sqlCommand);
e.printStackTrace();
}
}
- 使用
stmt.execute(sqlCommand)
方法执行SQL命令。 - 如果执行成功,打印出执行的SQL命令。
- 如果执行失败,打印出错误信息和堆栈跟踪。
注意事项
- 在实际应用中,建议使用更强大的SQL解析库来处理复杂的SQL语句,特别是当SQL语句中有注释或嵌套的引号时。
- 连接字符串、用户名和密码应该通过安全的方式传递,而不是硬编码在代码中。
- 代码中未包含详细的错误处理逻辑,如网络连接失败等情况,实际使用时应添加适当的异常处理。