sql文件批处理程序-java桌面应用

news2024/10/6 2:32:19

 项目效果:

 

 

 

支持sql文件夹批处理,选中文件夹或者sql文件

支持测试连接,可以校验数据库配置

支持报错回显,弹出报错文件名以及问题语句

支持在程序中修改错误语句,用户可以选择保存修改内容继续执行或不保存修改只执行

支持动态显示执行进度

支持自动识别文件编码进行解析

DatabaseImportPage为主程序入口

代码逻辑

数据库连接池

引入所需要的包,我这里导入了mysql和oracle的包

接着我们创建mysql数据库连接池

public class MysqlConnection {
    public static Connection connection; // 声明Connection对象
    public MysqlConnection(String url, String username, String password) throws SQLException, ClassNotFoundException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        this.connection = getConnection(url, username, password);
    }


    public static void main(String[] args) throws SQLException, ClassNotFoundException { // 主方法,测试连接
        String dbAddress = "localhost:3306";
        String dbname = "sqltool";
        String user = "root";
        String password = "shangyi";
        String type = "mysql";

        String url = "jdbc:mysql://localhost:3306/sqltool";

        MysqlConnection m = new MysqlConnection(url,user,password);
        java.sql.Connection con = m.connection;

    }

}

oracle数据库连接池

public class OracleConnection {

    private static OracleConnection oracleConnection;
    public static Connection connection; // 声明Connection对象
    public OracleConnection(String url, String username, String password) throws SQLException {
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

        this.connection = DriverManager.getConnection(url, username, password);
    }


    public static void main(String[] args) throws SQLException { // 主方法,测试连接
    }
}

我们的程序主函数是 DatabaseImportPage,我们在主程序里编写函数与数据库连接池交互

我们先创建了一个Connection对象并设置为null,接着我们根据传入的参数确定他需要oracle和mysql两个连接对象中的哪一个,然后将创建好的连接对象与我们之前创建的Connection连接起来


        Connection con = null;
        if (dbtype == "mysql") {
            String url = "jdbc:" + dbtype + "://" + dbAddress + "/" + dbname;

            MysqlConnection mysql;
            try {
                mysql = new MysqlConnection(url, user, password);
            } catch (SQLException e) {
                JOptionPane.showMessageDialog(null, "连接失败:" + e.getMessage(), "提示", JOptionPane.ERROR_MESSAGE);
                throw new RuntimeException(e);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }

            con = mysql.connection;


        }else{
            String url = "jdbc:" + dbtype +":thin:@"+dbAddress+":"+dbname;

            System.out.println(url);

            OracleConnection oracleConnection;
            try {
                oracleConnection = new OracleConnection(url,user,password);
            } catch (SQLException e) {
                JOptionPane.showMessageDialog(null, "连接失败:" + e.getMessage(), "提示", JOptionPane.ERROR_MESSAGE);
                throw new RuntimeException(e);
            }
            con = oracleConnection.connection;
        }

sql文件读取

首先,我们编写文本识别函数

这里我们用到了 juniversalchardet 这个包,他可以帮助我们识别文本的编码格式,这里我们创建一个bufferInputStream对象来读取文本内容,然后创建一个UniversalDetector对象来检测输入的文本,得到结果就结束循环

我们最后返回得到的字符个编码格式

public static Charset detectFileEncoding(String filePath) throws IOException {
        FileInputStream fis = new FileInputStream(new File(filePath));
        BufferedInputStream bis = new BufferedInputStream(fis);

        Charset charset = Charset.defaultCharset();
        byte[] buffer = new byte[4096];
        UniversalDetector detector = new UniversalDetector(null);

        int bytesRead;
        while ((bytesRead = bis.read(buffer)) != -1) {
            if (detector.isDone()) {
                break;
            }

            detector.handleData(buffer, 0, bytesRead);
        }

        detector.dataEnd();
        String encoding = detector.getDetectedCharset();
        if (encoding != null) {
            charset = Charset.forName(encoding);
        }

        detector.reset();
        bis.close();
        fis.close();

        return charset;
    }

接着,我们编写读取和写入文件的代码,以及递归查询文件夹下所有的sql文本的函数

public class FileHandle {

