Browse Source

增加对pgsql的支持,beta

zhouhao 6 years ago
parent
commit
06ad15be4e

+ 0 - 23
FEATURES.md

@@ -1,23 +0,0 @@
-# hsweb3.0
-hsweb3.0 是模块化的,每个功能可独立使用,可选择自己需要的功能依赖即可. 
-将来还将支持使用类似dubbo,spring-cloud的服务进行分布式管理.将不同的模块分布式运行.
-全部api都通过restful+json提供,前后分离. 目前暂未提供前端实现.
-
-## 核心功能
-+ [x] 权限管理.支持基于角色的权限控制,支持行,列的数据级权限控制,可自由拓展控制方式. 
-+ [x] 动态数据源.支持多数据源管理,灵活的切换方式,支持事务中切换数据源.
-+ [x] 并发场景工具.分布式锁,计数器等实用功能
-+ [x] 消息(mq)工具. 简单的消息封装,收发消息更方便.
-+ [x] websocket.配合消息工具实现前端消息推送.
-+ [x] OAuth2.0 服务和客户端,支持使用OAuth2.0进行单点登录
-+ [x] 数据字典功能,支持自定义字典解析器,满足特定字典格式需求.
-+ [x] 菜单管理.支持菜单分组,灵活配置菜单结构.
-+ [x] 动态脚本.在线编写脚本任务,维护系统更灵活.
-+ [x] 动态表单.在线设计表单(需前端支持),提供统一CRUD接口,随建随用.
-+ [ ] 工作流引擎.配合动态表单,实现工作流灵活自定义.
-+ [x] ***组织架构.采用[地区-组织-部门-职位-人员]方式,支持灵活的数据权限控制.***
-+ [x] 定时调度.在线配置任务,使用动态脚本编写任务内容,维护更方便.
-+ [x] 文件管理. 文件上传下载统一接口,支持文件秒传.
-+ [x] 访问日志. 记录用户每次访问信息.
-+ [x] 在线数据库管理. 在线维护数据库,执行sql等操作.
-+ [x] 代码生成器.可自定义模板,各种项目结构随心所欲.

+ 42 - 30
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/EasyOrmSqlBuilder.java

@@ -33,10 +33,7 @@ import org.hswebframework.ezorm.rdb.meta.converter.NumberValueConverter;
 import org.hswebframework.ezorm.rdb.render.Sql;
 import org.hswebframework.ezorm.rdb.render.SqlAppender;
 import org.hswebframework.ezorm.rdb.render.SqlRender;
-import org.hswebframework.ezorm.rdb.render.dialect.Dialect;
-import org.hswebframework.ezorm.rdb.render.dialect.H2RDBDatabaseMetaData;
-import org.hswebframework.ezorm.rdb.render.dialect.MysqlRDBDatabaseMetaData;
-import org.hswebframework.ezorm.rdb.render.dialect.OracleRDBDatabaseMetaData;
+import org.hswebframework.ezorm.rdb.render.dialect.*;
 import org.hswebframework.ezorm.rdb.render.support.simple.CommonSqlRender;
 import org.hswebframework.ezorm.rdb.render.support.simple.SimpleWhereSqlBuilder;
 import org.hswebframework.web.BusinessException;
@@ -108,32 +105,30 @@ public class EasyOrmSqlBuilder {
         return javaType;
     }
 
-    private final RDBDatabaseMetaData mysql  = new MysqlMeta();
-    private final RDBDatabaseMetaData oracle = new OracleMeta();
-    private final RDBDatabaseMetaData h2     = new H2Meta();
-
-    private final ConcurrentMap<RDBDatabaseMetaData, Map<String, RDBTableMetaData>> metaCache = new ConcurrentHashMap<RDBDatabaseMetaData, Map<String, RDBTableMetaData>>() {
-        @Override
-        public Map<String, RDBTableMetaData> get(Object key) {
-            Map<String, RDBTableMetaData> map = super.get(key);
-            if (map == null) {
-                map = new ConcurrentHashMap<>();
-                put((RDBDatabaseMetaData) key, map);
-            }
-            return map;
-        }
-    };
+    private final RDBDatabaseMetaData mysql      = new MysqlMeta();
+    private final RDBDatabaseMetaData oracle     = new OracleMeta();
+    private final RDBDatabaseMetaData h2         = new H2Meta();
+    private final RDBDatabaseMetaData postgresql = new PGMeta();
+    private final RDBDatabaseMetaData mssql      = new MSSQLMeta();
+
+    private final ConcurrentMap<RDBDatabaseMetaData, Map<String, RDBTableMetaData>> metaCache = new ConcurrentHashMap<>();
 
     public RDBDatabaseMetaData getActiveDatabase() {
         DatabaseType type = DataSourceHolder.currentDatabaseType();
         switch (type) {
-            case h2:
-                return h2;
             case mysql:
                 return mysql;
             case oracle:
                 return oracle;
+            case postgresql:
+                return postgresql;
+            case h2:
+                return h2;
+            case jtds_sqlserver:
+            case sqlserver:
+                return mssql;
             default:
+                log.warn("不支持的数据库类型:[{}]", type);
                 return h2;
         }
     }
