首页 新闻 会员 周边 捐助

Java有没有工具类可以执行这种数据库脚本文件?

0
悬赏园豆:30 [已解决问题] 解决于 2022-06-22 17:22

CodeCorner的主页 CodeCorner | 初学一级 | 园豆:177
提问于:2022-06-22 08:58
< >
分享
最佳答案
0

这应该是Oracle吧,使用工具类前需要引入Oracle的驱动包
Maven pom.xml配置

<dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc10</artifactId>
            <version>19.15.0.0.1</version>
</dependency>

然后是工具类代码,仅供参考

import java.sql.*;

public class SQLExecutor {

    public static void main(String[] args) {
        String driverClass = "oracle.jdbc.driver.OracleDriver";
        String url = "jdbc:oracle:thin:@你的数据库IP地址或域名:端口号:数据库名称";
        String username = "用户名";
        String password = "用户密码";
        // 执行存储过程需要数据库中已经创建好,然后使用 {call 存储过程名称(参数1,参数2,...,参数n)} 调用存储过程
        String procedure = "xxx(a, b)";
        execute(driverClass, url, username, password, procedure);
    }

    /**
     * 执行存储过程方法
     * @param driverClass 数据库驱动类的全路径名
     * @param url 数据库访问url (指定IP、端口号、数据库名)
     * @param username 数据库用户名
     * @param password 数据库用户密码
     * @param procedure 存储过程名称+对应参数(多个参数以','分隔)
     */
    public static void execute(String driverClass, String url, String username, String password, String procedure) {
        Connection connection = null;
        try {
            // 注册数据库驱动
            Class.forName(driverClass);
            // 创建数据库连接
            connection = DriverManager.getConnection(url);
            // 调用存储过程
            CallableStatement statement = connection.prepareCall("{call " + procedure + "}");
            statement.execute();
            // 结果集
            ResultSet resultSet = statement.getResultSet();
            // 遍历结果集
            while ( resultSet.next() ) {
                // 获取指定字段的字符串
                // String string = resultSet.getString("xxx");
            }
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if ( connection != null && !connection.isClosed() ) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    private SQLExecutor() {}
}
收获园豆:30
飒沓流星 | 小虾三级 |园豆:1099 | 2022-06-22 12:32

感谢,不过我想要的实现是Java读取.sql文件并执行里面的内容。

CodeCorner | 园豆:177 (初学一级) | 2022-06-22 13:36

@CodeCorner:
换个API就行了,你没用过这个吗?

改成

PreparedStatement statement = connection.prepareStatement(procedure);

procedure 就是文件内容,但是最后的那个"/"要去掉
这里面api有很多,看看文档,不合适再换其他的

飒沓流星 | 园豆:1099 (小虾三级) | 2022-06-22 15:09

@飒沓流星: 最后的"/"为什么要去掉?假如我一个文件里有多个语句块,需要用到"/"作分割用的。

CodeCorner | 园豆:177 (初学一级) | 2022-06-22 15:17

@CodeCorner: 那你代码里处理下呀,遇到“/”分隔之类的

飒沓流星 | 园豆:1099 (小虾三级) | 2022-06-22 15:20

@飒沓流星: 你的意思是用文件的内容当成字符串procedure,然后调用方法connection.prepareStatement(procedure)吗?

CodeCorner | 园豆:177 (初学一级) | 2022-06-22 15:25

@CodeCorner: 是这个意思。但是我不理解,明明是存储过程,为什么不单独创建;反而要把所有的存储过程放到一个sql文件里;那你们后期项目怎么维护呢

飒沓流星 | 园豆:1099 (小虾三级) | 2022-06-22 15:50

@飒沓流星: 测试了下,确实可以把文件的内容当成字符串来执行。不过jdbc不能识别出"/"这个分割符,这样一个文件就只能处理一个存储过程了。

CodeCorner | 园豆:177 (初学一级) | 2022-06-22 17:01

@飒沓流星: 项目中这只是一个读文件执行脚本的工具类,所以对项目影响不大

CodeCorner | 园豆:177 (初学一级) | 2022-06-22 17:05

@CodeCorner: 你可以把文件中的所有内容以字符串读取出来,按 ‘/’ 分隔 String#split() ,返回一个字符串数组,然后循环调用

飒沓流星 | 园豆:1099 (小虾三级) | 2022-06-22 17:06

@CodeCorner: 好吧👀

飒沓流星 | 园豆:1099 (小虾三级) | 2022-06-22 17:08

@飒沓流星: 嗯,试过这样做,但如果还存在其他的"/"就不行了,比如url字段:“controller/delete”。

CodeCorner | 园豆:177 (初学一级) | 2022-06-22 17:12

@CodeCorner: 嗯,用分隔符确实不太靠谱,sql文件可以拆分开吗(感觉要没招了)

飒沓流星 | 园豆:1099 (小虾三级) | 2022-06-22 17:17

@飒沓流星: 感谢提供方案,剩下的优化我再想想。

CodeCorner | 园豆:177 (初学一级) | 2022-06-22 17:23

@CodeCorner:
客气了,相互学习
读取文件内容的时候用 BufferedReader#readLine(); 一行一行 读取,如果一整行的内容 equals("/"),是不是就可以分隔了

飒沓流星 | 园豆:1099 (小虾三级) | 2022-06-22 17:32
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册