    // 读取文本内容
    public static String readFileContent(String filePath,String type) throws FileNotFoundException {
        String encoding = type;
        try {
            Charset fileEncoding = FileEncoding.detectFileEncoding(filePath);
            System.out.println("File Encoding: " + fileEncoding.name());
            encoding = fileEncoding.name();
        } catch (IOException e) {
            System.out.println("Error occurred while detecting file encoding: " + e.getMessage());
        }

        StringBuilder content = new StringBuilder();
        FileReader fileHandle = new FileReader(filePath);

//        使用系统默认的编码格式读取
//        try (BufferedReader reader = new BufferedReader(new FileReader(filePath)) ) {
//            String line;
//            while ((line = reader.readLine()) != null) {
//                content.append(line).append("\n");
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), encoding))) {
            String line;
            while ((line = reader.readLine()) != null) {
                // 处理每行文本
                content.append(line).append("\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return content.toString();
    }

//  指定格式写入文本
    public static void SaveDate(String sqlFilePath,String text,String type){
        try {
            // 指定文件编码为UTF-8
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(sqlFilePath), type));

            // 写入文本到文件
            writer.write(text);

            // 关闭文件写入流
            writer.close();

        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("写入文件时发生错误:" + e.getMessage());
        }

    }

    public static List<String> findSqlFiles(File folder) {
        List<String> sqlFilesList = new ArrayList<>();

        File[] files = folder.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".sql");
            }
        });

        if (files != null) {
            for (File file : files) {
                // 处理SQL文件,例如读取文件内容
                String filePath = file.getAbsolutePath();
                sqlFilesList.add(filePath);

                // 在这里可以使用文件读取方法来读取SQL文件的内容
            }
        }

        // 递归处理子文件夹
        File[] subfolders = folder.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.isDirectory();
            }
        });

        if (subfolders != null) {
            for (File subfolder : subfolders) {
                sqlFilesList.addAll(findSqlFiles(subfolder));
            }
        }

        return sqlFilesList;
    }
}

主页面

在主页面中,我们继承JFrame类,实现swing页面

接着我们创建数据库连接对象,再调用文件函数去拿所有的sql文件中的sql语句

然后,将sql语句交给执行函数执行,在执行的过程中,调用进度监督程序ProgressBarPage去实时反馈程序的进度

如果遇到程序出错的情况则启动报错程序DebugPage,去回显相关问题语句


public class DatabaseImportPage extends JFrame{

    private JTextField dbAddressField;
    private JPasswordField passwordField;
    private JTextField userField;
    private JTextField folderField;
    private JTextField dbNameField;
    protected static JTextField FileTypeField;

    boolean continueExecute = true;

