• springboot集成flyway,数据库是oracle


    一. springboot2.x ,oracle 11,用flyway5.x的报错,后来用了4.x的

    • 在dependencies加入了 oracle 和 flyway 的配置
    <dependency>
           <groupId>com.oracle</groupId>
           <artifactId>ojdbc6</artifactId>
           <version>11.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.flywaydb</groupId>
        <artifactId>flyway-core</artifactId>
        <version>4.2.0</version>
    </dependency>
    • 在plugins中加了 flyway 的配置
    <plugin>
        <groupId>org.flywaydb</groupId>
         <artifactId>flyway-maven-plugin</artifactId>
    </plugin>
    • 配置文件

    查看了很多文档,然后在application.properties写了下面的配置

    spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
    spring.datasource.url=jdbc:oracle:thin:@192.168.1.11:1521/orcl
    spring.datasource.username=comm
    spring.datasource.password=comm
    # Whether to enable flyway.
    spring.flyway.enabled=true 
    spring.flyway.baseline-on-migrate=false
    # The locations of migrations scripts.
    spring.flyway.locations=classpath:db/migration
    spring.flyway.clean-on-validation-error=false
    • 启动类
    @EnableTransactionManagement
    public class MyApplication {
          
        private static Logger logger = LoggerFactory.getLogger(MyApplication.class);
        
        public static void main(String[] args) {
            try {
                SpringApplication springApplication = new SpringApplication(MyApplication.class);
                springApplication.run(args);
                logger.info("----------------------flyway started successfully-----------------------");
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
    
    }

    启动之后报错:

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Found non-empty schema(s) "COMM" without metadata table! Use baseline() or set baselineOnMigrate to true to initialize the metadata table.

    这是因为没有初始化那个COMM的schema,然后我就把配置文件的

    spring.flyway.baseline-on-migrate= false 改成了true

    重新启动就成功了。

    二、查看schema_version表

    我一直找不到,comm自动补全里有这张表,差点就疯了,然后看到别人的博文里说: 

    由于schema_version是记录数据库版本信息的,因此flyway对其做了保护策略,如果要查看这张表,则必须给表名加双引号,如:select * from "schema_version"

    我终于看到了希望 : ) 

    能在表里看到一条初始化的数据。

    三、在resource下新建了文件夹 db/migration

    sql脚本命名规范:前辍(V/R)+版本号(小版本之间以.或_分隔)+双下划线+描述.sql。

    1. 我先放入了V1.0.0__init.sql 和 V2.0.0__init.sql,第一个是新建表test的,第二个是往test里面插入数据的,再次启动报错(test表不存在)了,那是因为schema_version表中初始化的那一条是1,然后就从V2执行了。

    然后删掉了version表中的第二条数据,将sql文件重新起了名字

    V1.0.1__init.sql:
    create table test
    (
      id          varchar2(20) not null,
      name     VARCHAR2(20)
    );
    V1.
    0.2__init.sql: insert into comm.test(id, name) values ('1','张三'); insert into comm.test(id, name) values ('2','李四');

    执行成功,表也创建成功了,开心ing。

    四、我现在不想每次增加sql都需要重新启动

    1. 新建flyway的执行类,我比参考文档多了36行的(把上面version表还有test表都删掉了,执行会报错,没有COMM的schema)

     1 package org.ssh.hip.flyway.controller;
     2 
     3 
     4 import java.util.HashMap;
     5 import java.util.Map;
     6 
     7 import javax.sql.DataSource;
     8 
     9 import org.flywaydb.core.Flyway;
    10 import org.slf4j.Logger;
    11 import org.slf4j.LoggerFactory;
    12 import org.springframework.beans.factory.annotation.Autowired;
    13 import org.springframework.stereotype.Controller;
    14 import org.springframework.web.bind.annotation.RequestMapping;
    15 import org.springframework.web.bind.annotation.ResponseBody;
    16 
    17 
    18 @Controller
    19 @RequestMapping("/flyway")
    20 public class FlywayConfig {
    21 
    22    @Autowired
    23    private DataSource dataSource;
    24 
    25    private Logger logger = LoggerFactory.getLogger(this.getClass());
    26 
    27 
    28    @RequestMapping(value = "/migrate")
    29    @ResponseBody
    30    public Map<String, String> migrate(){
    31        Map<String, String> res = new HashMap<String, String>();
    32        
    33        Flyway flyway = new Flyway();
    34 
    35        try {
    36            flyway.setBaselineOnMigrate(true);// 为了创建schema
    37            flyway.setDataSource(dataSource);
    38            // 设置flyway扫描sql升级脚本、java升级脚本的目录路径或包路径(表示是src/main/resources/flyway下面,前缀默认为src/main/resources,因为这个路径默认在classpath下面)
    39            flyway.setLocations("db/migration");
    40            // 设置sql脚本文件的编码
    41            flyway.setEncoding("UTF-8");
    42            flyway.setOutOfOrder(true);
    43 
    44            flyway.migrate();
    45 
    46 //       } catch (FlywayException e) {
    47        } catch (Exception e) {
    48 
    49            flyway.repair();
    50 
    51            logger.error("Flyway配置加载出错",e);
    52            res.put("code", "-1");
    53            res.put("message", "Flyway配置加载出错" + e.getMessage());
    54        }
    55        res.put("code", "0");
    56        res.put("message","success");
    57        return res;
    58    }
    59 }

    2. 修改启动类(将flyway配置从springboot排除,避免springboot自动配置)

     1 import org.slf4j.Logger;
     2 import org.slf4j.LoggerFactory;
     3 import org.springframework.boot.SpringApplication;
     4 import org.springframework.boot.autoconfigure.SpringBootApplication;
     5 import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
     6 import org.springframework.transaction.annotation.EnableTransactionManagement;
     7 import springfox.documentation.swagger2.annotations.EnableSwagger2;
     8 
     9 @EnableSwagger2
    10 @SpringBootApplication(exclude = { FlywayAutoConfiguration.class })
    11 @EnableTransactionManagement
    12 public class MyApplication {
    13       
    14     private static Logger logger = LoggerFactory.getLogger(MyApplication.class);
    15     
    16     public static void main(String[] args) {
    17         try {
    18             SpringApplication springApplication = new SpringApplication(MyApplication.class);
    19             springApplication.run(args);
    20             logger.info("----------------------flyway started successfully-----------------------");
    21         } catch (Exception e) {
    22             logger.error(e.getMessage());
    23         }
    24     }
    25 
    26 }

    然后欧了~~

    五、 设置sql存放的多个路径

    项目上为了管理sql方便,需要存放在不同的文件夹下,然后flyway的location就要设置多个地址

               List<String> lists = new ArrayList<String>();
               lists.add("filesystem:E:/module/apache-tomcat-8.5.46/webapps/test2");
               lists.add("filesystem:E:/module/apache-tomcat-8.5.46/webapps/all");
               lists.add("db/migration");
               String[] locations = lists.toArray(new String[0]); // new String[0]就是起一个模板的作用
               
               // 设置flyway扫描sql升级脚本、java升级脚本的目录路径或包路径(表示是src/main/resources/flyway下面,前缀默认为src/main/resources,因为这个路径默认在classpath下面)
               flyway.setLocations(locations);//("db/migration");

    其中不是src下的,只要在前面加上 【filesystem: 】默认的是【classpath: 】,locations中存放数组就行了。多个路径之间没有先后关系,是按照sql前面的V的顺序来执行的,不知道内部会不会按顺序来读取查找V的下一个。

    flyway的一些其他配置
    flyway.baseline-description对执行迁移时基准版本的描述.
    flyway.baseline-on-migrate当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false.
    flyway.baseline-version开始执行基准迁移时对现有的schema的版本打标签,默认值为1.
    flyway.check-location检查迁移脚本的位置是否存在,默认false.
    flyway.clean-on-validation-error当发现校验错误时是否自动调用clean,默认false.
    flyway.enabled是否开启flywary,默认true.
    flyway.encoding设置迁移时的编码,默认UTF-8.
    flyway.ignore-failed-future-migration当读取元数据表时是否忽略错误的迁移,默认false.
    flyway.init-sqls当初始化好连接时要执行的SQL.
    flyway.locations迁移脚本的位置,默认db/migration.
    flyway.out-of-order是否允许无序的迁移,默认false.
    flyway.password目标数据库的密码.
    flyway.placeholder-prefix设置每个placeholder的前缀,默认${.
    flyway.placeholder-replacementplaceholders是否要被替换,默认true.
    flyway.placeholder-suffix设置每个placeholder的后缀,默认}.
    flyway.placeholders.[placeholder name]设置placeholder的value
    flyway.schemas设定需要flywary迁移的schema,大小写敏感,默认为连接默认的schema.
    flyway.sql-migration-prefix迁移文件的前缀,默认为V.
    flyway.sql-migration-separator迁移脚本的文件名分隔符,默认__
    flyway.sql-migration-suffix迁移脚本的后缀,默认为.sql
    flyway.tableflyway使用的元数据表名,默认为schema_version
    flyway.target迁移时使用的目标版本,默认为latest version
    flyway.url迁移时使用的JDBC URL,如果没有指定的话,将使用配置的主数据源
    flyway.user迁移数据库的用户名
    flyway.validate-on-migrate迁移时是否校验,默认为true.
    参考文档:
    1.flyway,maven,oracle集成记录
    https://blog.csdn.net/citeng1329/article/details/100288990
    2.运用flyway实现数据库版本自动更新控制实录
    https://blog.csdn.net/u014255803/article/details/79107708/
    3.SpringBoot项目集成Flyway配置执行顺序问题解决方法
    https://blog.csdn.net/u012134942/article/details/97002288
    4.为什么springboot会在启动的时候自动运行Flyway DB? (这就是把上一个问题里面exclude的那个启动类代码贴出来了,直接ctrl鼠标左键点进去就可以看到)
    https://www.jianshu.com/p/b05a36f91ebc
    越努力越幸运~ 加油ヾ(◍°∇°◍)ノ゙
  • 相关阅读:
    页眉插入图片,文字和页号(码)的设置
    MIT_JOS_Lab5
    MIT_JOS_Lab4_PartB_and_PartC
    MIT_JOS_Lab4_PartA
    Monte Carlo Integration
    A strategy to quantify embedding layer
    From DFA to KMP algorithm
    A problem of dimension in Vector Space and It's nullspace
    Pytorch 模型的存储与加载
    Jensen's inequality 及其应用
  • 原文地址:https://www.cnblogs.com/utomboy/p/12504571.html
Copyright © 2020-2023  润新知