一、FlyWay方案
1、添加依赖
xml
<!-- Flyway 依赖 -->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
2、添加配置
yaml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: ${mysql.url}
username: ${mysql.username}
password: ${mysql.password}
flyway:
enabled: true
cleanDisabled: true # 禁用 Flyway 所有的 drop 相关的逻辑,避免出现跑路的情况。
locations: # 迁移脚本目录
- classpath:db/migration # 配置 SQL-based 的 SQL 脚本在该目录下
- classpath:cn.iocoder.springboot.lab20.databaseversioncontrol.migration # 配置 Java-based 的 Java 文件在该目录下
check-location: false # 是否校验迁移脚本目录下。如果配置为 true ,代表需要校验。此时,如果目录下没有迁移脚本,会抛出 IllegalStateException 异常
url: jdbc:mysql://127.0.0.1:3306/lab-20-flyway?useSSL=false&useUnicode=true&characterEncoding=UTF-8 # 数据库地址
user: root # 数据库账号
password: # 数据库密码
3、添加SQL版本
放在resource/db/migration目录下
sql
-- 创建用户表
CREATE TABLE `users` (
`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 `users`(username, password, create_time) VALUES('yudaoyuanma', 'password', now());
4、测试代码以及回调验证
java
public class V1_1__FixUsername extends BaseJavaMigration {
@Override
public void migrate(Context context) throws Exception {
// 创建 JdbcTemplate ,方便 JDBC 操作
JdbcTemplate template = new JdbcTemplate(context.getConfiguration().getDataSource());
// 查询所有用户,如果用户名为 yudaoyuanma ,则变更成 yutou
template.query("SELECT id, username, password, create_time FROM users", new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws SQLException {
// 遍历返回的结果
do {
String username = rs.getString("username");
if ("yudaoyuanma".equals(username)) {
Integer id = rs.getInt("id");
template.update("UPDATE users SET username = ? WHERE id = ?",
"yutou", id);
logger.info("[migrate][更新 user({}) 的用户名({} => {})", id, username, "yutou");
}
} while (rs.next());
}
});
}
@Override
public Integer getChecksum() {
return 11; // 默认返回,是 null 。
}
@Override
public boolean canExecuteInTransaction() {
return true; // 默认返回,也是 true
}
@Override
public MigrationVersion getVersion() {
return super.getVersion(); // 默认按照约定的规则,从类名中解析获得。可以自定义
}
}
java
@Component
public class ExampleFlywayCallback implements Callback {
private Logger log = LoggerFactory.getLogger(getClass());
@Override
public boolean supports(Event event, Context context) {
return true;
}
@Override
public boolean canHandleInTransaction(Event event, Context context) {
return false;
}
@Override
public void handle(Event event, Context context) {
log.info("event: {}", event);
}
}