    public DatabaseImportPage() {
        setTitle("数据库批量导入工具");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(600, 400);
//        setLayout(new GridLayout(8, 2)); // 添加文件编码输入框
        setLayout(new GridLayout(7, 2));
        ImageIcon icon = new ImageIcon("src/pic/icon.jpg");
        setIconImage(icon.getImage());

        JLabel dbTypeLabel = new JLabel("服务器类型:");
        JComboBox<String> dbTypecomboBox = new JComboBox<>(new String[]{"mysql", "oracle"});

        JLabel dbAddressLabel = new JLabel("服务器地址:");
        dbAddressField = new JTextField();
        JLabel dbName = new JLabel("数据库或服务名称:");
        dbNameField = new JTextField();
        JLabel passwordLabel = new JLabel("密码:");
        passwordField = new JPasswordField();
        JLabel userLabel = new JLabel("用户:");
        userField = new JTextField();

        JLabel fileTypeLabel = new JLabel("文件编码:");
        FileTypeField = new JTextField("UTF-8");

        JPanel panel = new JPanel(new GridLayout(1, 2));
        JLabel folderLabel = new JLabel("文件夹位置:");
        folderField = new JTextField();
        JButton folderButton = new JButton("选择文件夹");
        panel.add(folderField);
        panel.add(folderButton);

        JButton importButton = new JButton("开始导入");
        JButton testConnectionButton = new JButton("测试连接");

//        字体居中
        dbTypeLabel.setHorizontalAlignment(SwingConstants.CENTER);
        dbAddressLabel.setHorizontalAlignment(SwingConstants.CENTER);
        dbName.setHorizontalAlignment(SwingConstants.CENTER);
        passwordLabel.setHorizontalAlignment(SwingConstants.CENTER);
        userLabel.setHorizontalAlignment(SwingConstants.CENTER);
        folderLabel.setHorizontalAlignment(SwingConstants.CENTER);
        fileTypeLabel.setHorizontalAlignment(SwingConstants.CENTER);

//        字体大小
        Font labelFont = new Font("Font.BOLD", Font.PLAIN, 16); // 替换 "Arial" 和 16 为你想要的字体和大小
        dbTypeLabel.setFont(labelFont);
        dbAddressLabel.setFont(labelFont);
        dbName.setFont(labelFont);
        passwordLabel.setFont(labelFont);
        userLabel.setFont(labelFont);
        folderLabel.setFont(labelFont);
        fileTypeLabel.setFont(labelFont);

        add(dbTypeLabel);
        add(dbTypecomboBox);

        add(dbAddressLabel);
        add(dbAddressField);
        add(dbName);
        add(dbNameField);
        add(userLabel);
        add(userField);
        add(passwordLabel);
        add(passwordField);

//        add(fileTypeLabel);
//        add(FileTypeField);

        add(folderLabel);
        add(panel);

        add(importButton);
        add(testConnectionButton);

        // 导入文件夹下sql文件,并测试连接
        importButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 获取文本框中的值
                String dbType = (String) dbTypecomboBox.getSelectedItem();
                String dbAddress = dbAddressField.getText();
                String dbName = dbNameField.getText();
                String password = new String(passwordField.getPassword());
                String user = userField.getText();
                String folder = folderField.getText();
                String fileType = FileTypeField.getText(); // 文件编码格式

                // 执行导入操作,你可以在这里调用相应的方法或函数
                importData(dbAddress,dbName ,user, password, folder,dbType,fileType);
            }
        });

        // 测试数据库配置是否成功
        testConnectionButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 获取文本框中的值
                String dbAddress = dbAddressField.getText();
                String dbName = dbNameField.getText();
                String password = new String(passwordField.getPassword());
                String user = userField.getText();
                String type = (String) dbTypecomboBox.getSelectedItem();

                // 执行测试连接的操作,你可以在这里调用相应的方法或函数
                try {
                    testDatabaseConnection(dbAddress,dbName ,user, password,type);
                } catch (SQLException ex) {
                    throw new RuntimeException(ex);
                }
            }
        });


        // 选择文件夹或者文件
        folderButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser fileChooser = new JFileChooser();
                fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);

                int result = fileChooser.showOpenDialog(null);

                if (result == JFileChooser.APPROVE_OPTION) {
                    // 用户选择了文件或文件夹
                    File selectedFile = fileChooser.getSelectedFile();
                    String selectedPath = selectedFile.getAbsolutePath();
                    folderField.setText(selectedPath);
                } else {
                    // 用户取消了选择
                    folderField.setText("");
                }
            }
        });
    }

    // 添加导入数据的逻辑方法
    private void importData(String dbAddress,String dbname, String user, String password, String folderPath,String dbtype,String fileType)  {
//        dbAddress = "localhost:3306";
//        dbname = "sqltool";
//        user = "root";
//        password = "shangyi";
//        folderPath = "C:\\Users\\33718\\Desktop\\test\\mysql";
//        dbtype = "mysql";

        //        oracle配置
//        dbAddress = "localhost:1521";
//        dbname = "XE";
//        user = "C##SHANGYI1";
//        password = "1";
//        folderPath = "C:\\Users\\33718\\Desktop\\test\\oracle";
//        dbtype = "oracle";


        Connection con = null;
        if (dbtype == "mysql") {
            String url = "jdbc:" + dbtype + "://" + dbAddress + "/" + dbname;

            MysqlConnection mysql;
            try {
                mysql = new MysqlConnection(url, user, password);
            } catch (SQLException e) {
                JOptionPane.showMessageDialog(null, "连接失败:" + e.getMessage(), "提示", JOptionPane.ERROR_MESSAGE);
                throw new RuntimeException(e);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }

            con = mysql.connection;


        }else{
            String url = "jdbc:" + dbtype +":thin:@"+dbAddress+":"+dbname;

            System.out.println(url);

            OracleConnection oracleConnection;
            try {
                oracleConnection = new OracleConnection(url,user,password);
            } catch (SQLException e) {
                JOptionPane.showMessageDialog(null, "连接失败:" + e.getMessage(), "提示", JOptionPane.ERROR_MESSAGE);
                throw new RuntimeException(e);
            }
            con = oracleConnection.connection;
        }


        Statement statement = null; // 创建声明对象
        try {
            statement = con.createStatement();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        java.util.List<String> sqlFiles = new ArrayList<>();

        if (folderPath.endsWith(".sql")) {
            sqlFiles.add(folderPath);
        } else {
            File folder = new File(folderPath);
            sqlFiles = FileHandle.findSqlFiles(folder);
        }

        ProgressBarPage progressBarPage = ProgressBarPage.getProgressBarPage();

        Statement finalStatement = statement;

        if (sqlFiles.size() == 0){
            JOptionPane.showMessageDialog(null, "文件夹为空", "提示", JOptionPane.ERROR_MESSAGE);
            return ;
        }
        int length = 100 / sqlFiles.size(); // 进度条的长度

        java.util.List<String> finalSqlFiles = sqlFiles;

        SwingWorker<Void, ProgressBarPage.ProgressData> worker = new SwingWorker<Void, ProgressBarPage.ProgressData>() {
            @Override
            protected Void doInBackground() throws Exception {
                int totalTasks = finalSqlFiles.size();

                for (int i = 0; i < totalTasks; i++) {
                    if(! continueExecute){
                        break;
                    }
                    // 模拟执行任务
                    String sql = "执行:" + finalSqlFiles.get(i);
                    updateProgress(i+1, totalTasks, sql);

//                    try {
//                        Thread.sleep(500); // 模拟耗时操作
                    ExcuteSql(finalStatement, finalSqlFiles.get(i), finalSqlFiles,fileType);

//                    } catch (InterruptedException ex) {
//                        ex.printStackTrace();
//                    }
                }

                return null;
            }

            @Override
            protected void process(List<ProgressBarPage.ProgressData> chunks) {
                // 更新进度条和SQL信息
                for (ProgressBarPage.ProgressData data : chunks) {
                    ProgressBarPage.setProcess(data.getProgress());
                    ProgressBarPage.setRunningSql(data.getSql() );
                }
            }

            private void updateProgress(int currentTask, int totalTasks, String sql) {
                int progress = (int) ((double) currentTask / totalTasks * 100);
                publish(new ProgressBarPage.ProgressData(progress, sql));
            }

            @Override
            protected void done() {
                // 任务完成后执行操作
                System.out.println("执行完毕");
                ProgressBarPage.setRunningSql("执行完毕");
                continueExecute = true;
            }
        };

        worker.execute();
    }


    private void ExcuteSql(Statement statement, String sqlFilePath, java.util.List<String> SqlFiles,String fileType){

                String result = new String();

                try {  // 捕获文件未取到的 exception
                    result = FileHandle.readFileContent(sqlFilePath,fileType);
                } catch (FileNotFoundException e) {
                    throw new RuntimeException(e);
                }

                if(result.equals("")){
                    JOptionPane.showMessageDialog(null, "文件读取失败", "", JOptionPane.INFORMATION_MESSAGE);
                    this.continueExecute = false;
                    return;
                }

                String[] lines = result.split("\n");
                for (String line : lines) {
                    if(this.continueExecute){
                        try {
                            System.out.println(line);
                            statement.execute(line);
                        } catch (SQLException e) { // 捕获sql异常,提示用用户修改
                            DeBugPage newFrame = new DeBugPage(line,lines,sqlFilePath, SqlFiles,statement,e);

                            this.continueExecute = false;
                            throw new RuntimeException(e);
                        }
                    }else break;
                }
    }


    // 添加测试数据库连接的逻辑方法
    private void testDatabaseConnection(String dbAddress, String dbname,String user, String password,String type) throws SQLException {
//        mysql配置
//        dbAddress = "localhost:3306";
//        dbname = "sqltool";
//        user = "root";
//        password = "shangyi";
//        folderPath = "C:\Users\33718\Desktop\test";
//        type = "mysql";

//        oracle配置
//        dbAddress = "localhost:1521";
//        dbname = "XE";
//        user = "C##SHANGYI1";
//        password = "1";
//        String folderPath = "C:\\Users\\33718\\Desktop\\test";
//        type = "oracle";

        Connection connection = null;
        if(type == "mysql"){
            String url = "jdbc:" + type +"://"+dbAddress+"/" + dbname;

            System.out.println(url);

            try {
                connection = DriverManager.getConnection(url, user, password);
                JOptionPane.showMessageDialog(null, "连接成功", "提示", JOptionPane.INFORMATION_MESSAGE);
            }catch (SQLException e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog(null, "连接失败:" + e.getMessage(), "提示", JOptionPane.ERROR_MESSAGE);
            } catch (Exception e){
                JOptionPane.showMessageDialog(null, "连接失败:" + e.getMessage(), "提示", JOptionPane.ERROR_MESSAGE);
            }
        }else{
            String url = "jdbc:" + type +":thin:@"+"//"+dbAddress+"/"+dbname;
            try {

                OracleConnection oracleConnection = new OracleConnection(url,user,password);
                JOptionPane.showMessageDialog(null, "连接成功", "提示", JOptionPane.INFORMATION_MESSAGE);
            }catch (SQLException e) {
                // 捕获数据库连接异常
                e.printStackTrace();
                JOptionPane.showMessageDialog(null, "连接失败:" + e.getMessage(), "提示", JOptionPane.ERROR_MESSAGE);
            } catch (Exception e){
                JOptionPane.showMessageDialog(null, "连接失败:" + e.getMessage(), "提示", JOptionPane.ERROR_MESSAGE);
            }

        }

    }


    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                DatabaseImportPage importApp = new DatabaseImportPage();
                importApp.setVisible(true);
            }
        });

    }

}

