springboot-maven项目+jpa 运行过程中执行resources下sql脚本文件-ClassPathResource和ScriptUtils.executeSqlScript的使用

简介: springboot-maven项目+jpa 运行过程中执行resources下sql脚本文件-ClassPathResource和ScriptUtils.executeSqlScript的使用

要完成上述需求,需要分两步操作

  • 获取resources目录下的sql脚本文件
  • 执行该文件

获取resources目录下的sql脚本文件


一般来说,项目的配置文件及静态资源都会放置在resources目录下。如下图


00a73497fb0d4cac9bc760c8d04911f4.png

当需要在java代码中使用resources目录下的文件时,就需要先获取该文件了

以获取上图test.sql文件为例,方法有二


方法一:

//这种方法在linux下无法工作
File sourceFile = ResourceUtils.getFile("classpath:db/test.sql");


⚠️:这种方法在linux下无法工作,我未采用

方法二:

我使用的是第二种。


import org.springframework.core.io.Resource;
// ... 忽略部分代码
Resource resource = new ClassPathResource("db/test.sql");
//获取到resource对象后,可以调用resouce.getFile()方法来获取文件。
File sourceFile = resource.getFile();

通过Resouce的实现类ClassPathResource来new一个对象。

该构造方法的参数是resources目录下的文件路径,注意这里是使用的相对路径(相对于resouces目录而言的)


尝试使用但未成功的方法


//通过入参相对路径或绝对路径都没有获取成功
Class.getResource("")获取相对于当前类的相对路径
Class.getResource("/")获取classpath的根路径
ClassLoader.getResource("")获取classpath的根路径


执行该sql文件


使用 Spring 提供的工具类执行 sql 文件


我是通过jpa来简化对数据库的操作,所以采用了Spring的工具类;如果用的是mybatis,可以直接跳过看下面

import javax.sql.DataSource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.init.ScriptUtils;
// ... 忽略部分代码
DataSource dataSource = createDataSource();  
Resource resource = new ClassPathResource("db/test.sql");
ScriptUtils.executeSqlScript(dataSource.getConnection(), resource);

使用mybatis方式执行 sql 文件

使用的是mybatis的ScriptRunner方法

直接上代码


/**
 * 使用ScriptRunner执行sql文件
 */
