Springboot(二十)启动时数据库初始化spring.datasource/spring.jpa

1.使用springboot jdbc初始化数据库

spring:
  datasource:
    username: xuhaixing
    password: xuhaixing
    url: jdbc:mysql://192.168.94.151:3306/mytest?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
    driver-class-name: com.mysql.jdbc.Driver
    platform: mysql
    #启动时需要初始化的建表语句
    schema: classpath:schema-mysql.sql
    #初始化的数据
    data: classpath:data-mysql.sql
    # Initialize the datasource with available DDL and DML scripts.
    initialization-mode: always
    continue-on-error: false
    #data-password:
    #data-username:
    #schema-password:
    #schema-username:
    sql-script-encoding: utf-8
    separator: ;

  spring.datasource下有两个属性  schme、data,其中schema为表初始化语句,data为数据初始化,默认加载schema.sqldata.sql。脚本位置可以通过spring.datasource.schema  与spring.datasource.data 来改变,源码如下:

/**
	 * Create the schema if necessary.
	 * @return {@code true} if the schema was created
	 * @see DataSourceProperties#getSchema()
	 */
	public boolean createSchema() {
		List<Resource> scripts = getScripts("spring.datasource.schema",
				this.properties.getSchema(), "schema");
		if (!scripts.isEmpty()) {
			if (!isEnabled()) {
				logger.debug("Initialization disabled (not running DDL scripts)");
				return false;
			}
			String username = this.properties.getSchemaUsername();
			String password = this.properties.getSchemaPassword();
			runScripts(scripts, username, password);
		}
		return !scripts.isEmpty();
	}

	/**
	 * Initialize the schema if necessary.
	 * @see DataSourceProperties#getData()
	 */
	public void initSchema() {
		List<Resource> scripts = getScripts("spring.datasource.data",
				this.properties.getData(), "data");
		if (!scripts.isEmpty()) {
			if (!isEnabled()) {
				logger.debug("Initialization disabled (not running data scripts)");
				return;
			}
			String username = this.properties.getDataUsername();
			String password = this.properties.getDataPassword();
			runScripts(scripts, username, password);
		}
	}

看getScripts源码,它还会加载schema-${platform}.sql文件,或者data-${platform}.sql文件,其中platform就是spring.datasource.platform的值


	private List<Resource> getScripts(String propertyName, List<String> resources,
			String fallback) {
		if (resources != null) {
			return getResources(propertyName, resources, true);
		}
		String platform = this.properties.getPlatform();
		List<String> fallbackResources = new ArrayList<>();
		fallbackResources.add("classpath*:" + fallback + "-" + platform + ".sql");
		fallbackResources.add("classpath*:" + fallback + ".sql");
		return getResources(propertyName, fallbackResources, false);
	}
	private List<Resource> getScripts(String propertyName, List<String> resources,
			String fallback) {
		if (resources != null) {
			return getResources(propertyName, resources, true);
		}
		String platform = this.properties.getPlatform();
		List<String> fallbackResources = new ArrayList<>();
		fallbackResources.add("classpath*:" + fallback + "-" + platform + ".sql");
		fallbackResources.add("classpath*:" + fallback + ".sql");
		return getResources(propertyName, fallbackResources, false);
	}

 

spring.datasource.initialization-mode  初始化模式(springboot2.0),其中有三个值,always为始终执行初始化,embedded只初始化内存数据库(默认值),如h2等,never为不执行初始化。

/*
 * Copyright 2012-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.boot.jdbc;

/**
 * Supported {@link javax.sql.DataSource} initialization modes.
 *
 * @author Vedran Pavic
 * @author Stephane Nicoll
 * @since 2.0.0
 * @see AbstractDataSourceInitializer
 */
public enum DataSourceInitializationMode {

	/**
	 * Always initialize the datasource.
	 */
	ALWAYS,

	/**
	 * Only initialize an embedded datasource.
	 */
	EMBEDDED,

	/**
	 * Do not initialize the datasource.
	 */
	NEVER

}

spring.datasouce.data-passwork:

spring.datasouce.data-username:

spring.datasouce.schema-password:

spring.datasouce.schema-username:

这四个值为执行schema.sql或者data.sql时,用的用户

 

spring.datasource.sql-script-encoding: utf-8 为文件的编码

spring.datasource.separator: ; 为sql脚本中语句分隔符

spring.datasource.continue-on-error: false   遇到语句错误时是否继续,若已经执行过某些语句,再执行可能会报错,可以忽略,不会影响程序启动

 

2.使用hibernate初始化数据库

spring:
  jpa:
    show-sql: true
    #启动时是否初始化数据库-hibernate
    generate-ddl: false
    hibernate:
      ddl-auto: update