错误处理

在错误处理页面,先根据主页面传递的错误信息进行现场回显,显示错误日志,错误的sql语句,以及报错sql语句的具体位置等信息

用户可以在页面中直接修改该语句,可以选择执行并保存,也可以选择只执行不报错修改内容

如果在执行剩余sql语句的过程中又出现报错,会继续弹出错处处理页面


public class DeBugPage extends JFrame {
//    private static DeBugPage deBugPage;
    private static Statement statement;

    static boolean continueExecute = true;

    boolean AllOver = false;

    public DeBugPage(String line, String[] SqlFile, String sqlFilePath,java.util.List<String> sqlFilePaths,Statement statement,SQLException e) {

        ImageIcon icon = new ImageIcon("src/pic/icon.jpg");
        setIconImage(icon.getImage());

        this.statement = statement;

        this.AllOver = false;

        JTextArea textArea = new JTextArea(
                    "错误文件:"+ sqlFilePath+"\n" +
                            "错误语句:"+line
        );

        StringBuilder res = new StringBuilder();
        for(String sql : SqlFile){
            res.append(sql);
            res.append("\n");
        }

//        计算问题sql语句位置
        int startIndex = res.indexOf(line.trim());

        JTextPane textPane2 = new JTextPane();
        textPane2.setText(res.toString());

//        修改样式,将问题sql进行高亮显示
        // 创建一个样式
        StyleContext styleContext = new StyleContext();
        Style style = styleContext.addStyle("CustomStyle", null);
        StyleConstants.setForeground(style, Color.RED); // 设置文本颜色为红色

        // 创建一个文档
        StyledDocument document = textPane2.getStyledDocument();

        // 设置文档的样式
        document.setCharacterAttributes(startIndex, line.trim().length(), style, true);

        // 显示错误expection
        String exceptionText = e.toString();
        JTextPane textPane3 = new JTextPane();
        textPane3.setText(exceptionText.toString());

        textArea.setEditable(false);  // 文件路径和具体语句不可编辑
        JScrollPane scrollPane = new JScrollPane(textArea);  // 错误语句显示

        JScrollPane scrollPane2 = new JScrollPane(textPane2); // 源文件显示

        JScrollPane scrollPane3 = new JScrollPane(textPane3); // 报错信息回显

//        JPanel panel = new JPanel(new GridLayout(2, 1));
        JPanel panel = new JPanel(new GridBagLayout());

//        设置二者的位置
        GridBagConstraints constraints = new GridBagConstraints();

        // 设置第一个 JScrollPane
        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.gridwidth = 1; // 比例为 1
        constraints.gridheight = 1;
        constraints.weightx = 1.0;
        constraints.weighty = 0.25; // 比例为 1:3
        constraints.fill = GridBagConstraints.BOTH;
        panel.add(scrollPane, constraints);

        // 设置第二个 JScrollPane
        constraints.gridx = 0;
        constraints.gridy = 1;
        constraints.gridwidth = 1; // 比例为 1
        constraints.gridheight = 1;
        constraints.weightx = 1.0;
        constraints.weighty = 1.0; // 比例为 1:4
        constraints.fill = GridBagConstraints.BOTH;
        panel.add(scrollPane2, constraints);

        // 设置第三个 JScrollPane
        constraints.gridx = 0;
        constraints.gridy = 2;
        constraints.gridwidth = 1; // 比例为 1
        constraints.gridheight = 1;
        constraints.weightx = 1.0;
        constraints.weighty = 1.0; // 比例为 1:4
        constraints.fill = GridBagConstraints.BOTH;
        panel.add(scrollPane3, constraints);


//        添加两个新的按钮
        constraints.gridx = 0;
        constraints.gridy = 3;
        constraints.gridwidth = 2; // 一行两列
        constraints.gridheight = 1;
        constraints.weightx = 1.0;
        constraints.weighty = 0.0; // 不分配垂直空间
        constraints.fill = GridBagConstraints.HORIZONTAL; // 水平填充

        JPanel panel2 = new JPanel(new GridLayout(1, 2));
        // 创建保存修改按钮
        JButton saveButton = new JButton("保存并执行");
        panel2.add(saveButton);

        // 创建继续执行按钮
        JButton continueButton = new JButton("继续执行");
        panel2.add(continueButton);

        panel.add(panel2,constraints);

        add(panel);

        setSize(500, 400);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setVisible(true);

        saveButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
//                保存文本
                String text = textPane2.getText();
//                SaveDate(sqlFilePath,text);
                FileHandle.SaveDate(sqlFilePath,text,DatabaseImportPage.FileTypeField.getText());
                JOptionPane.showMessageDialog(null, "保存成功", "提示", JOptionPane.INFORMATION_MESSAGE);

//                继续运行sql文件
                String restSql = textPane2.getText().substring(startIndex);
                ContineExecute(restSql,sqlFilePath,sqlFilePaths);
                dispose(); // 销毁自身对象
            }
        });

        continueButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String restSql = textPane2.getText().substring(startIndex);
                ContineExecute(restSql,sqlFilePath,sqlFilePaths);
                dispose(); // 销毁自身对象

            }
        });
    }