public class ExecuteSql {
    @Autowired
    private DataSource dataSource; // 获取数据库连接对象
    public static void main(String[] args) {
        try {
            executeSqlFile("db/test.sql");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void executeSqlFile(String sqlFileName) throws Exception {
        // 获取连接对象
        Connection conn = dataSource.getConnection();
        //或者直接指明数据库
        //Class.forName(className);
        //Connection conn = DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
        try {
            // 设置不自动提交
            conn.setAutoCommit(false);
            // 初始化ScriptRunner
            ScriptRunner runner = new ScriptRunner(conn);
            // 设置不自动提交
            runner.setAutoCommit(false);
            // true,遇见错误会停止执行,打印并抛出异常,捕捉异常,并进行回滚,保证在一个事务内执行;
            // false,遇见错误不会停止,会继续执行,会打印异常信息,并不会抛出异常,当前方法无法捕捉异常无法进行回滚操作,无法保证在一个事务内执行;
            runner.setStopOnError(true);
            // true则获取整个脚本并执行;
            // false则按照自定义的分隔符每行执行;
            runner.setSendFullScript(false);
            // 定义命令间的分隔符
            runner.setDelimiter(";");
            runner.setFullLineDelimiter(false);
            // 设置是否输出日志,null不输出日志,不设置自动将日志输出到控制台
            runner.setLogWriter(null);
            // 读取文件
            Resource resource = new ClassPathResource(sqlFileName);
            File file = resource.getFile();
            // 如果有多个sql文件,可以写多个runner.runScript(xxx),
            runner.runScript(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
            // 执行
            conn.commit();
        } catch (Exception e) {
            conn.rollback();
            e.printStackTrace();
        } finally {
            conn.close();
        }
    }
}


jpa方式完整代码


import javax.sql.DataSource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.init.ScriptUtils;
// 获取连接对象
DataSource dataSource = createDataSource().getConnection();
//也可以下面这种方式直接指明
//Class.forName(className);
//Connection conn = DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
Resource resource = new ClassPathResource("db/test.sql");
ScriptUtils.executeSqlScript(conn, resource);
//去检查数据库验证吧!


如果成功了,那么下面就不用看了


其他问题

找不到脚本文件

报错


看到有情况是按照上述jpa方式执行了代码,但是仍然有类似找不到文件的报错

如:

java.io.FileNotFoundException: class path resource [db/test.sql] cannot be resolved to URL because it does not exist
     at org.springframework.core.io.ClassPathResource.getURL(ClassPathResource.java:195)

分析


ClassPathResource方法是到 classPath* 下去找,然后在项目本地的目录下找classPath下是否有这个文件(maven的classPath在 “target\classes”目录下)


解决


可以检查下pom.xml文件,

可能是springboot的maven默认只加载了classPath同级目录下的文件,想要加载其他文件可以使用配置标签

如下:


<build>
  <resources>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
        //相对路径
          <include>**/*.sql</include>
        </includes>
      </resource>
  </resources>
</build>


目录
相关文章
|
XML Java Maven
springboot-多环境配置文件
本文介绍了如何创建开发和生产环境的配置文件,并在IDEA和Maven中进行配置。开发环境中,通过设置profile为`dev`来指定配置文件;生产环境中,使用Maven命令参数`-Pprod`打包并指定配置文件。公共配置可放在`application.yml`中统一管理。日志配置需确保`logback-spring.xml`中的profile正确,以保证日志正常输出。
1252 4
springboot-多环境配置文件
|
存储 前端开发 Java
Springboot静态资源映射及文件映射
在Spring Boot项目中,为了解决前端访问后端存储的图片问题,起初尝试通过静态资源映射实现,但发现这种方式仅能访问打包时已存在的文件。对于动态上传的图片(如头像),需采用资源映射配置,将特定路径映射到服务器上的文件夹,确保新上传的图片能即时访问。例如,通过`addResourceHandler(&quot;/img/**&quot;).addResourceLocations(&quot;file:E:\\myProject\\forum_server\\&quot;)`配置,使前端可通过URL直接访问图片。
929 0
Springboot静态资源映射及文件映射
|
10月前
|
前端开发 JavaScript Java
基于springboot+vue开发的校园食堂评价系统【源码+sql+可运行】【50809】
本系统基于SpringBoot与Vue3开发,实现校园食堂评价功能。前台支持用户注册登录、食堂浏览、菜品查看及评价发布;后台提供食堂、菜品与评价管理模块,支持权限控制与数据维护。技术栈涵盖SpringBoot、MyBatisPlus、Vue3、ElementUI等,适配响应式布局,提供完整源码与数据库脚本,可直接运行部署。
578 6
基于springboot+vue开发的校园食堂评价系统【源码+sql+可运行】【50809】
|
前端开发 Cloud Native Java
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
本文来自YashanDB官网,介绍如何处理Oracle客户端sql*plus中使用@@调用同级目录SQL脚本的场景。崖山数据库23.2.x.100已支持@@用法,但旧版本可通过Python脚本批量重写SQL文件,将@@替换为绝对路径。文章通过Oracle示例展示了具体用法,并提供Python脚本实现自动化处理,最后调整批处理脚本以适配YashanDB运行环境。
|
网络协议 Java
springboot配置hosts文件
springboot配置hosts文件
339 11
|
存储 前端开发 JavaScript
SpringBoot结合Minio实现文件切片极速上传
【10月更文挑战第21天】
1066 6
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")

推荐镜像

更多