谷粒商城实战笔记-一键执行项目SQL脚本

news2024/11/17 0:50:01

文章目录

      • 代码结构概述
      • 详细解释
        • 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代码。

代码结构概述

  1. 主类定义 - 定义了一个名为SqlScriptExecutor的公共类。
  2. 主方法 (main 方法) - 这是程序的入口点,它遍历指定目录下的所有文件。
  3. 执行SQL脚本的方法 (executeSqlScript) - 这个方法负责连接到数据库、创建数据库(如果不存在)、读取并执行SQL脚本文件中的命令。
  4. 执行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语句中有注释或嵌套的引号时。
  • 连接字符串、用户名和密码应该通过安全的方式传递,而不是硬编码在代码中。
  • 代码中未包含详细的错误处理逻辑,如网络连接失败等情况,实际使用时应添加适当的异常处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1991958.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HCIP学习 | OSPF---LSA限制、不规则区域、附录E、选路

目录 Days06(24.8.8)OSPF---LSA限制、不规则区域、附录E、选路 特殊区域 stub 区域, 末节区域 Totally stub :完全的末节区域 NSSA区域:(not so stub area) 非完全末节区域 完全的非完全的末节区域: …

Python 函数(1)

1、函数 函数是带名字的代码块,用于完成具体的工作。要执行函数定义的特定义务,可调用该函数。当需要再程序中多次执行同一项任务时,无需反复编写完成该任务的代码,只需要调用该任务的函数,让其运行即可。 1.1、定义…

【mars3d】GraphicLayer遍历添加数据,正确拿到数据

import * as mars3d from "mars3d"export let map // mars3d.Map三维地图对象 export let graphicLayer // 矢量数据图层 export const mapOptions {scene: {center:{"lat":30.577085,"lng":116.885511,"alt":45203.5,"heading&…

仿真入门——CST软件如何设置分布式计算的共享储存

在 CST Studio Suite 的分布式计算中,常有用户因为某台机器的网络问题丢失某个数据。这里介绍一种方法,可以在使用分布式计算或 MPI 计算时设置共享存储。在这种情况下,不涉及文件传输,所有文件操作都在共享文件的媒介上完成。 数…

【React】详解 App.js 文件

文章目录 一、App.js文件的基本结构1. 引入必要的模块2. 定义根组件3. 导出根组件 二、App.js文件的详细解析1. 函数组件与类组件函数组件类组件 2. 使用CSS模块3. 组织子组件4. 管理组件状态使用useState钩子使用state对象 三、App.js文件的最佳实践1. 保持组件的简洁和模块化…

政策标准、行业动态、安全事件、密码专栏、三所发布、国家互联网中心安全周报。

1、全国网络安全标准化技术委员会关于17项网络安全国家标准项目立项的通知 按照委员会标准制修订工作程序的要求,17项网络安全国家标准的立项工作已经完成,现将清单印发给各工作组,请按照国家标准委和委员会相关规定,认真做好项目…

开展FMEA时如何明确分析对象?

在FMEA过程中,分析对象的选择直接决定了后续工作的方向与质量。一个模糊不清或过于宽泛的分析对象,会导致分析过程冗长低效,甚至遗漏关键风险点。相反,一个精准明确的分析对象,能够让团队集中精力,高效识别…

琪德直流屏监控模块HXTJK002,HXTJK003AB电源模块HXT240D10

直流屏电源模块产品型号:HXT240D05,HXT240D10,HXT240D10Z,HXT220D10,HXT220D05,HXT120D10,HXT120D05,HXT220D10-III,HXT110D10-III,HXT110D20-III,HXT220D20-…

传递绿色动力,引领绿色出行!绿传科技邀您参加2024深圳eVTOL展

2024深圳eVTOL产业发展大会暨低空经济展览会将于9月23-25日在深圳坪山燕子湖国际会展中心召开。展会将通过“两天论坛三天展览”的形式展开,专注未来城市空中交通新形态、民用有人驾驶、无人驾驶航空器、城市低空物流,并讨论eVTOL的整机研发、设计、制造…

七夕情人节有什么好物推荐?五款精品数码产品推荐!