//    按照系统默认编码写入
    private static void SaveDate(String sqlFilePath,String text){
//        保存文本
        try {
            // 创建一个 FileWriter 对象来写入文件
            FileWriter writer = new FileWriter(sqlFilePath);

            // 写入文本到文件
            writer.write(text);

            // 关闭文件写入流
            writer.close();

            System.out.println("文本已成功写入文件:" + sqlFilePath);
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("写入文件时发生错误:" + e.getMessage());
        }

    }

//  点击继续执行的按钮
    private static void ContineExecute(String restSql,String sqlFilePath,java.util.List<String> sqlFilePaths){

        //  标记剩余sql执行过程中是否有错
        boolean allSqlSuccessful = true;

        //  先处理本文件下未执行的sql语句
        String[] lines = restSql.split("\n");
        for (String line : lines) {
            if(allSqlSuccessful){
                try {
                    System.out.println(line);
                    statement.execute(line);
                } catch (SQLException e) { // 捕获sql异常,提示用用户修改
                    // 重新创建一个debug页面对象
                    e.printStackTrace();
                    allSqlSuccessful = false;
                    DeBugPage newFrame = new DeBugPage(line,lines,sqlFilePath, sqlFilePaths,statement,e);
                    break;
                }
            }
        }


//        接下来执行剩余的sql文件下的sql语句
//        先得到当前sql文件的位置的索引
        if(allSqlSuccessful){
            int index = -1;
            for(int i = 0;i<sqlFilePaths.size();i++){
                System.out.println(sqlFilePaths.get(i));
                if(sqlFilePaths.get(i).equals(sqlFilePath)){
                    index = i; // 记录索引
                    break;
                }
            }

            if(index < sqlFilePaths.size()-1)
                ExcuteSql2(statement,sqlFilePaths,index);
            // 执行出现错误的sql文件后面的所有文件
//            ExcuteSql2(statement,sqlFilePaths,index);
        }


    }


    private static void ExcuteSql2(Statement statement,java.util.List<String> sqlFiles,int start){

        ProgressBarPage progressBarPage = ProgressBarPage.getProgressBarPage();
        Statement finalStatement = statement;
        int length = 100 / sqlFiles.size(); // 进度条的长度
        java.util.List<String> finalSqlFiles = sqlFiles;
        java.util.List<String> finalSqlFiles1 = sqlFiles;

        SwingWorker<Void, ProgressBarPage.ProgressData> worker = new SwingWorker<Void, ProgressBarPage.ProgressData>() {
            @Override
            protected Void doInBackground() throws Exception {
                int totalTasks = finalSqlFiles1.size();

                for (int i = start+1; i < totalTasks; i++) {
//                    System.out.println(finalSqlFiles.get(i));

                    if(!continueExecute){
                        break;
                    }
                    // 模拟执行任务
                    String sql = "执行:" + finalSqlFiles1.get(i);
                    updateProgress(i+1, totalTasks, sql);

                    try {
                        Thread.sleep(500); // 模拟耗时操作
                        ExcuteSql(finalStatement, finalSqlFiles.get(i), finalSqlFiles);

                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }

                return null;
            }

            @Override
            protected void process(List<ProgressBarPage.ProgressData> chunks) {
                // 更新进度条和SQL信息
                for (ProgressBarPage.ProgressData data : chunks) {
                    ProgressBarPage.setProcess(data.getProgress());
                    ProgressBarPage.setRunningSql(data.getSql() );
                }
            }

            private void updateProgress(int currentTask, int totalTasks, String sql) {
                int progress = (int) ((double) currentTask / totalTasks * 100);
                publish(new ProgressBarPage.ProgressData(progress, sql));
            }

            @Override
            protected void done() {
                // 任务完成后执行操作
                System.out.println("执行完毕");
                continueExecute = true;
                ProgressBarPage.setRunningSql("执行完毕");

            }
        };

        worker.execute();

    }

    private static void ExcuteSql(Statement statement, String sqlFilePath, java.util.List<String> SqlFiles){

        Boolean continueExecute = true;

        String result = new String();

        try {  // 读取该路径下所有sql语句
            result = FileHandle.readFileContent(sqlFilePath,DatabaseImportPage.FileTypeField.getText());
        } catch (FileNotFoundException e) { // 捕获文件未取到的 exception
            throw new RuntimeException(e);
        }

        String[] lines = result.split("\n");
        for (String line : lines) {
            if(continueExecute){
                try {
                    statement.execute(line);
                } catch (SQLException e) { // 捕获sql异常,提示用用户修改
                    DeBugPage newFrame = new DeBugPage(line,lines,sqlFilePath, SqlFiles,statement,e);
                    continueExecute = false;
                    System.out.println("error");
                    throw new RuntimeException(e);
                }
            }else break;
        }
    }
}

