代码编织梦想

需求背景简述:springboot-maven项目在运行过程中,需要依据用户的行为来触发数据库建表操作,原来的jpa动态建表已经不能支撑(jpa是在项目启动时动态建表,也可能我没找到项目运行中利用jpa动态建表的用法),所以我选择了去执行sql文件的方法。

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

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

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

一般来说,项目的配置文件及静态资源都会放置在resources目录下。如下图
在这里插入图片描述
当需要在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>
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_37482190/article/details/127990972

spring boot结合layui+thymeleaf+springbootjpa+oracle实现案例_宇默的博客-爱代码爱编程

首先说一下,我为什么会写这个案例,话不多说,上图: POM.XML: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema

application.properties详解 --springboot配置文件常用配置_enjoycoding.的博客-爱代码爱编程

原文连接 # spring boot application.properties配置的各个属性详解 # 该示例文件作为标准提供。(官方文档 翻译过来的) # 还是花了些功夫翻译,各位如果转发,请留下本文地址,谢谢 # 翻译过程中难免出现翻译错误的地方,如果有哪位大神发现有错误的地方,请您留言指正,感激不尽,共同进步。 # created  by lpf

springboot配置文件最全最详细中文说明_bluekitty1210的博客-爱代码爱编程

# REDIS (Redis 配置) # 连接工厂使用的数据库索引 spring.redis.database= 0 # Redis服务器主机 spring.redis.host= localhost # 登录redis服务器的密码 spring.redis.password= # 给定时间池可以分配的最大连接数 使用负值为无限制 spring.redi

springboot maven打包jar运行,springboot mybatis druid,demo源码_无、涯的博客-爱代码爱编程

注:本文介绍的mysql版本是5.x ,如果mysql升级到8 有几个地方需要改动 https://blog.csdn.net/a704397849/article/details/108396563 之前分享一

springboot + quartz(定时框架) + jpa 整合_斯普润布特的博客-爱代码爱编程

 SpringBoot + Quartz(定时框架) + Jpa 整合   maven依赖 <!-- 定时任务 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-

springboot--------restful([梦学谷]十一)-爱代码爱编程

    登录 注册 写文章 首页 下载APP Spring Boot 2 官方指导手册译文 Hsinwong 关注 赞赏支持 Spring Boot 2 官方指导手册译文 1 2018.05.11 11:44:54 字数 18289 阅读 8299 入门 介绍 Spring Boot Spring Boot 使您可以轻松地创建独立的、生产级的基

application.properties详解 --springBoot配置文件-爱代码爱编程

转载侵删:https://blog.csdn.net/lpfsuperman/article/details/78287265    以下为链接原文 # spring boot application.properties配置的各个属性详解 # 该示例文件作为标准提供。(官方文档 翻译过来的) # 还是花了些功夫翻译,各位如果转发,请留下本文地址,

最全的springboot之application.properties配置文件详解-爱代码爱编程

 为方便自己使用,在全网找的最全的application.properties配置文件详解,需要的时候可以来这里找一下 目录 1.网友的配置 2.王军伟老师的总结 1.网友的配置 转载自https://blog.csdn.net/xingbaozhen1210/article/details/84063997?tt_from=weixin&

application.properties详解 --springBoot配置文件[保存备用】-爱代码爱编程

# spring boot application.properties配置的各个属性详解 # 该示例文件作为标准提供。(官方文档 翻译过来的) # 还是花了些功夫翻译,各位如果转发,请留下原作者地址https://blog.csdn.net/LPFSuperMan/article/details/78287265?utm_medium=distrib

SpringBoot项目拥抱Mybatis-Plus持久层框架实践-爱代码爱编程

本文目录 前言 自从 Mybatis-Plus推出以来,越来越多的公司在自己的项目中选择Mybatis-Plus框架替换了持久层框架Mybatis。因为Mybatis-Plus用起来既有Mybatis的手写复杂sql语句的灵活性,又兼具了Spring Data Jpa自动提供了单表CRUD操作的通用框架方法,只需要自定义一个Mapper并继承Bas

springboot从数据库读取配置文件_renkai721的博客-爱代码爱编程

springboot常规的项目是直接读取resources/application.properties文件或者application.yml或者bootstrap.properties文件。还有常见的玩法是把nacos或eureka或zookeeper来实现远程读取配置文件。 --------------------------------------