|
@@ -15,16 +15,20 @@
|
|
|
*/
|
|
|
package com.baomidou.mybatisplus.extension.ddl;
|
|
|
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
|
import com.baomidou.mybatisplus.extension.ddl.history.IDdlGenerator;
|
|
|
+import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
|
|
|
import org.apache.ibatis.jdbc.ScriptRunner;
|
|
|
+import org.apache.ibatis.logging.Log;
|
|
|
+import org.apache.ibatis.logging.LogFactory;
|
|
|
|
|
|
import javax.sql.DataSource;
|
|
|
import java.io.Reader;
|
|
|
import java.io.StringReader;
|
|
|
import java.sql.Connection;
|
|
|
import java.sql.DriverManager;
|
|
|
-import java.sql.SQLException;
|
|
|
import java.util.List;
|
|
|
import java.util.function.Consumer;
|
|
|
|
|
@@ -36,26 +40,90 @@ import java.util.function.Consumer;
|
|
|
*/
|
|
|
public class DdlScript {
|
|
|
|
|
|
+ private static final Log LOG = LogFactory.getLog(DdlScript.class);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 数据源
|
|
|
+ */
|
|
|
private final DataSource dataSource;
|
|
|
|
|
|
- private final IDdlGenerator ddlGenerator;
|
|
|
|
|
|
- private final boolean autoCommit;
|
|
|
+ /**
|
|
|
+ * DDL生成器
|
|
|
+ *
|
|
|
+ * @deprecated 3.5.11 区分职责,如果需要DDL版本控制请直接使用{@link DdlHelper}
|
|
|
+ */
|
|
|
+ @Deprecated
|
|
|
+ private IDdlGenerator ddlGenerator;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 是否自动提交
|
|
|
+ */
|
|
|
+ private boolean autoCommit;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 非池化执行 (非自动提交)
|
|
|
+ *
|
|
|
+ * @since 3.5.11
|
|
|
+ */
|
|
|
+ public DdlScript(String driverClassName, String url, String user, String password) {
|
|
|
+ this(driverClassName, url, user, password, false);
|
|
|
+ }
|
|
|
|
|
|
+ /**
|
|
|
+ * 非池化执行
|
|
|
+ *
|
|
|
+ * @since 3.5.11
|
|
|
+ */
|
|
|
+ public DdlScript(String driverClassName, String url, String user, String password, boolean autoCommit) {
|
|
|
+ this.dataSource = new UnpooledDataSource(driverClassName, url, user, password);
|
|
|
+ this.autoCommit = autoCommit;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建脚本执行器
|
|
|
+ *
|
|
|
+ * @param dataSource 数据源
|
|
|
+ */
|
|
|
public DdlScript(DataSource dataSource) {
|
|
|
- this(dataSource, null);
|
|
|
+ this.dataSource = dataSource;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 创建脚本执行器
|
|
|
+ *
|
|
|
+ * @param dataSource 数据源
|
|
|
+ * @param ddlGenerator DDL生成器
|
|
|
+ * @deprecated 3.5.11
|
|
|
+ */
|
|
|
+ @Deprecated
|
|
|
public DdlScript(DataSource dataSource, IDdlGenerator ddlGenerator) {
|
|
|
this(dataSource, ddlGenerator, false);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 创建脚本执行器
|
|
|
+ *
|
|
|
+ * @param dataSource 数据源
|
|
|
+ * @param ddlGenerator DDL生成器
|
|
|
+ * @param autoCommit 是否自动提交
|
|
|
+ * @deprecated 3.5.11
|
|
|
+ */
|
|
|
+ @Deprecated
|
|
|
public DdlScript(DataSource dataSource, IDdlGenerator ddlGenerator, boolean autoCommit) {
|
|
|
this.dataSource = dataSource;
|
|
|
this.ddlGenerator = ddlGenerator;
|
|
|
this.autoCommit = autoCommit;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 执行 SQL 脚本文件
|
|
|
+ *
|
|
|
+ * @param sqlFiles SQL 脚本文件列表
|
|
|
+ * @see DdlHelper#runScript(IDdlGenerator, DataSource, List, boolean)
|
|
|
+ * @deprecated 3.5.11
|
|
|
+ */
|
|
|
+ @Deprecated
|
|
|
public void run(List<String> sqlFiles) {
|
|
|
this.run(sqlFiles, this.autoCommit);
|
|
|
}
|
|
@@ -65,13 +133,22 @@ public class DdlScript {
|
|
|
*
|
|
|
* @param sqlFiles SQL 脚本文件列表
|
|
|
* @param autoCommit 自动提交事务
|
|
|
+ * @see DdlHelper#runScript(IDdlGenerator, DataSource, List, boolean)
|
|
|
+ * @deprecated 3.5.11
|
|
|
*/
|
|
|
+ @Deprecated
|
|
|
public void run(List<String> sqlFiles, boolean autoCommit) {
|
|
|
DdlHelper.runScript(this.ddlGenerator, this.dataSource, sqlFiles, autoCommit);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 运行 SQL 脚本
|
|
|
+ *
|
|
|
+ * @param sqlScript 脚本内容
|
|
|
+ * @throws Exception {@link org.apache.ibatis.jdbc.RuntimeSqlException}
|
|
|
+ */
|
|
|
public void run(String sqlScript) throws Exception {
|
|
|
- this.run(sqlScript, null);
|
|
|
+ this.run(sqlScript, StringPool.SEMICOLON);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -79,28 +156,30 @@ public class DdlScript {
|
|
|
*
|
|
|
* @param sqlScript SQL 脚本内容
|
|
|
* @param delimiter 执行 SQL 分隔符,默认 ; 符号结束执行
|
|
|
- * @throws Exception
|
|
|
+ * @throws Exception {@link org.apache.ibatis.jdbc.RuntimeSqlException}
|
|
|
*/
|
|
|
public void run(String sqlScript, String delimiter) throws Exception {
|
|
|
this.run(new StringReader(sqlScript), this.autoCommit, delimiter);
|
|
|
}
|
|
|
|
|
|
public void run(Reader reader) throws Exception {
|
|
|
- this.run(reader, this.autoCommit, null);
|
|
|
+ this.run(reader, this.autoCommit, StringPool.SEMICOLON);
|
|
|
}
|
|
|
|
|
|
public void run(Reader reader, boolean autoCommit) throws Exception {
|
|
|
- this.run(reader, autoCommit, null);
|
|
|
+ this.run(reader, autoCommit, StringPool.SEMICOLON);
|
|
|
}
|
|
|
|
|
|
public void run(Reader reader, boolean autoCommit, String delimiter) throws Exception {
|
|
|
- this.run(this.dataSource.getConnection(), reader, autoCommit, delimiter);
|
|
|
+ try (Connection connection = this.dataSource.getConnection()) {
|
|
|
+ this.run(connection, reader, autoCommit, delimiter);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 执行 SQL 脚本
|
|
|
*
|
|
|
- * @param connection {@link Connection}
|
|
|
+ * @param connection {@link Connection} 调用方需要自行控制关闭
|
|
|
* @param reader SQL 脚本内容
|
|
|
* @param autoCommit 自动提交事务
|
|
|
* @param delimiter 执行 SQL 分隔符,默认 ; 符号结束执行
|
|
@@ -115,50 +194,87 @@ public class DdlScript {
|
|
|
scriptRunner.runScript(reader);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 以默认分隔符(;) 执行 SQL 脚本
|
|
|
+ *
|
|
|
+ * @param driverClassName 连接驱动名
|
|
|
+ * @param url 连接地址
|
|
|
+ * @param user 数据库用户名
|
|
|
+ * @param password 数据库密码
|
|
|
+ * @param sqlScript 执行 SQL 脚本
|
|
|
+ * @param exceptionConsumer 异常处理
|
|
|
+ * @see DdlScript(String, String, String, String)
|
|
|
+ * @see #run(String, Consumer)
|
|
|
+ * @deprecated 3.5.11
|
|
|
+ */
|
|
|
+ @Deprecated
|
|
|
public boolean execute(final String driverClassName, final String url, final String user, final String password,
|
|
|
- final String sql, Consumer<String> exceptionConsumer) {
|
|
|
- return this.execute(driverClassName, url, user, password, sql, null, exceptionConsumer);
|
|
|
+ final String sqlScript, Consumer<String> exceptionConsumer) {
|
|
|
+ return this.execute(driverClassName, url, user, password, sqlScript, StringPool.SEMICOLON, exceptionConsumer);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 以默认分隔符(;) 执行 SQL 脚本
|
|
|
+ *
|
|
|
+ * @param sqlScript 执行 SQL脚本
|
|
|
+ * @param exceptionConsumer 异常处理
|
|
|
+ * @since 3.5.11
|
|
|
+ */
|
|
|
+ public boolean run(String sqlScript, Consumer<String> exceptionConsumer) {
|
|
|
+ return this.run(sqlScript, StringPool.SEMICOLON, exceptionConsumer);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * jdbc 连接指定 sql 执行
|
|
|
+ * 以指定分隔符 执行 SQL 脚本
|
|
|
*
|
|
|
* @param driverClassName 连接驱动名
|
|
|
* @param url 连接地址
|
|
|
* @param user 数据库用户名
|
|
|
* @param password 数据库密码
|
|
|
- * @param sql 执行 SQL
|
|
|
+ * @param sqlScript 执行 SQL 脚本
|
|
|
* @param delimiter 执行 SQL 分隔符,默认 ; 符号结束执行
|
|
|
* @param exceptionConsumer 异常处理
|
|
|
- * @return
|
|
|
+ * @return 操作结果
|
|
|
+ * @deprecated 3.5.11 {@link #run(String, String, Consumer)}
|
|
|
*/
|
|
|
+ @Deprecated
|
|
|
public boolean execute(final String driverClassName, final String url, final String user, final String password,
|
|
|
- final String sql, String delimiter, Consumer<String> exceptionConsumer) {
|
|
|
- Connection connection = null;
|
|
|
- try {
|
|
|
- Class.forName(driverClassName);
|
|
|
- connection = DriverManager.getConnection(url, user, password);
|
|
|
- // 执行 SQL 脚本
|
|
|
- this.run(connection, new StringReader(sql), this.autoCommit, delimiter);
|
|
|
+ final String sqlScript, String delimiter, Consumer<String> exceptionConsumer) {
|
|
|
+ //一般不需要显示加载,只有很旧很旧的驱动才需要
|
|
|
+ if (StringUtils.isNotBlank(driverClassName)) {
|
|
|
+ Class<?> driverClass = ClassUtils.toClassConfident(driverClassName);
|
|
|
+ if (LOG.isDebugEnabled()) {
|
|
|
+ LOG.debug("Load driver class: " + driverClass.getName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ try (Connection connection = DriverManager.getConnection(url, user, password)) {
|
|
|
+ this.run(connection, new StringReader(sqlScript), this.autoCommit, delimiter);
|
|
|
return true;
|
|
|
} catch (Exception e) {
|
|
|
- if (null != connection) {
|
|
|
- try {
|
|
|
- connection.rollback();
|
|
|
- } catch (SQLException ex) {
|
|
|
- ex.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
+ LOG.error("Execute sqlScript: " + sqlScript + " , fail:", e);
|
|
|
exceptionConsumer.accept(e.getMessage());
|
|
|
- } finally {
|
|
|
- if (null != connection) {
|
|
|
- try {
|
|
|
- connection.close();
|
|
|
- } catch (SQLException ex) {
|
|
|
- ex.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 以指定分隔符 执行 SQL 脚本
|
|
|
+ *
|
|
|
+ * @param sqlScript 执行 SQL 脚本
|
|
|
+ * @param exceptionConsumer 异常处理
|
|
|
+ * @param delimiter 执行 SQL 分隔符,默认 ; 符号结束执行
|
|
|
+ * @return 操作结果
|
|
|
+ * @since 3.5.11
|
|
|
+ */
|
|
|
+ public boolean run(String sqlScript, String delimiter, Consumer<String> exceptionConsumer) {
|
|
|
+ try (Connection connection = dataSource.getConnection()) {
|
|
|
+ this.run(connection, new StringReader(sqlScript), this.autoCommit, delimiter);
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ LOG.error("Execute sqlScript: " + sqlScript + " , fail:", e);
|
|
|
+ exceptionConsumer.accept(e.getMessage());
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
}
|