@@ -153,7 +148,8 @@ public class EasyOrmSqlBuilder {
         tableName = getRealTableName(tableName);
         RDBDatabaseMetaData active = getActiveDatabase();
         String cacheKey = tableName.concat("-").concat(resultMapId);
-        Map<String, RDBTableMetaData> cache = metaCache.get(active);
+        Map<String, RDBTableMetaData> cache = metaCache.computeIfAbsent(active, k -> new ConcurrentHashMap<>());
+
         RDBTableMetaData cached = cache.get(cacheKey);
         if (cached != null) {
             return cached;
@@ -165,7 +161,7 @@ public class EasyOrmSqlBuilder {
 
         List<ResultMapping> resultMappings = new ArrayList<>(resultMaps.getResultMappings());
         resultMappings.addAll(resultMaps.getIdResultMappings());
-        resultMappings.forEach(resultMapping -> {
+        for (ResultMapping resultMapping : resultMappings) {
             if (resultMapping.getNestedQueryId() == null) {
                 RDBColumnMetaData column = new RDBColumnMetaData();
                 column.setJdbcType(JDBCType.valueOf(resultMapping.getJdbcType().name()));
@@ -192,8 +188,8 @@ public class EasyOrmSqlBuilder {
                 }
                 rdbTableMetaData.addColumn(column);
             }
-        });
-        cache.put(cacheKey, rdbTableMetaData);
+        }
+
         if (useJpa) {
             Class type = entityFactory == null ? resultMaps.getType() : entityFactory.getInstanceType(resultMaps.getType());
             RDBTableMetaData parseResult = JpaAnnotationParser.parseMetaDataFromEntity(type);
@@ -207,6 +203,7 @@ public class EasyOrmSqlBuilder {
                 }
             }
         }
+        cache.put(cacheKey, rdbTableMetaData);
         return rdbTableMetaData;
     }
 
@@ -274,8 +271,7 @@ public class EasyOrmSqlBuilder {
         }
         RDBTableMetaData tableMetaData = createMeta(tableName, resultMapId);
         SqlRender<InsertParam> render = tableMetaData.getDatabaseMetaData().getRenderer(SqlRender.TYPE.INSERT);
-        String sql = render.render(tableMetaData, insertParam).getSql();
-        return sql;
+        return render.render(tableMetaData, insertParam).getSql();
     }
 
     public String buildUpdateSql(String resultMapId, String tableName, UpdateParam param) {
@@ -405,7 +401,7 @@ public class EasyOrmSqlBuilder {
     }
 
     class MysqlMeta extends MysqlRDBDatabaseMetaData {
-        public MysqlMeta() {
+        MysqlMeta() {
             super();
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
             renderMap.put(SqlRender.TYPE.UPDATE, new UpdateSqlBuilder(Dialect.MYSQL));
@@ -413,7 +409,7 @@ public class EasyOrmSqlBuilder {
     }
 
     class OracleMeta extends OracleRDBDatabaseMetaData {
-        public OracleMeta() {
+        OracleMeta() {
             super();
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
             renderMap.put(SqlRender.TYPE.UPDATE, new UpdateSqlBuilder(Dialect.ORACLE));
@@ -421,10 +417,26 @@ public class EasyOrmSqlBuilder {
     }
 
     class H2Meta extends H2RDBDatabaseMetaData {
-        public H2Meta() {
+        H2Meta() {
             super();
             renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
             renderMap.put(SqlRender.TYPE.UPDATE, new UpdateSqlBuilder(Dialect.H2));
         }
     }
+
+    class PGMeta extends PGRDBDatabaseMetaData {
+        PGMeta() {
+            super();
+            renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
+            renderMap.put(SqlRender.TYPE.UPDATE, new UpdateSqlBuilder(Dialect.POSTGRES));
+        }
+    }
+
+    class MSSQLMeta extends MSSQLRDBDatabaseMetaData {
+        MSSQLMeta() {
+            super();
+            renderMap.put(SqlRender.TYPE.INSERT, new InsertSqlBuilder());
+            renderMap.put(SqlRender.TYPE.UPDATE, new UpdateSqlBuilder(Dialect.MSSQL));
+        }
+    }
 }

+ 4 - 1
hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/DatabaseType.java

@@ -32,7 +32,10 @@ public enum DatabaseType {
     h2("org.h2.Driver", "org.h2.jdbcx.JdbcDataSource", "select 1", createUrlPredicate("h2")),
     oracle("oracle.jdbc.driver.OracleDriver", "oracle.jdbc.xa.client.OracleXADataSource", "select 1 from dual", createUrlPredicate("oracle")),
     jtds_sqlserver("net.sourceforge.jtds.jdbc.Driver", "net.sourceforge.jtds.jdbcx.JtdsDataSource", "select 1 t", createUrlPredicate("jtds:sqlserver")),
-    sqlserver("com.microsoft.sqlserver.jdbc.SQLServerDriver", "com.microsoft.sqlserver.jdbc.SQLServerXADataSource", "select 1 t", createUrlPredicate("sqlserver"));
+    sqlserver("com.microsoft.sqlserver.jdbc.SQLServerDriver", "com.microsoft.sqlserver.jdbc.SQLServerXADataSource", "select 1 t", createUrlPredicate("sqlserver")),
+    //beta
+    postgresql("org.postgresql.Driver", "org.postgresql.xa.PGXADataSource", "select 1 ", createUrlPredicate("postgresql"));
+
 
     static Predicate<String> createUrlPredicate(String name) {
         return url -> {

+ 11 - 6
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/SystemInitializeAutoConfiguration.java

@@ -21,12 +21,8 @@ package org.hswebframework.web.starter;
 import lombok.extern.slf4j.Slf4j;
 import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
 import org.hswebframework.ezorm.rdb.meta.RDBDatabaseMetaData;
-import org.hswebframework.ezorm.rdb.meta.parser.H2TableMetaParser;
-import org.hswebframework.ezorm.rdb.meta.parser.MysqlTableMetaParser;
-import org.hswebframework.ezorm.rdb.meta.parser.OracleTableMetaParser;
-import org.hswebframework.ezorm.rdb.render.dialect.H2RDBDatabaseMetaData;
-import org.hswebframework.ezorm.rdb.render.dialect.MysqlRDBDatabaseMetaData;
-import org.hswebframework.ezorm.rdb.render.dialect.OracleRDBDatabaseMetaData;
+import org.hswebframework.ezorm.rdb.meta.parser.*;
+import org.hswebframework.ezorm.rdb.render.dialect.*;
 import org.hswebframework.ezorm.rdb.simple.SimpleDatabase;
 import org.hswebframework.expands.script.engine.DynamicScriptEngine;
 import org.hswebframework.expands.script.engine.DynamicScriptEngineFactory;
@@ -135,6 +131,15 @@ public class SystemInitializeAutoConfiguration implements CommandLineRunner, Bea
                 metaData = new OracleRDBDatabaseMetaData();
                 metaData.setParser(new OracleTableMetaParser(sqlExecutor));
                 break;
+            case postgresql:
+                metaData = new PGRDBDatabaseMetaData();
+                metaData.setParser(new PGSqlTableMetaParser(sqlExecutor));
+                break;
+            case sqlserver:
+            case jtds_sqlserver:
+                metaData = new MSSQLRDBDatabaseMetaData();
+                metaData.setParser(new SqlServer2012TableMetaParser(sqlExecutor));
+                break;
             case mysql:
                 String engine = environment.getProperty("mysql.engine");
                 if (StringUtils.hasText(engine)) {

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

@@ -0,0 +1,48 @@
+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 PostgresTableMetaDataParser extends AbstractSqlTableMetaDataParser {
+    private static final String TABLE_META_SQL = "select column_name as \"name\"" +
+            " , udt_name as \"dataType\"" +
+            " , table_name as \"tableName\"" +
+            " , character_maximum_length as \"dataLength\"" +
+            " , numeric_precision as \"precision\"" +
+            " , numeric_scale as \"scale\"" +
+            " , case when is_nullable = 'YES' then 0 else 1 end as \"notNull\"" +
+            " ,col_description(a.attrelid,a.attnum) as \"comment\"" +
+            " from information_schema.columns columns ," +
+            "     pg_class as c,pg_attribute as a" +
+            " where a.attrelid = c.oid and a.attnum>0 and a.attname = columns.column_name and c.relname=columns.table_name" +
+            " and table_schema = current_schema()" +
+            "  and table_name = #{table}";
+
+    private static final String TABLE_COMMENT_SQL = "select cast(obj_description(relfilenode,'pg_class') as varchar)" +
+            "  as \"comment\" from pg_class c" +
+            " where relname=#{table} and relkind = 'r' and relname not like 'pg_%'" +
+            " and relname not like 'sql_%'";
+
+    private static final String ALL_TABLE_SQL = "select table_name as \"name\" from information_schema.TABLES where table_schema=current_schema()";
+
+    public PostgresTableMetaDataParser(SqlExecutor sqlExecutor) {
+        super(sqlExecutor, DatabaseType.postgresql);
+    }
+
+    @Override
+    public String getSelectTableColumnsSql() {
+        return TABLE_META_SQL;
+    }
+
+    @Override
+    public String getSelectTableMetaSql() {
+        return TABLE_COMMENT_SQL;
+    }
+
+    @Override
+    public String getSelectAllTableSql() {
+        return ALL_TABLE_SQL;
+    }
+
+}

+ 7 - 4
hsweb-system/hsweb-system-database-manager/hsweb-system-database-manager-starter/src/main/java/org/hswebframework/web/database/manager/TableMetaDataParserAutoConfiguration.java

@@ -5,10 +5,7 @@ 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.OracleTableMetaDataParser;
-import org.hswebframework.web.database.manager.meta.table.parser.support.SqlServerTableMetaDataParser;
+import org.hswebframework.web.database.manager.meta.table.parser.support.*;
 import org.hswebframework.web.datasource.DatabaseType;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -43,6 +40,12 @@ public class TableMetaDataParserAutoConfiguration {
     public OracleTableMetaDataParser oracleTableMetaParser() {
         return new OracleTableMetaDataParser(sqlExecutor);
     }
+    @Bean
+    @ConditionalOnClass(name = "org.postgresql.Driver")
+    public PostgresTableMetaDataParser postgresTableMetaDataParser() {
+        return new PostgresTableMetaDataParser(sqlExecutor);
+    }
+
 
     @Bean
     @ConditionalOnClass(name = "com.microsoft.sqlserver.jdbc.SQLServerDriver")

+ 8 - 4
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-local/src/main/java/org/hswebframework/web/service/form/simple/SimpleDatabaseRepository.java

@@ -2,10 +2,7 @@ package org.hswebframework.web.service.form.simple;
 
 import org.hswebframework.ezorm.rdb.RDBDatabase;
 import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
-import org.hswebframework.ezorm.rdb.meta.parser.H2TableMetaParser;
-import org.hswebframework.ezorm.rdb.meta.parser.MysqlTableMetaParser;
-import org.hswebframework.ezorm.rdb.meta.parser.OracleTableMetaParser;
-import org.hswebframework.ezorm.rdb.meta.parser.SqlServer2012TableMetaParser;
+import org.hswebframework.ezorm.rdb.meta.parser.*;
 import org.hswebframework.ezorm.rdb.render.dialect.*;
 import org.hswebframework.ezorm.rdb.simple.SimpleDatabase;
 import org.hswebframework.web.datasource.DataSourceHolder;
@@ -74,6 +71,13 @@ public class SimpleDatabaseRepository implements DatabaseRepository {
             return metaData;
         });
         databaseMetaSuppliers.put(DatabaseType.sqlserver, databaseMetaSuppliers.get(DatabaseType.jtds_sqlserver));
+
+        databaseMetaSuppliers.put(DatabaseType.postgresql, () -> {
+            PGRDBDatabaseMetaData metaData = new PGRDBDatabaseMetaData();
+            metaData.setParser(new PGSqlTableMetaParser(sqlExecutor));
+            return metaData;
+        });
+
     }
 
     @Override