Browse Source

优化数据库解析

zhou-hao 7 years ago
parent
commit
c9e1fb770a
29 changed files with 746 additions and 236 deletions
  1. 6 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/pom.xml
  2. 4 35
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/DatabaseManagerService.java
  3. 9 7
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/SqlExecuteRequest.java
  4. 9 17
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/SqlExecuteResult.java
  5. 0 2
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/SqlInfo.java
  6. 10 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/exception/SqlExecuteException.java
  7. 32 60
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/ColumnMetadata.java
  8. 32 25
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/Constraint.java
  9. 3 15
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/ForeignConstraint.java
  10. 8 15
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/TableMetadata.java
  11. 115 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/AbstractSqlTableMetaDataParser.java
  12. 13 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/MetaDataParser.java
  13. 8 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/MetaDataParserRegister.java
  14. 10 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/MetaDataParserSupplier.java
  15. 7 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/TableMetaDataParser.java
  16. 44 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/support/H2TableMetaDataParser.java
  17. 44 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/support/MysqlTableMetaDataParser.java
  18. 45 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/support/OralceTableMetaDataParser.java
  19. 43 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/support/SqlServerTableMetaDataParser.java
  20. 11 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/sql/SqlExecutor.java
  21. 41 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/sql/TransactionSqlExecutor.java
  22. 44 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/test/src/org/hswebframework/web/database/manager/meta/table/parser/support/H2TableMetaDataParserTest.java
  23. 93 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/main/java/org/hswebframework/web/datasource/manager/simple/DatabaseManagerAutoConfiguration.java
  24. 15 46
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/main/java/org/hswebframework/web/datasource/manager/simple/DefaultLocalTransactionExecutor.java
  25. 52 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/main/java/org/hswebframework/web/datasource/manager/simple/NonTransactionSqlExecutor.java
  26. 38 11
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/main/java/org/hswebframework/web/datasource/manager/simple/SimpleDatabaseManagerService.java
  27. 1 1
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/main/java/org/hswebframework/web/datasource/manager/simple/TransactionExecutor.java
  28. 3 0
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/main/resources/META-INF/spring.factories
  29. 6 2
      hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/test/java/org/hswebframework/web/datasource/manager/simple/SimpleDatabaseManagerServiceTest.java

+ 6 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/pom.xml

@@ -18,5 +18,11 @@
             <artifactId>hsweb-datasource-api</artifactId>
             <version>${project.version}</version>
         </dependency>
+
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>

+ 4 - 35
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/DatabaseManagerService.java

@@ -1,6 +1,8 @@
 package org.hswebframework.web.database.manager;
 
 import org.hswebframework.web.database.manager.meta.ObjectMetadata;
+import org.hswebframework.web.database.manager.sql.SqlExecutor;
+import org.hswebframework.web.database.manager.sql.TransactionSqlExecutor;
 import org.hswebframework.web.datasource.DynamicDataSource;
 
 import java.util.List;
@@ -9,39 +11,6 @@ import java.util.Map;
 /**
  * @author zhouhao
  */
