文章目录
- 代码结构概述
 - 详细解释
 - 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语句中有注释或嵌套的引号时。
 - 连接字符串、用户名和密码应该通过安全的方式传递,而不是硬编码在代码中。
 - 代码中未包含详细的错误处理逻辑,如网络连接失败等情况,实际使用时应添加适当的异常处理。
 


















