検索
ホームページJava&#&チュートリアルSpringBoot が SQL スクリプトの実行を開始および初期化する方法

    SpringBoot が開始し、SQL スクリプトの実行を初期化します

    プロジェクトの開始時にいくつかの SQL スクリプトを実行したい場合はどうすればよいでしょうか。SpringBoot はこれを提供します。関数を使用すると、SpringBoot プロジェクトの開始時にスクリプトを実行できます。

    まずソース コードを見てみましょう

    SpringBoot が SQL スクリプトの実行を開始および初期化する方法

    boolean createSchema() {
    	//会从application.properties或application.yml中获取sql脚本列表
    	List<Resource> scripts = this.getScripts("spring.datasource.schema", this.properties.getSchema(), "schema");
        if (!scripts.isEmpty()) {
        	if (!this.isEnabled()) {
            	logger.debug("Initialization disabled (not running DDL scripts)");
                return false;
            }
    
            String username = this.properties.getSchemaUsername();
            String password = this.properties.getSchemaPassword();
            //运行sql脚本
            this.runScripts(scripts, username, password);
        }
        return !scripts.isEmpty();
    }
    private List<Resource> getScripts(String propertyName, List<String> resources, String fallback) {
    	if (resources != null) {
    		//如果配置文件中配置,则加载配置文件
        	return this.getResources(propertyName, resources, true);
       	} else {
       		//指定schema要使用的Platform(mysql、oracle),默认为all
        	String platform = this.properties.getPlatform();
            List<String> fallbackResources = new ArrayList();
            //如果配置文件中没配置,则会去类路径下找名称为schema或schema-platform的文件
            fallbackResources.add("classpath*:" + fallback + "-" + platform + ".sql");
           	fallbackResources.add("classpath*:" + fallback + ".sql");
           	return this.getResources(propertyName, fallbackResources, false);
        }
    }
    private List<Resource> getResources(String propertyName, List<String> locations, boolean validate) {
    	List<Resource> resources = new ArrayList();
    	Iterator var5 = locations.iterator();
    
        while(var5.hasNext()) {
        	String location = (String)var5.next();
            Resource[] var7 = this.doGetResources(location);
            int var8 = var7.length;
    
            for(int var9 = 0; var9 < var8; ++var9) {
            	Resource resource = var7[var9];
            	//验证文件是否存在
            	if (resource.exists()) {
                	resources.add(resource);
               	} else if (validate) {
                	throw new InvalidConfigurationPropertyValueException(propertyName, resource, "The specified resource does not exist.");
                }
            }
        }
        return resources;
    }

    ソース コードから、それが何を意味するのかはおおよそわかります。SpringBoot は次のスクリプト ファイルを見つけます。デフォルトではクラスパスですが、クラスパスの下には指定されたスキーマ名またはスキーマプラットフォーム名のスクリプトファイルのみを配置できます。複数のスクリプトファイルを分割したい場合、この方法は適していません。 application.properties または application.yml 構成スクリプト リストに移動します。この初期化スクリプト操作は構成ファイルで制御できますか? はい、3 つの値に設定できる初期化モード属性があります。常に初期化が常に実行されることを意味します。 、h3 などのメモリ データベース (デフォルト値) のみを初期化する埋め込みは、初期化が実行されないことを意味するものではありません。

    spring:
      datasource:
        username: root
        password: liuzhenyu199577
        url: jdbc:mysql://localhost:3306/jdbc
        driver-class-name: com.mysql.cj.jdbc.Driver
        initialization-mode: always

    これら 2 つの方法を確認してみましょう

    1. デフォルトでスキーマまたはスキーマ プラットフォームのスクリプト ファイルを配置します

    SpringBoot が SQL スクリプトの実行を開始および初期化する方法

    CREATE TABLE IF NOT EXISTS department (ID VARCHAR(40) NOT NULL, NAME VARCHAR(100), PRIMARY KEY (ID));

    Viewデータベースには部門テーブルがありません。次に、プログラムを開始します

    SpringBoot が SQL スクリプトの実行を開始および初期化する方法

    #開始後、再度確認して実行します

    SpringBoot が SQL スクリプトの実行を開始および初期化する方法

    2. 設定ファイルで複数の SQL スクリプトを指定します

    spring:
      datasource:
        username: root
        password: liuzhenyu199577
        url: jdbc:mysql://localhost:3306/jdbc
        driver-class-name: com.mysql.cj.jdbc.Driver
        initialization-mode: always
        schema:
          - classpath:department.sql
          - classpath:department2.sql
          - classpath:department3.sql

    SpringBoot が SQL スクリプトの実行を開始および初期化する方法

    3 つの SQL スクリプトはすべて insert ステートメントです

    INSERT INTO department (ID,NAME) VALUES (&#39;1&#39;,&#39;2&#39;)
    INSERT INTO department (ID,NAME) VALUES (&#39;2&#39;,&#39;3&#39;)
    INSERT INTO department (ID,NAME) VALUES (&#39;3&#39;,&#39;4&#39;)

    にはデータがありません次に、プログラムを開始します

    SpringBoot が SQL スクリプトの実行を開始および初期化する方法

    #開始後、もう一度見てみると、テーブルに 3 つのデータがあります

    SpringBoot が SQL スクリプトの実行を開始および初期化する方法

    SpringBoot の起動と SQL スクリプトの初期化の手順です

    ##SpringBoot プロジェクトは起動時に指定された SQL ファイルを実行します

    ##1. 起動時に実行

    プロジェクトが開始されると、指定されたファイルが最初に実行されます SQL ステートメントが必要な場合、実行する必要がある SQL ファイルをリソース フォルダーに追加できます。ファイル内の SQL ステートメントは DDL スクリプトまたは DDL スクリプトにすることができます。 DML スクリプトを作成し、次のように対応する構成を構成に追加します:

    spring:
      datasource:
        schema: classpath:schema.sql # schema.sql中一般存放的是DDL脚本,即通常为创建或更新库表的脚本 data: classpath:data.sql # data.sql中一般是DML脚本,即通常为数据插入脚本

    2. 複数の SQL ファイルを実行します

    spring.datasource.schema と spring.datasource.data は両方とも受信をサポートします。

    spring:
      datasource:
        schema: classpath:schema_1.sql, classpath:schema_2.sql data: classpath:data_1.sql, classpath:data_2.sql 或 spring: datasource: schema: - classpath:schema_1.sql - classpath:schema_2.sql data: - classpath:data_1.sql - classpath:data_2.sql

    3. 異なる実行環境では異なるスクリプトが実行されます

    通常、複数の実行環境が存在します。開発、テスト、本番など。通常、動作環境が異なれば実行する必要がある SQL も異なります。この問題を解決するには、ワイルドカードを使用できます。

    さまざまな環境用のフォルダーを作成する

    リソース フォルダー内にさまざまな環境に対応するフォルダー (dev/、sit/、prod/ など) を作成します。

    Configuration

    application.yml

    spring:
      datasource:
        schema: classpath:${spring.profiles.active:dev}/schema.sql 
        data: classpath:${spring.profiles.active:dev}/data.sql

    注: ${} ワイルドカードはデフォルト値をサポートします。たとえば、上記の設定の ${spring.profiles.active:dev} では、セミコロンの前は spring.profiles.active 属性の値を取得し、属性の値が存在しない場合は、セミコロンの後の値を取得します。セミコロンが使用されます。つまり、dev です。

    bootstrap.yml

    spring:
      profiles:
        active: dev # dev/sit/prod等。分别对应开发、测试、生产等不同运行环境。

    リマインダー: spring.profiles.active プロパティは通常、bootstrap.yml または bootstrap.properties で構成されます。

    4. 異なるデータベースのサポート

    異なるデータベースの構文は異なるため、同じ機能を実現するために、異なるデータベースの SQL ステートメントは異なる可能性があるため、複数のコピーが存在する可能性があります。ファイル。異なるデータベースをサポートする必要がある場合は、次の構成を使用できます。

    spring:
      datasource:
        schema: classpath:${spring.profiles.active:dev}/schema-${spring.datasource.platform}.sql
        data: classpath:${spring.profiles.active:dev}/data-${spring.datasource.platform}.sql
        platform: mysql

    注意: プラットフォーム属性のデフォルト値は「all」です。そのため、上記の構成は、異なるデータベース間を切り替える場合にのみ使用してください。デフォルト値 この場合、Spring Boot は現在使用されているデータベースを自動的に検出します。

    注: 現時点では、dev が許可された環境を例に挙げると、次のファイルが resource/dev/ フォルダーに存在する必要があります: schema-mysql.sql および data-mysql.sql。

    5. 落とし穴の回避

    #​​

    ##5.1 落とし穴

    実行された SQL ファイルにストアド プロシージャまたは関数が含まれている場合、起動時にエラーが報告されます。プロジェクト 。 例えば、プロジェクト開始時に、あるテーブルをスキャンし、テーブル内のレコード数が0の場合は複数のレコードを挿入し、0より大きい場合はスキップするというような要件があります。 。

    schema.sql ファイルのスクリプトは次のとおりです:

    -- 当存储过程`p1`存在时,删除。
    drop procedure if exists p1;
     
    -- 创建存储过程`p1`
    create procedure p1() 
    begin declare row_num int; select count(*) into row_num from `t_user`; if row_num = 0 then INSERT INTO `t_user`(`username`, `password`) VALUES (&#39;zhangsan&#39;, &#39;123456&#39;); end if; end; -- 调用存储过程`p1` call p1(); drop procedure if exists p1;

    プロジェクトを開始し、次の理由によりエラーを報告します:

    Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'create procedure p1() begin declare row_num int' at line 1

    大致的意思是:'create procedure p1() begin declare row_num int'这一句出现语法错误。刚看到这一句,我一开始是懵逼的,吓得我赶紧去比对mysql存储过程的写法,对了好久都发现没错,最后看到一篇讲解spring boot配置启动时执行sql脚本的文章,发现其中多了一项配置:spring.datasource.separator=$$。然后看源码发现,spring boot在解析sql脚本时,默认是以';'作为断句的分隔符的。看到这里,不难看出报错的原因,即:spring boot把'create procedure p1() begin declare row_num int'当成是一条普通的sql语句。而我们需要的是创建一个存储过程。

    5.2 解决方案

    修改sql脚本的断句分隔符。如:spring.datasource.separator=$$。然后把脚本改成:

    -- 当存储过程`p1`存在时,删除。
    drop procedure if exists p1;$$
     
    -- 创建存储过程`p1`
    create procedure p1() 
    begin declare row_num int; select count(*) into row_num from `t_user`; if row_num = 0 then INSERT INTO `t_user`(`username`, `password`) VALUES (&#39;zhangsan&#39;, &#39;123456&#39;); end if; end;$$ -- 调用存储过程`p1` call p1();$$ drop procedure if exists p1;$$

    5.3 不足

    因为sql脚本的断句分隔符从';'变成'$$',所以可能需要在DDL、DML语句的';'后加'$$',不然可能会出现将整个脚本当成一条sql语句来执行的情况。比如:

    -- DDL
    CREATE TABLE `table_name` (
      -- 字段定义
      ... 
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;$$
     
    -- DML
    INSERT INTO `table_name` VALUE(...);$$

    以上がSpringBoot が SQL スクリプトの実行を開始および初期化する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明
    この記事は亿速云で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。

    ホットAIツール

    Undresser.AI Undress

    Undresser.AI Undress

    リアルなヌード写真を作成する AI 搭載アプリ

    AI Clothes Remover

    AI Clothes Remover

    写真から衣服を削除するオンライン AI ツール。

    Undress AI Tool

    Undress AI Tool

    脱衣画像を無料で

    Clothoff.io

    Clothoff.io

    AI衣類リムーバー

    AI Hentai Generator

    AI Hentai Generator

    AIヘンタイを無料で生成します。

    ホットツール

    MinGW - Minimalist GNU for Windows

    MinGW - Minimalist GNU for Windows

    このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

    メモ帳++7.3.1

    メモ帳++7.3.1

    使いやすく無料のコードエディター

    WebStorm Mac版

    WebStorm Mac版

    便利なJavaScript開発ツール

    Dreamweaver Mac版

    Dreamweaver Mac版

    ビジュアル Web 開発ツール

    SublimeText3 Mac版

    SublimeText3 Mac版

    神レベルのコード編集ソフト(SublimeText3)