进度监控

我们实现一个进度条页面,与主程序中的sql执行进度进行交互,通过某一特定数据区传递进度信息,实现实时监控


public class ProgressBarPage extends Frame{

    private static  ProgressBarPage progressBarPage ;

    static JFrame  frame = new JFrame("进度");
    static JProgressBar progressBar = new JProgressBar(0, 100);

    static JLabel statusLabel = new JLabel("正在执行:");

    private ProgressBarPage(){
        ImageIcon icon = new ImageIcon("src/pic/icon.jpg");
        frame.setIconImage(icon.getImage());
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setSize(400, 150);
        frame.setLayout(new BorderLayout());

        progressBar.setValue(0);
        progressBar.setStringPainted(true);

//        frame.add(progressBar);
        frame.add(progressBar, BorderLayout.NORTH); // 将进度条放在上方
        frame.add(statusLabel, BorderLayout.CENTER); // 将状态信息放在中间

        // 创建窗口关闭监听器
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {

                frame.setVisible(true);
            }
        });

        frame.setVisible(true);
    }

    public static void setProcess(int i){
        progressBar.setValue(i);
    }

    public static void setRunningSql(String str){
        statusLabel.setText(str);
    }

    public  static ProgressBarPage getProgressBarPage(){
            return new ProgressBarPage();
    }

    public static void close(){
        progressBarPage.setVisible(false);
    }

    public static class ProgressData {
        private int progress;
        private String sql;

        public ProgressData(int progress, String sql) {
            this.progress = progress;
            this.sql = sql;
        }

        public int getProgress() {
            return progress;
        }

        public String getSql() {
            return sql;
        }
    }

    public static void main(String[] args) {
        ProgressBarPage progressBarPage = new ProgressBarPage();

    }

}

