简介
当项目在一个新的环境启动或部署时,必不可少的步骤是完成数据库的初始化
将所需要的数据库表,可能还有一些初始的配置数据一次性写入到数据库中
常规的做法,是将初始化脚本整理到项目的资源目录中,提醒开发程序员或者运维人员在部署时手动执行
本文介绍如何优化地完成这个动作,将初始化脚本写入到项目的配置文件中,项目启动时,自动执行该脚本,完成数据库的初始化
配置
简单来说,是在 application.yml 文件中,增加下面这个配置,指定项目启动时加载的数据库脚本
spring:
# 数据库连接配置(先连接到MySQL服务器,不指定数据库)
datasource:
url: jdbc:mysql://localhost:3306/?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# 核心配置:自动执行SQL初始化数据库
sql:
init:
# 开启SQL初始化(SpringBoot 2.5+ 默认关闭,必须手动开启)
mode: always
# 指定要执行的SQL路径(多个用逗号分隔)
schema-locations: classpath:init.sql
# 编码(解决中文乱码)
encoding: utf-8
init.sql 内容如下,是数据库的初始化脚本,注意这个脚本应设计成幂等的,即多次执行效果相同
具体来说,就是创建前先判断是否存在,存在了就不创建,不存在才创建
-- =============================================
-- 数据库初始化脚本
-- 优雅初始化数据库演示项目
-- =============================================
-- 创建数据库(如果不存在)
CREATE DATABASE IF NOT EXISTS `db_elegant` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 使用该数据库
USE `db_elegant`;
-- 创建用户表(如果不存在)
CREATE TABLE IF NOT EXISTS `db_elegant`.`user` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`username` VARCHAR(50) NOT NULL COMMENT '用户名',
`email` VARCHAR(100) DEFAULT NULL COMMENT '邮箱',
`age` INT DEFAULT NULL COMMENT '年龄',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
-- 创建商品表(如果不存在)
CREATE TABLE IF NOT EXISTS `db_elegant`.`product` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` VARCHAR(100) NOT NULL COMMENT '商品名称',
`description` VARCHAR(500) DEFAULT NULL COMMENT '商品描述',
`price` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '价格',
`stock` INT NOT NULL DEFAULT 0 COMMENT '库存',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
-- 插入测试数据(数据不存在时才插入)
INSERT IGNORE INTO `db_elegant`.`user` (`username`, `email`, `age`) VALUES
('张三', 'zhangsan@example.com', 25),
('李四', 'lisi@example.com', 30),
('王五', 'wangwu@example.com', 28);
INSERT IGNORE INTO `db_elegant`.`product` (`name`, `description`, `price`, `stock`) VALUES
('iPhone 15 Pro', '苹果最新款手机', 8999.00, 100),
('MacBook Pro 14英寸', 'M3芯片专业笔记本', 14999.00, 50),
('AirPods Pro', '主动降噪耳机', 1899.00, 200);
-- 输出初始化完成信息
SELECT '数据库初始化完成!' AS message;
测试
启动项目试一下
它自己就把数据库脚本执行了
而且后续接口的查询,也都能查到该数据库的数据,因为在脚本中指定了数据库(USE db_elegant;)