随着七夕情人节的浪漫钟声渐起,你是否在寻找一份既充满爱意又能体现生活品味的礼物?在这个充满甜蜜氛围的日子里,团团为你精心挑选了一份经过个人实测的好物推荐清单。这些礼物不仅代表着时尚与潮流,更是传递心意的桥梁&#xff0…

Redis-哨兵监控(sentinel)

是什么 Docs 吹哨人巡查监控后台master主机是否故障,如果故障了根据投票数自动将某一个从库转换为新主库,继续对外服务 作用:无人值守运维 能干嘛 1.主从监控 监控主从redis的库是否运行正常 2.消息通知 哨兵可以将故障转移的结果发送给客户端 3.…

应急响应-主机安全之系统及进程排查相关命令(Linux操作系统-初级篇)

目录 概述lscpu-显示有关CPU架构的信息uname-查看系统信息lsmod-输出加载的所有模块lastb-输出最后登录失败的用户last-展示用户最近登录信息lastlog-展示所有用户最后的登录时间systemctl-系统服务,开机自启排查crontab-计划任务选项 history-查看历史命令选项常用…

Python 画 等高线图

Python 画 等高线图 flyfish 通过三维图形与投影等高线相结合的方式,能够直观地看到三维函数的形状以及在平面上等值线的分布。 等高线是一种用来表示三维表面在二维平面上的方法。它们是通过在固定高度(或深度)处切割三维表面来创建的平面…

ArcGIS中如何再画一个已经存在的相同属性地类图斑

1.打开边界后,创建要素界面模板下面的内容是空的 2.此时点击组织模板 3.点击新建模板 4.勾选要添加的图层、下一步完成即可。 5.此时创建要素模板就有内容了 6.想要画哪个地类就先点哪个地类,再开始画图即可。 注意:画出来的图斑仅继承了匹配…

TOMCAT远程代码执行

首先下载一个apache-tomcat8.5.39 进入bin目录找到setclasspath.bat 进入文件进行编辑 修改为自己java所在的路径 在bin目录下打开cmd运行startup.bat 然后在文件管理器中搜索cgi-bin 然后在里面创建bat文件存在内容 然后在网页中打开

“奥运精神、数智传递”安通达AI智能外呼系列·企业沟通的金牌选择

北京时间7月27日凌晨,备受瞩目的第三十三届奥林匹克运动会在浪漫之都法国巴黎正式开幕。在全世界各国代表队奋力拼搏、激烈比赛的同时,一束来自中国的科技之光,照亮了推动人工智能发展的道路。 “你好,我是张雨霏/邹敬园&#xff…

PAT 乙级 1022题

题目&#xff1a;D进制的AB 输入两个非负 10 进制整数 A 和 B (≤230−1)&#xff0c;输出 AB 的 D (1<D≤10)进制数。 输入格式&#xff1a; 输入在一行中依次给出 3 个整数 A、B 和 D。 输出格式&#xff1a; 输出 AB 的 D 进制数。 输入样例&#xff1a; 123 456 …

vulnhub靶机tomato记录

https://www.vulnhub.com/entry/tomato-1,557/ 过程 用nmap对目标主机做全端口扫描&#xff0c;dirb做目录扫描&#xff0c;结果如下&#xff1a; 8888端口开放一个web服务&#xff0c;存在Basic认证&#xff0c;试了爆破无果&#xff0c;sun-answerbook是一个在线文档系统&am…

第25课 Scratch入门篇:火箭升空

火箭升空 故事背景&#xff1a; 在未来的世界里&#xff0c;发射火箭机器人来到火箭基地&#xff0c;火箭机器人开始倒计时&#xff0c;当倒计时结束后&#xff0c;火箭飞上天空&#xff01;火箭在天空中越飞越远&#xff0c;越来越小&#xff01;&#xff01;&#xff01; …

拼多多一面0518

nginx作为http服务器&#xff0c;用来反向代理哪些资源 Web应用资源&#xff1a; Nginx最常用来代理Web应用服务器&#xff08;如Apache、Tomcat、Node.js等&#xff09;上的资源。客户端发送的请求首先到达Nginx&#xff0c;Nginx根据配置将请求转发给后端的Web应用服务器处理…