程序链接:

https://github.com/ShangyiAlone/sqlTool.git

SQL文件批处理程序: sql文件批处理程序

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

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

相关文章

线性代数 第四章 线性方程组

一、矩阵形式 经过初等行变换化为阶梯形矩阵。当&#xff0c;有解&#xff1b;当&#xff0c;有非零解。 有解&#xff0c;等价于 可由线性表示 克拉默法则&#xff1a;非齐次线性方程组中&#xff0c;系数行列式&#xff0c;则方程组有唯一解&#xff0c;且唯一解为 其中是…

TestCenter测试管理工具

estCenter&#xff08;简称TC&#xff09;一款广受好评的测试管理工具&#xff0c;让测试工作更规范、更有效率&#xff0c;实现测试流程无纸化&#xff0c;测试数据资产化。 产品概述 TC流程图 产品功能 一、案例库 案例库集中化管理&#xff0c;支持对测试用例集中管理&…

Gartner报告 | Mendix再次成为低代码领导者!Mendix在愿景完整性和执行能力领域的排名最为靠前。

本文作者: Hans de Visser, Mendix 首席产品官 在最新发布的2023 Gartner魔力象限图™ 中对于企业级低代码应用程序平台&#xff0c;Gartner指出&#xff0c;企业IT领导者需要满足“应用程序开发向更高抽象级别迈进的步伐&#xff0c;并采用低代码平台来加速应用程序开发。” 此…

【华为】路由器以PPPoE拨号接入广域网

组网需求 用户希望以PPPoE拨号方式接入广域网&#xff0c;如图1所示&#xff0c;Router作为PPPoE客户端&#xff0c;得到PPPoE服务器的认证后获得IP地址&#xff0c;实现用户接入互联网的需求。内网网关地址&#xff08;即VLANIF1接口的IP地址&#xff09;为10.137.32.1/24。 …

N-131基于jsp,ssm物流快递管理系统

开发工具&#xff1a;eclipse&#xff0c;jdk1.8 服务器&#xff1a;tomcat7.0 数据库&#xff1a;mysql5.7 技术&#xff1a; springspringMVCmybaitsEasyUI 项目包括用户前台和管理后台两部分&#xff0c;功能介绍如下&#xff1a; 一、用户(前台)功能&#xff1a; 用…

UE5 Android下载zip文件并解压缩到指定位置

一、下载是使用市场的免费插件 二、解压缩是使用市场的免费插件 三、Android路径问题 windows平台下使用该插件没有问题&#xff0c;只是在Android平台下&#xff0c;只有使用绝对路径才能进行解压缩&#xff0c;所以如何获得Android下的绝对路径&#xff1f;增加C文件获得And…

生态扩展:Flink Doris Connector

生态扩展&#xff1a;Flink Doris Connector 官网地址&#xff1a; https://doris.apache.org/zh-CN/docs/dev/ecosystem/flink-doris-connector flink的安装&#xff1a; tar -zxvf flink-1.16.0-bin-scala_2.12.tgz mv flink-1.16.0-bin-scala_2.12.tgz /opt/flinkflink环境…

【c++|opencv】二、灰度变换和空间滤波---5.中值滤波

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 1. 中值滤波 #include<iostream> #include<opencv2/opencv.hpp> #include"Salt.h"using namespace cv; using namespace std;voi…

NEFU离散数学实验4-数论