generate-ddl: true时,执行schema创建,会检测classpath下的import.sql文件,当然spring.jpa.hibernate.ddl-auto: 必须为create/update/create-drop,none和validate是不行的,因为这个创建时hibernate的,所以建议用spring的

 

 

更多内容请关注微信公众号:程序员星星,博客与csdn同时更新

<think>我们正在讨论SpringBootJPA的配置属性:spring.jpa.hibernate.ddl-auto=update根据引用[2]:spring.jpa.hibernate.ddl-auto是标准的Hibernate属性,可以设置为none、validate、update、create、create-drop。其中,update的作用是:当应用程序启动时,Hibernate会根据实体类(被@Entity注解的类)的结构去更新数据库表结构。具体来说:-如果数据库表不存在,则会创建新表。-如果数据库表已经存在,则会检查实体类的当前状态与数据库表结构是否一致。如果不一致,Hibernate会执行ALTERTABLE语句来添加新列、修改列等(注意:它不会删除列或更改现有列的数据类型,因为这样可能导致数据丢失)。但是,需要注意的是,update模式在生产环境中需要谨慎使用,因为它可能会在运行时修改数据库结构,可能会导致不可预知的问题。另外,它不能检测到列的重命名或删除,因为Hibernate无法确定这些操作是否安全。引用[3]进一步解释了:使用update时,JPA(通过Hibernate实现)会根据实体类的变化来更新数据库表结构。同时,引用[3]还提到了另一个属性spring.jpa.generate-dll,并建议避免同时使用这两个属性(spring.jpa.generate-dll和spring.jpa.hibernate.ddl-auto),以免混淆。通常,我们只设置spring.jpa.hibernate.ddl-auto。因此,总结一下:`spring.jpa.hibernate.ddl-auto=update`的作用是在应用程序启动时,自动将数据库表结构更新为与实体类定义相匹配的状态(仅添加新列和表,不会删除列或表)。注意:这个属性通常用于开发环境,方便在开发过程中修改实体类后自动更新数据库结构。在生产环境中,一般使用none或validate,以避免意外修改数据库结构。根据引用[2]的说明,SpringBoot的默认行为是:-对于内嵌数据库(如hsqldb,h2,derby),默认值是create-drop(启动时创建,关闭时删除)-对于非内嵌数据库(如MySQL,PostgreSQL等),默认值是none(即不做任何操作)所以,如果我们使用非内嵌数据库,并且希望自动更新表结构,需要显式设置`spring.jpa.hibernate.ddl-auto=update`。最后,提醒:自动更新表结构有一定的局限性,例如:-不会删除未使用的列或表-对于复杂的修改(如修改列类型、删除列、重命名列等)可能无法处理因此,对于生产环境,建议使用数据库迁移工具(如Flyway或Liquibase)来管理数据库结构变更。下面生成相关问题:</think>### `spring.jpa.hibernate.ddl-auto=update` 的作用详解 在 Spring Boot 中,`spring.jpa.hibernate.ddl-auto=update` 是一个关键的 JPA 配置属性,其作用主要体现在**数据库表结构的自动管理**上。具体功能如下: 1. **动态更新表结构** 当应用启动时,Hibernate 会自动检查实体类(`@Entity` 注解的类)的定义与数据库表结构的差异: - 若数据库表**不存在** → 自动创建新表 - 若数据库表**已存在** → 仅**增量更新**表结构(如添加新列、修改列类型),**不会删除**现有列或表[^2][^3]。 2. **与开发阶段的适配性** ```properties # 示例配置(application.properties) spring.jpa.hibernate.ddl-auto=update ``` - **适用场景**:开发/测试环境,频繁修改实体类结构时。 - **优势**:避免手动执行 SQL 脚本修改表结构,提升开发效率。 - **风险**:**不适用于生产环境**,可能导致意外数据丢失或结构冲突[^2][^3]。 3. **与其他模式的对比** | 属性值 | 行为 | 适用场景 | |--------------|----------------------------------------------------------------------|------------------| | `create` | 每次重启**删除旧表并新建表**(数据丢失) | 测试环境初始化 | | `create-drop`| 启动时建表,关闭时删表 | 单元测试 | | `validate` | 仅验证实体与表结构是否匹配(不匹配则报错) | 生产环境 | | `none` | 禁用 DDL 自动处理(默认值) | 生产环境 | 4. **注意事项** - **不支持删除列/重命名**:若实体类中删除字段,数据库中原字段仍保留[^3]。 - **与迁移工具冲突**:若使用 Flyway/Liquibase,应设为 `validate` 或 `none`。 - **优先级规则**:显式配置 `ddl-auto` 会覆盖 Spring Boot 的默认行为(内嵌数据库默认为 `create-drop`,其他默认为 `none`)[^2]。 > **实践建议**:生产环境务必关闭 `update` 模式,改用数据库版本控制工具(如 Flyway)执行结构化迁移脚本[^3]。 --- ###
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值