Bläddra i källkod

调整DdlScript.

nieqiurong 1 månad sedan
förälder
incheckning
4dd12f6250

+ 153 - 37
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/ddl/DdlScript.java

@@ -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;
+    }
+
 }

+ 28 - 0
mybatis-plus-extension/src/test/java/com/baomidou/mybatisplus/test/DdlScriptTest.java

@@ -0,0 +1,28 @@
+package com.baomidou.mybatisplus.test;
+
+import com.baomidou.mybatisplus.extension.ddl.DdlScript;
+import org.h2.Driver;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DdlScriptTest {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(DdlScriptTest.class);
+
+    @Test
+    void test() throws Exception {
+        var dddScript = new DdlScript(Driver.class.getName(),
+            "jdbc:h2:mem:test;MODE=mysql;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE",
+            "sa", "");
+        LOGGER.info("--------------execute----------------");
+        dddScript.run( "select 1 from dual;", msg ->{});
+        LOGGER.info("--------------execute----------------");
+        dddScript.run( "select 2 from dual;", msg ->{});
+        LOGGER.info("--------------run----------------");
+        dddScript.run("select 1 from dual;");
+        LOGGER.info("--------------run----------------");
+        dddScript.run("select 3 from dual#", "#");
+    }
+
+}