liquIbase方式
1、添加依赖
xml
<!-- Liquibase 依赖 -->
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
2、添加配置项
yaml
spring:
# datasource 数据源配置内容,对应 DataSourceProperties 配置属性类
datasource:
url: jdbc:mysql://127.0.0.1:3306/lab-20-liquibase?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root # 数据库账号
password: # 数据库密码
# Liquibase 配置内容,对应 LiquibaseProperties 配置项
liquibase:
enabled: true # 开启 Liquibase 功能。默认为 true 。
change-log: classpath:/db/changelog/db.changelog-master.yaml # Liquibase 配置文件地址
url: jdbc:mysql://127.0.0.1:3306/lab-20-liquibase?useSSL=false&useUnicode=true&characterEncoding=UTF-8 # 数据库地址
user: root # 数据库账号
password: # 数据库密码
3、添加版本变更Log配置项
db目录下的db.changelog-master.yaml
yaml
databaseChangeLog:
- changeSet: # 对应一个 ChangeSet 对象
id: 0 # ChangeSet 编号
author: yunai # 作者
comments: 空 # 备注
- changeSet: # 对应一个 ChangeSet 对象
id: 1 # ChangeSet 编号
author: yunai # 作者
comments: 初始化 users 表 # 备注
changes: # 对应 Change 数组。Change 是一个接口,每种操作对应一种 Change 实现类
- createTable: # 创建表,对应 CreateTableChange 对象。
tableName: users # 表名
remarkds: 用户表 # 表注释
columns: # 对应 ColumnConfig 数组
- column:
name: id # 字段名
type: int # 字段类型
autoIncrement: true # 自增
constraints: # 限制条件,对应一个 ConstraintsConfig 对象
primaryKey: true # 主键
nullable: false # 不允许空
- column:
name: username
type: varchar(64)
constraints:
nullable: false
- column:
name: password
type: varchar(32)
constraints:
nullable: false
- column:
name: create_time
type: datetime
constraints:
nullable: false
- insert: # 插入记录,对应 InsertDataChange 对象。
tableName: users # 表名
columns: # 对应 ColumnConfig 数组
- column:
name: username # 字段名
value: yudaoyuanma # 值
- column:
name: password
value: password
- column:
name: create_time
value: now()
- changeSet: # 对应一个 ChangeSet 对象
id: 2 # ChangeSet 编号
author: yunai # 作者
comments: 初始化 users2 表 # 备注
changes: # 对应 Change 数组。Change 是一个接口,每种操作对应一种 Change 实现类
- sqlFile: # 使用 SQL 文件,对应 SQLFileChange 对象
encoding: utf8
path: classpath:db/changelog/sqlfile/CHAGE_SET_2_INIT_DB.sql
- changeSet: # 对应一个 ChangeSet 对象
id: 3 # ChangeSet 编号
author: yunai # 作者
comments: 修复 `users` 的用户名 # 备注
changes: # 对应 Change 数组。Change 是一个接口,每种操作对应一种 Change 实现类
- customChange: {class: cn.iocoder.springboot.lab20.databaseversioncontrol.migration.CHANGE_SET_3_FixUsername} # 对应 CustomTaskChange
4、SQL文件
sql
-- 创建用户表
CREATE TABLE `users2` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
`username` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号',
`password` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
-- 插入一条数据
INSERT INTO `users2`(username, password, create_time) VALUES('yudaoyuanma', 'password', now());
5、版本控制测试
java
public class CHANGE_SET_3_FixUsername implements CustomTaskChange {
private Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void execute(Database database) throws CustomChangeException {
JdbcConnection connection = (JdbcConnection) database.getConnection();
try (PreparedStatement psmt = connection.prepareStatement("SELECT id, username, password, create_time FROM users")) {
try (ResultSet rs = psmt.executeQuery()) {
while (rs.next()) {
String username = rs.getString("username");
if ("yudaoyuanma".equals(username)) {
Integer id = rs.getInt("id");
// 这里,再来一刀更新操作,偷懒不写了。
logger.info("[migrate][更新 user({}) 的用户名({} => {})", id, username, "yutou");
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public String getConfirmationMessage() {
return null;
}
@Override
public void setUp() throws SetupException {
}
@Override
public void setFileOpener(ResourceAccessor resourceAccessor) {
}
@Override
public ValidationErrors validate(Database database) {
return null;
}
}