-public interface DatabaseManagerService {
-
-    /**
-     * 开启一个指定数据源的事务,并返回事务ID,在其他操作的时候,使用事务ID共享同一个事务
-     *
-     * @param datasourceId 数据源ID {@link DynamicDataSource#getId()}
-     * @return 事务ID
-     */
-    String newTransaction(String datasourceId);
-
-    /**
-     * 对默认数据源开启事务,并返回事务ID,在其他操作的时候,使用事务ID共享同一个事务
-     *
-     * @return 事务ID
-     */
-    String newTransaction();
-
-    /**
-     * 提交事务
-     *
-     * @param transactionId 事务ID
-     */
-    void commit(String transactionId);
-
-    /**
-     * 回滚事务
-     *
-     * @param transactionId 事务ID
-     */
-    void rollback(String transactionId);
-
-    List<SqlExecuteResult> execute(String transactionId, SqlExecuteRequest request);
-
-    Map<ObjectMetadata.ObjectType, List<ObjectMetadata>> getMetas(String datasourceId);
-
+public interface DatabaseManagerService extends SqlExecutor,TransactionSqlExecutor {
+    Map<ObjectMetadata.ObjectType, List<? extends ObjectMetadata>> getMetas(String datasourceId);
 }

+ 9 - 7
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/SqlExecuteRequest.java

@@ -1,19 +1,21 @@
 package org.hswebframework.web.database.manager;
 
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
 import java.io.Serializable;
 import java.util.List;
 
 /**
  * @author zhouhao
  */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
 public class SqlExecuteRequest implements Serializable{
     private List<SqlInfo> sql;
 
-    public List<SqlInfo> getSql() {
-        return sql;
-    }
-
-    public void setSql(List<SqlInfo> sql) {
-        this.sql = sql;
-    }
 }

+ 9 - 17
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/SqlExecuteResult.java

@@ -1,29 +1,21 @@
 package org.hswebframework.web.database.manager;
 
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
 /**
- * TODO 完成注释
- *
  * @author zhouhao
  */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
 public class SqlExecuteResult {
 
     private SqlInfo sqlInfo;
 
     private Object result;
 
-    public SqlInfo getSqlInfo() {
-        return sqlInfo;
-    }
-
-    public void setSqlInfo(SqlInfo sqlInfo) {
-        this.sqlInfo = sqlInfo;
-    }
-
-    public Object getResult() {
-        return result;
-    }
-
-    public void setResult(Object result) {
-        this.result = result;
-    }
 }

+ 0 - 2
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/SqlInfo.java

@@ -3,8 +3,6 @@ package org.hswebframework.web.database.manager;
 import java.io.Serializable;
 
 /**
- * TODO 完成注释
- *
  * @author zhouhao
  */
 public class SqlInfo implements Serializable {

+ 10 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/exception/SqlExecuteException.java

@@ -0,0 +1,10 @@
+package org.hswebframework.web.database.manager.exception;
+
+public class SqlExecuteException extends RuntimeException {
+    private String sql;
+
+    public SqlExecuteException(String message, Throwable cause, String sql) {
+        super(message, cause);
+        this.sql = sql;
+    }
+}

+ 32 - 60
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/ColumnMetadata.java

@@ -1,84 +1,56 @@
 package org.hswebframework.web.database.manager.meta.table;
 
+import lombok.Data;
+
 import java.io.Serializable;
+import java.sql.JDBCType;
 import java.util.List;
 
 /**
- *
  * @author zhouhao
  */
+@Data
 public class ColumnMetadata implements Serializable {
     private static final long serialVersionUID = 2068679809718583039L;
+
+    /**
+     * 列名
+     */
     private String name;
 
+    /**
+     * 备注
+     */
     private String comment;
 
+    /**
+     * 数据类型
+     */
     private String dataType;
-    //长度
-    private int    length;
 
-    //精度
+    /**
+     * 长度
+     */
+    private int length;
+
+    /**
+     * 精度
+     */
     private int precision;
 
-    //小数位数
+    /**
+     * 小数点位数
+     */
     private int scale;
 
+    /**
+     * 是否不能为空
+     */
     private boolean notNull;
 
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getComment() {
-        return comment;
-    }
-
-    public void setComment(String comment) {
-        this.comment = comment;
-    }
-
-    public String getDataType() {
-        return dataType;
-    }
-
-    public void setDataType(String dataType) {
-        this.dataType = dataType;
-    }
-
-    public int getLength() {
-        return length;
-    }
-
-    public void setLength(int length) {
-        this.length = length;
-    }
-
-    public int getPrecision() {
-        return precision;
-    }
-
-    public void setPrecision(int precision) {
-        this.precision = precision;
-    }
-
-    public int getScale() {
-        return scale;
-    }
-
-    public void setScale(int scale) {
-        this.scale = scale;
-    }
-
-    public boolean isNotNull() {
-        return notNull;
-    }
-
-    public void setNotNull(boolean notNull) {
-        this.notNull = notNull;
-    }
+    /**
+     * JDBCType
+     */
+    private JDBCType jdbcType;
 
 }

+ 32 - 25
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/Constraint.java

@@ -1,43 +1,50 @@
 package org.hswebframework.web.database.manager.meta.table;
 
+import lombok.Data;
+
 import java.io.Serializable;
 
 /**
+ * 约束
+ *
  * @author zhouhao
+ * @since 3.0
  */
+@Data
 public class Constraint implements Serializable {
     private static final long serialVersionUID = 6594361915290310179L;
+
+    /**
+     * 表名
+     *
+     * @see TableMetadata#getName()
+     */
     private String table;
 
+    /**
+     * 列名
+     *
+     * @see ColumnMetadata#getName()
+     */
     private String column;
 
+    /**
+     * 约束类型
+     */
     private Type type;
 
-    public String getTable() {
-        return table;
-    }
-
-    public void setTable(String table) {
-        this.table = table;
-    }
-
-    public String getColumn() {
-        return column;
-    }
-
-    public void setColumn(String column) {
-        this.column = column;
-    }
-
-    public Type getType() {
-        return type;
-    }
-
-    public void setType(Type type) {
-        this.type = type;
-    }
-
     public enum Type {
-        PrimaryKey, ForeignKey, Unique, Check, Default
+        /**
+         * 主键
+         */
+        PrimaryKey,
+        /**
+         * 外键
+         */
+        ForeignKey,
+        /**
+         * 唯一约束
+         */
+        Unique, Check, Default
     }
 }

+ 3 - 15
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/ForeignConstraint.java

@@ -1,27 +1,15 @@
 package org.hswebframework.web.database.manager.meta.table;
 
+import lombok.Data;
+
 /**
  * @author zhouhao
  */
+@Data
 public class ForeignConstraint extends Constraint {
     private static final long serialVersionUID = -7146549641064694467L;
     private String targetTable;
 
     private String targetColumn;
 
-    public String getTargetTable() {
-        return targetTable;
-    }
-
-    public void setTargetTable(String targetTable) {
-        this.targetTable = targetTable;
-    }
-
-    public String getTargetColumn() {
-        return targetColumn;
-    }
-
-    public void setTargetColumn(String targetColumn) {
-        this.targetColumn = targetColumn;
-    }
 }

+ 8 - 15
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/TableMetadata.java

@@ -1,12 +1,19 @@
 package org.hswebframework.web.database.manager.meta.table;
 
+import lombok.*;
 import org.hswebframework.web.database.manager.meta.ObjectMetadata;
+import org.springframework.stereotype.Service;
 
 import java.util.List;
 
 /**
  * @author zhouhao
  */
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
 public class TableMetadata extends ObjectMetadata {
     private static final long serialVersionUID = 1762059989615865556L;
 
@@ -14,19 +21,5 @@ public class TableMetadata extends ObjectMetadata {
 
     private List<Constraint> constraints;
 
-    public String getComment() {
-        return comment;
-    }
-
-    public void setComment(String comment) {
-        this.comment = comment;
-    }
-
-    public List<Constraint> getConstraints() {
-        return constraints;
-    }
-
-    public void setConstraints(List<Constraint> constraints) {
-        this.constraints = constraints;
-    }
+    private List<ColumnMetadata> columns;
 }

+ 115 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/AbstractSqlTableMetaDataParser.java

@@ -0,0 +1,115 @@
+package org.hswebframework.web.database.manager.meta.table.parser;
+
+import org.apache.commons.beanutils.BeanUtilsBean;
+import org.hswebframework.ezorm.core.ObjectWrapper;
+import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
+import org.hswebframework.web.database.manager.meta.table.ColumnMetadata;
+import org.hswebframework.web.database.manager.meta.table.TableMetadata;
+import org.hswebframework.web.datasource.DatabaseType;
+
+import java.sql.SQLException;
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.stream.Collectors;
+
+public abstract class AbstractSqlTableMetaDataParser implements TableMetaDataParser, MetaDataParserSupplier {
+
+    private SqlExecutor sqlExecutor;
+
+    private static ColumnMetadataWrapper wrapper = new ColumnMetadataWrapper();
+
+    public abstract String getSelectTableColumnsSql();
+
+    public abstract String getSelectTableMetaSql();
+
+    public abstract String getSelectAllTableSql();
+
+    public AbstractSqlTableMetaDataParser(SqlExecutor sqlExecutor,DatabaseType... databaseTypes) {
+        this.sqlExecutor = sqlExecutor;
+        supportDataBases.addAll(Arrays.asList(databaseTypes));
+    }
+
+    private Set<DatabaseType> supportDataBases =new HashSet<>();
+
+    @Override
+    public boolean isSupport(DatabaseType type) {
+        return supportDataBases.contains(type);
+    }
+
+    @Override
+    public MetaDataParser get() {
+        return this;
+    }
+
+    @Override
+    public List<TableMetadata> parseAll() throws SQLException {
+        return sqlExecutor.list(getSelectAllTableSql())
+                .parallelStream()
+                .map(map -> map.get("name"))
+                .map(String::valueOf)
+                .map(tableName -> {
+                    try {
+                        return this.parse(tableName);
+                    } catch (SQLException e) {
+                        throw new RuntimeException(e);
+                    }
+                })
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public TableMetadata parse(String objectName) throws SQLException {
+
+        Map<String, Object> param = new HashMap<>();
+        param.put("table", objectName);
+
+        Map<String, Object> tableMetaMap = sqlExecutor.single(getSelectTableMetaSql(), param);
+
+        if (tableMetaMap == null) {
+            return null;
+        }
+        TableMetadata table = new TableMetadata();
+        table.setName(objectName);
+        table.setComment((String) tableMetaMap.getOrDefault("comment", ""));
+        List<ColumnMetadata> columns = sqlExecutor.list(getSelectTableColumnsSql(), param, wrapper);
+
+        table.setColumns(columns);
+
+        return table;
+    }
+
+
+    static class ColumnMetadataWrapper implements ObjectWrapper<ColumnMetadata> {
+        static Map<String, BiConsumer<ColumnMetadata, Object>> propertySetters = new HashMap<>();
+
+        static {
+            propertySetters.put("name", (columnMetadata, value) -> columnMetadata.setName(String.valueOf(value)));
+
+        }
+
+        @Override
+        public Class<ColumnMetadata> getType() {
+            return ColumnMetadata.class;
+        }
+
+        @Override
+        public ColumnMetadata newInstance() {
+            return new ColumnMetadata();
+        }
+
+        @Override
+        public void wrapper(ColumnMetadata instance, int index, String attr, Object value) {
+            try {
+                BeanUtilsBean.getInstance().setProperty(instance, attr, value);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        @Override
+        public boolean done(ColumnMetadata instance) {
+            return true;
+        }
+    }
+}

+ 13 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/MetaDataParser.java

@@ -0,0 +1,13 @@
+package org.hswebframework.web.database.manager.meta.table.parser;
+
+import org.hswebframework.web.database.manager.meta.ObjectMetadata;
+
+import java.sql.SQLException;
+import java.util.List;
+
+public interface MetaDataParser<M extends ObjectMetadata> {
+
+    List<M> parseAll() throws SQLException;
+
+    M parse(String objectName) throws SQLException;
+}

+ 8 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/MetaDataParserRegister.java

@@ -0,0 +1,8 @@
+package org.hswebframework.web.database.manager.meta.table.parser;
+
+import org.hswebframework.web.database.manager.meta.ObjectMetadata;
+import org.hswebframework.web.datasource.DatabaseType;
+
+public interface MetaDataParserRegister {
+    <M extends ObjectMetadata> void registerMetaDataParser(DatabaseType databaseType, ObjectMetadata.ObjectType objectType, MetaDataParser<M> parser);
+}

+ 10 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/MetaDataParserSupplier.java

@@ -0,0 +1,10 @@
+package org.hswebframework.web.database.manager.meta.table.parser;
+
+import org.hswebframework.web.database.manager.meta.ObjectMetadata;
+import org.hswebframework.web.datasource.DatabaseType;
+
+public interface MetaDataParserSupplier<M extends ObjectMetadata>  {
+    boolean isSupport(DatabaseType type);
+
+    MetaDataParser<M> get();
+}

+ 7 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/TableMetaDataParser.java

@@ -0,0 +1,7 @@
+package org.hswebframework.web.database.manager.meta.table.parser;
+
+import org.hswebframework.web.database.manager.meta.table.TableMetadata;
+
+public interface TableMetaDataParser extends MetaDataParser<TableMetadata> {
+
+}

+ 44 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/support/H2TableMetaDataParser.java

@@ -0,0 +1,44 @@
+package org.hswebframework.web.database.manager.meta.table.parser.support;
+
+import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
+import org.hswebframework.web.database.manager.meta.table.parser.AbstractSqlTableMetaDataParser;
+import org.hswebframework.web.datasource.DatabaseType;
+
+public class H2TableMetaDataParser extends AbstractSqlTableMetaDataParser {
+   private static final String TABLE_META_SQL = "SELECT " +
+            "column_name AS \"name\"" +
+            ",type_name AS \"dataType\"" +
+            ",character_maximum_length as \"length\"" +
+            ",numeric_precision as \"precision\"" +
+            ",numeric_scale as \"scale\"" +
+            ",case when is_nullable='YES' then 0 else 1 end as \"notNull\"" +
+            ",remarks as \"comment\" " +
+            "FROM information_schema.columns WHERE TABLE_NAME = upper(#{table})";
+
+    private  static final String TABLE_COMMENT_SQL = "SELECT " +
+            "remarks as \"comment\" " +
+            "FROM information_schema.tables " +
+            "WHERE table_type='TABLE' and table_name=upper(#{table})";
+
+    private static final String ALL_TABLE_SQL = "select table_name as \"name\" FROM information_schema.tables where table_type='TABLE'";
+
+    public H2TableMetaDataParser(SqlExecutor sqlExecutor) {
+        super(sqlExecutor,DatabaseType.h2);
+    }
+
+    @Override
+    public String getSelectTableColumnsSql() {
+        return TABLE_META_SQL;
+    }
+
+    @Override
+    public String getSelectTableMetaSql() {
+        return TABLE_COMMENT_SQL;
+    }
+
+    @Override
+    public String getSelectAllTableSql() {
+        return ALL_TABLE_SQL;
+    }
+
+}

+ 44 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/support/MysqlTableMetaDataParser.java

@@ -0,0 +1,44 @@
+package org.hswebframework.web.database.manager.meta.table.parser.support;
+
+import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
+import org.hswebframework.web.database.manager.meta.table.parser.AbstractSqlTableMetaDataParser;
+import org.hswebframework.web.datasource.DatabaseType;
+
+public class MysqlTableMetaDataParser extends AbstractSqlTableMetaDataParser {
+
+    private static final String TABLE_META_SQL = " select " +
+            "column_name as `name`, " +
+            "data_type as `dataType`, " +
+            "character_maximum_length as `length`, " +
+            "numeric_precision as `precision`, " +
+            "numeric_scale as `scale`, " +
+            "column_comment as `comment`, " +
+            "case when is_nullable='YES' then 0 else 1 end as 'notNull' " +
+            "from information_schema.columns where table_schema=database() and table_name=#{table}";
+
+    private  static final String TABLE_COMMENT_SQL = " select " +
+            "table_comment as `comment` " +
+            "from information_schema.tables where table_name=#{table}";
+
+    private static final String ALL_TABLE_SQL = "select table_name as `name` from information_schema.`TABLES` where table_schema=database()";
+
+    public MysqlTableMetaDataParser(SqlExecutor sqlExecutor) {
+        super(sqlExecutor,DatabaseType.mysql);
+    }
+
+    @Override
+    public String getSelectTableColumnsSql() {
+        return TABLE_META_SQL;
+    }
+
+    @Override
+    public String getSelectTableMetaSql() {
+        return TABLE_COMMENT_SQL;
+    }
+
+    @Override
+    public String getSelectAllTableSql() {
+        return ALL_TABLE_SQL;
+    }
+
+}

+ 45 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/support/OralceTableMetaDataParser.java

@@ -0,0 +1,45 @@
+package org.hswebframework.web.database.manager.meta.table.parser.support;
+
+import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
+import org.hswebframework.web.database.manager.meta.table.parser.AbstractSqlTableMetaDataParser;
+import org.hswebframework.web.datasource.DatabaseType;
+
+public class OralceTableMetaDataParser extends AbstractSqlTableMetaDataParser {
+
+    private final static String TABLE_META_SQL = "select distinct(cols.column_name) as \"name\"" +
+            ",cols.table_name as \"name\"" +
+            ",cols.data_type as \"dataType\"" +
+            ",cols.data_length as \"dataLength\"" +
+            ",cols.data_precision as \"precision\"" +
+            ",cols.data_scale as \"scale\"" +
+            ",acc.comments as \"comment\"" +
+            ",case when cols.nullable='Y' then 0 else 1 end as \"notNull\"" +
+            ",cols.column_id from user_tab_columns cols " +
+            "left join all_col_comments acc on acc.column_name=cols.column_name and acc.table_name=cols.table_name " +
+            "where cols.table_name=upper(#{table}) " +
+            "order by cols.column_id ";
+
+    private final static String TABLE_COMMENT_SQL = "select comments as \"comment\" from user_tab_comments where table_type='TABLE' and table_name=upper(#{table})";
+
+    private final static String ALL_TABLE_SQL = "select table_name as \"name\" from user_tab_comments where table_type='TABLE'";
+
+    public OralceTableMetaDataParser(SqlExecutor sqlExecutor) {
+        super(sqlExecutor, DatabaseType.oracle);
+    }
+
+    @Override
+    public String getSelectTableColumnsSql() {
+        return TABLE_META_SQL;
+    }
+
+    @Override
+    public String getSelectTableMetaSql() {
+        return TABLE_COMMENT_SQL;
+    }
+
+    @Override
+    public String getSelectAllTableSql() {
+        return ALL_TABLE_SQL;
+    }
+
+}

+ 43 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/meta/table/parser/support/SqlServerTableMetaDataParser.java

@@ -0,0 +1,43 @@
+package org.hswebframework.web.database.manager.meta.table.parser.support;
+
+import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
+import org.hswebframework.web.database.manager.meta.table.parser.AbstractSqlTableMetaDataParser;
+import org.hswebframework.web.datasource.DatabaseType;
+
+public class SqlServerTableMetaDataParser extends AbstractSqlTableMetaDataParser {
+    private static String TABLE_META_SQL = "SELECT \n" +
+            "c.name as [name],\n" +
+            "t.name as [dataType],\n" +
+            "c.length as [length],\n" +
+            "c.xscale as [scale],\n" +
+            "c.xprec as [precision],\n" +
+            "case when c.isnullable=1 then 0 else  1 end as [notNull],\n" +
+            "cast(p.value as varchar(500)) as [comment]\n" +
+            "FROM syscolumns c\n" +
+            "inner join  systypes t on c.xusertype = t.xusertype \n" +
+            "left join sys.extended_properties p on c.id=p.major_id and c.colid=p.minor_id\n" +
+            "WHERE c.id = object_id(#{table})";
+
+    private static String TABLE_COMMENT_SQL = "select cast(p.value as varchar(500)) as [comment] from sys.extended_properties p " +
+            " where p.major_id=object_id(#{table}) and p.minor_id=0";
+
+    public SqlServerTableMetaDataParser(SqlExecutor sqlExecutor) {
+        super(sqlExecutor, DatabaseType.sqlserver, DatabaseType.jtds_sqlserver);
+    }
+
+    @Override
+    public String getSelectTableColumnsSql() {
+        return TABLE_META_SQL;
+    }
+
+    @Override
+    public String getSelectTableMetaSql() {
+        return TABLE_COMMENT_SQL;
+    }
+
+    @Override
+    public String getSelectAllTableSql() {
+        return "select name from sysobjects where xtype='U'";
+    }
+
+}

+ 11 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/sql/SqlExecutor.java

@@ -0,0 +1,11 @@
+package org.hswebframework.web.database.manager.sql;
+
+import org.hswebframework.web.database.manager.SqlExecuteRequest;
+import org.hswebframework.web.database.manager.SqlExecuteResult;
+
+import java.util.List;
+
+public interface SqlExecutor {
+    List<SqlExecuteResult> execute(SqlExecuteRequest request)throws Exception;
+
+}

+ 41 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/main/java/org/hswebframework/web/database/manager/sql/TransactionSqlExecutor.java

@@ -0,0 +1,41 @@
+package org.hswebframework.web.database.manager.sql;
+
+import org.hswebframework.web.database.manager.SqlExecuteRequest;
+import org.hswebframework.web.database.manager.SqlExecuteResult;
+import org.hswebframework.web.datasource.DynamicDataSource;
+
+import java.util.List;
+
+public interface TransactionSqlExecutor {
+    /**
+     * 开启一个指定数据源的事务,并返回事务ID,在其他操作的时候,使用事务ID共享同一个事务
+     *
+     * @param datasourceId 数据源ID {@link DynamicDataSource#getId()}
+     * @return 事务ID
+     */
+    String newTransaction(String datasourceId);
+
+    /**
+     * 对默认数据源开启事务,并返回事务ID,在其他操作的时候,使用事务ID共享同一个事务
+     *
+     * @return 事务ID
+     */
+    String newTransaction();
+
+    /**
+     * 提交事务
+     *
+     * @param transactionId 事务ID
+     */
+    void commit(String transactionId);
+
+    /**
+     * 回滚事务
+     *
+     * @param transactionId 事务ID
+     */
+    void rollback(String transactionId);
+
+    List<SqlExecuteResult> execute(String transactionId, SqlExecuteRequest request) throws Exception;
+
+}

+ 44 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-api/src/test/src/org/hswebframework/web/database/manager/meta/table/parser/support/H2TableMetaDataParserTest.java

@@ -0,0 +1,44 @@
+package org.hswebframework.web.database.manager.meta.table.parser.support;
+
+import org.hswebframework.ezorm.rdb.executor.AbstractJdbcSqlExecutor;
+import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
+import org.hswebframework.web.database.manager.meta.table.TableMetadata;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+public class H2TableMetaDataParserTest {
+    H2TableMetaDataParser parser;
+
+    @Before
+    public void init() throws Exception {
+        Class.forName("org.h2.Driver");
+        Connection connection = DriverManager.getConnection("jdbc:h2:mem:/test;", "sa", "");
+        SqlExecutor sqlExecutor = new AbstractJdbcSqlExecutor() {
+            @Override
+            public Connection getConnection() {
+                return connection;
+            }
+
+            @Override
+            public void releaseConnection(Connection connection) throws SQLException {
+                //connection.close();
+            }
+        };
+        sqlExecutor.exec("create table test(id varchar(32) not null,name varchar(128) ,age number(32))");
+        parser = new H2TableMetaDataParser(sqlExecutor);
+    }
+
+    @Test
+    public void testParse() throws SQLException {
+        TableMetadata metaData = parser.parse("test");
+
+        Assert.assertNotNull(metaData);
+        Assert.assertNotNull(metaData.getColumns());
+
+    }
+}

+ 93 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/main/java/org/hswebframework/web/datasource/manager/simple/DatabaseManagerAutoConfiguration.java

@@ -0,0 +1,93 @@
+package org.hswebframework.web.datasource.manager.simple;
+
+import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
+import org.hswebframework.ezorm.rdb.meta.parser.OracleTableMetaParser;
+import org.hswebframework.web.database.manager.DatabaseManagerService;
+import org.hswebframework.web.database.manager.meta.ObjectMetadata;
+import org.hswebframework.web.database.manager.meta.table.parser.MetaDataParserRegister;
+import org.hswebframework.web.database.manager.meta.table.parser.MetaDataParserSupplier;
+import org.hswebframework.web.database.manager.meta.table.parser.TableMetaDataParser;
+import org.hswebframework.web.database.manager.meta.table.parser.support.H2TableMetaDataParser;
+import org.hswebframework.web.database.manager.meta.table.parser.support.MysqlTableMetaDataParser;
+import org.hswebframework.web.database.manager.meta.table.parser.support.SqlServerTableMetaDataParser;
+import org.hswebframework.web.datasource.DatabaseType;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConditionalOnMissingBean(DatabaseManagerService.class)
+public class DatabaseManagerAutoConfiguration {
+
+    @Bean
+    public DatabaseManagerService databaseManagerService() {
+        return new SimpleDatabaseManagerService();
+    }
+
+    @Configuration
+    public static class TableMetaDataParserAutoConfiguration {
+
+        @Autowired
+        private SqlExecutor sqlExecutor;
+
+        @Autowired
+        private MetaDataParserRegister metaDataParserRegister;
+
+        @Bean
+        @ConditionalOnClass(name = "org.h2.Driver")
+        public H2TableMetaDataParser h2TableMetaDataParser() {
+            return new H2TableMetaDataParser(sqlExecutor);
+        }
+
+        @Bean
+        @ConditionalOnClass(name = "com.mysql.jdbc.Driver")
+        public MysqlTableMetaDataParser mysqlTableMetaDataParser() {
+            return new MysqlTableMetaDataParser(sqlExecutor);
+        }
+
+        @Bean
+        @ConditionalOnClass(name = "oracle.jdbc.driver.OracleDriver")
+        public OracleTableMetaParser oracleTableMetaParser() {
+            return new OracleTableMetaParser(sqlExecutor);
+        }
+
+        @Bean
+        @ConditionalOnClass(name ="com.microsoft.sqlserver.jdbc.SQLServerDriver")
+        public SqlServerTableMetaDataParser sqlServerTableMetaDataParser(){
+            return new SqlServerTableMetaDataParser(sqlExecutor);
+        }
+        @Bean
+        @ConditionalOnClass(name ="net.sourceforge.jtds.jdbc.Driver")
+        public SqlServerTableMetaDataParser jstdSqlServerTableMetaDataParser(){
+            return new SqlServerTableMetaDataParser(sqlExecutor);
+        }
+
+        @Bean
+        public BeanPostProcessor tableMetaDataAutoParserRegister() {
+            return new BeanPostProcessor() {
+                @Override
+                public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
+                    return o;
+                }
+
+                @Override
+                @SuppressWarnings("unchecked")
+                public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
+                    if (o instanceof MetaDataParserSupplier) {
+                        MetaDataParserSupplier<? extends TableMetaDataParser> supplier = ((MetaDataParserSupplier) o);
+                        for (DatabaseType databaseType : DatabaseType.values()) {
+                            if (supplier.isSupport(databaseType)) {
+                                metaDataParserRegister.registerMetaDataParser(databaseType, ObjectMetadata.ObjectType.TABLE, supplier.get());
+                            }
+                        }
+                    }
+                    return o;
+                }
+            };
+        }
+    }
+}

+ 15 - 46
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/main/java/org/hswebframework/web/datasource/manager/simple/DefaultLocalTransactionExecutor.java

@@ -4,14 +4,13 @@ import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
 import org.hswebframework.web.database.manager.SqlExecuteRequest;
 import org.hswebframework.web.database.manager.SqlExecuteResult;
 import org.hswebframework.web.database.manager.SqlInfo;
+import org.hswebframework.web.database.manager.exception.SqlExecuteException;
 import org.hswebframework.web.datasource.DataSourceHolder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.transaction.TransactionStatus;
 import org.springframework.transaction.support.TransactionTemplate;
 
-import java.lang.ref.Reference;
-import java.lang.ref.SoftReference;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.LinkedList;
@@ -109,28 +108,7 @@ public class DefaultLocalTransactionExecutor implements TransactionExecutor {
     }
 
     protected void buildDefaultSqlRequestExecutor() {
-        sqlRequestExecutor = (executor, sqlInfo) -> {
-            SqlExecuteResult result = new SqlExecuteResult();
-            Object executeResult = null;
-
-            switch (sqlInfo.getType().toUpperCase()) {
-                case "SELECT":
-                    executeResult = executor.list(sqlInfo.getSql());
-                    break;
-                case "INSERT":
-                case "UPDATE":
-                    executeResult = executor.update(sqlInfo.getSql());
-                    break;
-                case "DELETE":
-                    executeResult = executor.delete(sqlInfo.getSql());
-                    break;
-                default:
-                    executor.exec(sqlInfo.getSql());
-            }
-            result.setResult(executeResult);
-            result.setSqlInfo(sqlInfo);
-            return result;
-        };
+        sqlRequestExecutor = (executor, sqlInfo) -> new NonTransactionSqlExecutor(executor).doExecute(sqlInfo);
     }
 
     @Override
@@ -184,7 +162,7 @@ public class DefaultLocalTransactionExecutor implements TransactionExecutor {
                                 //执行sql
                                 return sqlRequestExecutor.apply(sqlExecutor, sqlInfo);
                             } catch (SQLException e) {
-                                throw new RuntimeException(e);
+                                throw new SqlExecuteException(e.getMessage(), e, sqlInfo.getSql());
                             }
                         })
                         .collect(Collectors.toList());
@@ -199,7 +177,7 @@ public class DefaultLocalTransactionExecutor implements TransactionExecutor {
     }
 
     @Override
-    public List<SqlExecuteResult> execute(SqlExecuteRequest request) {
+    public List<SqlExecuteResult> execute(SqlExecuteRequest request) throws Exception {
         if (shutdown) {
             throw new UnsupportedOperationException("transaction is close");
         }
@@ -209,7 +187,6 @@ public class DefaultLocalTransactionExecutor implements TransactionExecutor {
 
         //异常信息
         Exception[] exceptions = new Exception[1];
-
         Execution execution = new Execution();
         execution.request = request;
         execution.callback = sqlExecuteResults -> {
@@ -217,30 +194,22 @@ public class DefaultLocalTransactionExecutor implements TransactionExecutor {
             sqlExecuteResults.clear();
             countDownLatch.countDown();
         };
-        execution.onError = e -> {
+        execution.onError = (e) -> {
             exceptions[0] = e;
             countDownLatch.countDown();
         };
         logger.debug("submit sql execute job {}", transactionId);
         executionQueue.add(execution);
-        try {
-            //当前没有在执行sql,说明现在正在等待新的sql进入,唤醒之
-            if (!running) {
-                waitToReady.await();
-            }
-            //等待sql执行完毕
-            countDownLatch.await();
-            //判断是否有异常
-            Exception exception;
-            if ((exception = exceptions[0]) != null) {
-                if (exception instanceof RuntimeException) {
-                    throw (RuntimeException) exception;
-                } else {
-                    throw new RuntimeException(exception);
-                }
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
+        //当前没有在执行sql,说明现在正在等待新的sql进入,唤醒之
+        if (!running) {
+            waitToReady.await();
+        }
+        //等待sql执行完毕
+        countDownLatch.await();
+        //判断是否有异常
+        Exception exception;
+        if ((exception = exceptions[0]) != null) {
+            throw exception;
         }
         return results;
     }

+ 52 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/main/java/org/hswebframework/web/datasource/manager/simple/NonTransactionSqlExecutor.java

@@ -0,0 +1,52 @@
+package org.hswebframework.web.datasource.manager.simple;
+
+import org.hswebframework.web.database.manager.SqlExecuteRequest;
+import org.hswebframework.web.database.manager.SqlExecuteResult;
+import org.hswebframework.web.database.manager.SqlInfo;
+import org.hswebframework.web.database.manager.exception.SqlExecuteException;
+import org.hswebframework.web.database.manager.sql.SqlExecutor;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class NonTransactionSqlExecutor implements SqlExecutor {
+    private org.hswebframework.ezorm.rdb.executor.SqlExecutor executor;
+
+
+    public NonTransactionSqlExecutor(org.hswebframework.ezorm.rdb.executor.SqlExecutor executor) {
+        this.executor = executor;
+    }
+
+    @Override
+    public List<SqlExecuteResult> execute(SqlExecuteRequest request)throws Exception {
+        return request.getSql().stream().map(this::doExecute).collect(Collectors.toList());
+    }
+
+    public SqlExecuteResult doExecute(SqlInfo sqlInfo)   {
+        SqlExecuteResult result = new SqlExecuteResult();
+        Object executeResult = null;
+        try {
+            switch (sqlInfo.getType().toUpperCase()) {
+                case "SELECT":
+                    executeResult = executor.list(sqlInfo.getSql());
+                    break;
+                case "INSERT":
+                case "UPDATE":
+                    executeResult = executor.update(sqlInfo.getSql());
+                    break;
+                case "DELETE":
+                    executeResult = executor.delete(sqlInfo.getSql());
+                    break;
+                default:
+                    executor.exec(sqlInfo.getSql());
+            }
+        }catch (SQLException e){
+            throw new SqlExecuteException(e.getMessage(),e,sqlInfo.getSql());
+        }
+        result.setResult(executeResult);
+        result.setSqlInfo(sqlInfo);
+
+        return result;
+    }
+}

+ 38 - 11
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/main/java/org/hswebframework/web/datasource/manager/simple/SimpleDatabaseManagerService.java

@@ -1,29 +1,32 @@
 package org.hswebframework.web.datasource.manager.simple;
 
+import lombok.extern.slf4j.Slf4j;
 import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
 import org.hswebframework.web.database.manager.DatabaseManagerService;
 import org.hswebframework.web.database.manager.SqlExecuteRequest;
 import org.hswebframework.web.database.manager.SqlExecuteResult;
 import org.hswebframework.web.database.manager.meta.ObjectMetadata;
+import org.hswebframework.web.database.manager.meta.table.parser.MetaDataParser;
+import org.hswebframework.web.database.manager.meta.table.parser.MetaDataParserRegister;
+import org.hswebframework.web.datasource.DataSourceHolder;
+import org.hswebframework.web.datasource.DatabaseType;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
 import org.springframework.transaction.support.TransactionTemplate;
 
 import javax.annotation.PostConstruct;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
+import java.sql.SQLException;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
 
 /**
- * TODO 完成注释
  *
  * @author zhouhao
  */
-@Service
-public class SimpleDatabaseManagerService implements DatabaseManagerService {
+@Slf4j
+public class SimpleDatabaseManagerService implements DatabaseManagerService,MetaDataParserRegister {
 
     private Map<String, TransactionExecutor> transactionExecutorMap = new ConcurrentHashMap<>();
 
@@ -33,10 +36,13 @@ public class SimpleDatabaseManagerService implements DatabaseManagerService {
 
     private TransactionTemplate transactionTemplate;
 
+    private Map<DatabaseType,Map<ObjectMetadata.ObjectType,MetaDataParser<? extends ObjectMetadata>>> parserRepo=new HashMap<>();
+
+
     @PostConstruct
     public void init() {
         if (executorService == null) {
-            executorService = Executors.newFixedThreadPool(20);
+            executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*2);
         }
     }
 
@@ -88,7 +94,7 @@ public class SimpleDatabaseManagerService implements DatabaseManagerService {
     }
 
     @Override
-    public List<SqlExecuteResult> execute(String transactionId, SqlExecuteRequest request) {
+    public List<SqlExecuteResult> execute(String transactionId, SqlExecuteRequest request) throws Exception {
         TransactionExecutor executor = transactionExecutorMap.get(transactionId);
         if (executor != null) {
             return executor.execute(request);
@@ -97,8 +103,29 @@ public class SimpleDatabaseManagerService implements DatabaseManagerService {
     }
 
     @Override
-    public Map<ObjectMetadata.ObjectType, List<ObjectMetadata>> getMetas(String datasourceId) {
+    public List<SqlExecuteResult> execute(SqlExecuteRequest request) throws Exception {
+        return new NonTransactionSqlExecutor(sqlExecutor).execute(request);
+    }
 
-        return null;
+    @Override
+    public Map<ObjectMetadata.ObjectType, List<? extends ObjectMetadata>> getMetas(String datasourceId) {
+        return parserRepo
+                .computeIfAbsent(DataSourceHolder.dataSource(datasourceId).getType(),t->new HashMap<>())
+                .entrySet()
+                .parallelStream()
+                .collect(Collectors.toMap(Map.Entry::getKey, entry->{
+                    try {
+                        return entry.getValue().parseAll();
+                    } catch (SQLException e) {
+                        log.error("parse meta {} error",entry.getKey(),e);
+                        return new ArrayList<>();
+                    }
+                }));
+    }
+
+    @Override
+    public <M extends ObjectMetadata> void registerMetaDataParser(DatabaseType databaseType, ObjectMetadata.ObjectType objectType, MetaDataParser<M> parser) {
+        parserRepo.computeIfAbsent(databaseType,t->new HashMap<>())
+                .put(objectType,parser);
     }
 }

+ 1 - 1
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/main/java/org/hswebframework/web/datasource/manager/simple/TransactionExecutor.java

@@ -17,6 +17,6 @@ public interface TransactionExecutor extends Runnable {
 
     void rollback();
 
-    List<SqlExecuteResult> execute(SqlExecuteRequest request);
+    List<SqlExecuteResult> execute(SqlExecuteRequest request)throws Exception;
 
 }

+ 3 - 0
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/main/resources/META-INF/spring.factories

@@ -0,0 +1,3 @@
+# Auto Configure
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.hswebframework.web.datasource.manager.simple.DatabaseManagerAutoConfiguration

+ 6 - 2
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-simple/src/test/java/org/hswebframework/web/datasource/manager/simple/SimpleDatabaseManagerServiceTest.java

@@ -27,7 +27,7 @@ public class SimpleDatabaseManagerServiceTest extends SimpleWebApplicationTests
     private DatabaseManagerService databaseManagerService;
 
     @Test
-    public void testExecuteSql() throws InterruptedException, SQLException {
+    public void testExecuteSql() throws Exception {
         String id = databaseManagerService.newTransaction();
         SqlExecuteRequest request = new SqlExecuteRequest();
         SqlInfo sqlInfo = new SqlInfo();
@@ -47,7 +47,11 @@ public class SimpleDatabaseManagerServiceTest extends SimpleWebApplicationTests
 
         for (int i = 0; i < total; i++) {
             new Thread(() -> {
-                databaseManagerService.execute(id, request);
+                try {
+                    databaseManagerService.execute(id, request);
+                } catch (Exception e) {
+                    throw new RuntimeException();
+                }
                 countDownLatch.countDown();
             }).start();
         }