相关概念 离散数学中的数论相关概念和公式如下&#xff1a; 1.最大公约数(GCD)&#xff1a;两个整数a和b的最大公约数是能够同时整除a和b的最大正整数&#xff0c;记作GCD(a, b)。 2.最小公倍数(LCM)&#xff1a;两个整数a和b的最小公倍数是能够同时整除a和b的最小正整数&#…

MySQL-Galera-Cluster集群详细介绍

目录 一、什么是Mysql集群&#xff1f;1.单节点mysql存在的常见问题2.mysql集群介绍3.Mysql集群的优点和风险 二、Mysql集群的一些疑问1.mysql的AB复制和Galera Cluster有什么区别&#xff1f;2.什么情况下适用AB复制&#xff0c;什么情况下使用Galera cluster&#xff1f;3.可…

给出n个字母(a-z),找出出现次数最多的字母并输出。(附ASCII码表)

Result01&#xff1a; 两层for循环枚举&#xff0c;时间复杂度为O(N2)&#xff0c;空间复杂度O(1)。 //暴力解&#xff1a;public static char Result01(char[] chars) {int maxNums 0;//保存最大出现次数int index 0;//记录出现次数最多的元素在数组中的下标for (int i …

初识【Java类和对象】

目录 1.面向对象的初步认知 1.1什么是面向对象? 1.2面向对象与面向过程 2.类定义和使用 2.1简单认识类 2.2类的定义格式 3.类的实例化 3.1什么是实例化 3.2类和对象的说明 4.this引用 4.1为什么要有this的引用 4.2什么是this引用 4.3this引用的特性 &#x1…

3 — NLP 中的标记化:分解文本数据的艺术

一、说明 这是一个系列文章的第三篇文章&#xff0c; 文章前半部分分别是&#xff1a; 1 — NLP 的文本预处理技术2 — NLP中的词干提取和词形还原&#xff1a;文本预处理技术 在本文中&#xff0c;我们将介绍标记化主题。在开始之前&#xff0c;我建议您阅读我之前介绍…

【机器学习合集】模型设计之注意力机制动态网络 ->(个人学习记录笔记)

文章目录 注意力机制1. 注意力机制及其应用1.1 注意力机制的定义1.2 注意力机制的典型应用 2. 注意力模型设计2.1 空间注意力机制2.2 空间注意力模型2.3 通道注意力机制2.4 空间与通道注意力机制2.5 自注意力机制2.5 级联attention 动态网络1. 动态网络的定义2. 基于丢弃策略的…

高校教务系统登录页面JS分析——西安电子科技大学

高校教务系统密码加密逻辑及JS逆向 本文将介绍西安电子科技大学高校教务系统的密码加密逻辑以及使用JavaScript进行逆向分析的过程。通过本文&#xff0c;你将了解到密码加密的基本概念、常用加密算法以及如何通过逆向分析来破解密码。 &#x1f31f;PS&#xff1a;我还以为和…

Linux服务器使用GPU技巧

进行深度学习实验的时候用pytorch-gpu&#xff0c;经常要与GPU打交道&#xff1b; 所以经常遇到奇奇怪怪的问题&#xff1b; 查看GPU占用情况 watch -n 10 nvidia-smi 使用技巧 torch.nn.DataParallel() CLASStorch.nn.DataParallel(module, device_idsNone, output_devic…

部署Kubernetes(k8s)多主的高可用集群

文章目录 文档说明网络拓扑IP地址规划 安装步骤环境准备关闭防火墙关闭SELinux关闭Swap分区修改主机名称解析设置主机名称转发 IPv4 并让 iptables 看到桥接流量升级操作系统内核导入elrepo gpg key安装elrepo YUM源仓库安装kernel-lt版本设置grub2默认引导为0重新生成grub2引导…

关于CSS的几种字体悬浮的设置方法

关于CSS的几种字体悬浮的设置方法 1. 鼠标放上动态的2. 静态的&#xff08;位置看上悬浮&#xff09;2.1 参考QQ邮箱2.2 参考知乎 1. 鼠标放上动态的 效果如下&#xff1a; 代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><met…

使用复合机器人有哪些注意事项

随着科技的快速发展&#xff0c;复合机器人在各个领域得到了广泛应用。复合机器人可以完成多种任务&#xff0c;具备高效、精准、灵活等优势。然而&#xff0c;在使用复合机器人时&#xff0c;我们也需要注意一些事项&#xff0c;以确保安全和有效地使用这些机器人。 一、安装要…

OpenCV - C++实战(05) — 颜色检测

目录 第5章 颜色检测 5.1 实现原理 5.2 Lab颜色模型 5.3 cv :: threshold() 阈值函数 5.4 计算图像之间的距离 5.4.1 公式计算 5.4.2 cv::absdiff() 5.4.3 cv::floodFill() 5.5 完整代码 Github代码地址&#xff1a;GitHub - Qinong/OpenCV 第5章 颜色检测 颜色检测…