zhouhao 8 лет назад
Родитель
Сommit
13269f23ef
16 измененных файлов с 903 добавлено и 7 удалено
  1. 157 0
      hsweb-web-bean/src/main/java/org/hsweb/web/bean/po/datasource/DataSource.java
  2. 26 0
      hsweb-web-bean/src/main/resources/system/install/sql/h2/install.sql
  3. 27 2
      hsweb-web-bean/src/main/resources/system/install/sql/mysql/install.sql
  4. 26 0
      hsweb-web-bean/src/main/resources/system/install/sql/oracle/install.sql
  5. 73 0
      hsweb-web-controller/src/main/java/org/hsweb/web/controller/datasource/DataSourceController.java
  6. 52 0
      hsweb-web-dao-impl-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/mysql/datasource/DataSourceMapper.xml
  7. 52 0
      hsweb-web-dao-impl-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/oracle/datasource/DataSourceMapper.xml
  8. 28 0
      hsweb-web-dao-interface/src/main/java/org/hsweb/web/dao/datasource/DataSourceMapper.java
  9. 5 0
      hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/basic/SqlExecutorService.java
  10. 157 0
      hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/datasource/DataSourceServiceImpl.java
  11. 106 0
      hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/datasource/DynamicDataSourceServiceImpl.java
  12. 108 2
      hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/system/DataBaseManagerServiceImpl.java
  13. 1 0
      hsweb-web-service-impl-common/src/test/java/org/hsweb/web/service/impl/system/DataBaseManagerServiceImplTest.java
  14. 42 0
      hsweb-web-service-interface/src/main/java/org/hsweb/web/service/datasource/DataSourceService.java
  15. 32 0
      hsweb-web-service-interface/src/main/java/org/hsweb/web/service/datasource/DynamicDataSourceService.java
  16. 11 3
      hsweb-web-service-interface/src/main/java/org/hsweb/web/service/system/DataBaseManagerService.java

+ 157 - 0
hsweb-web-bean/src/main/java/org/hsweb/web/bean/po/datasource/DataSource.java

@@ -0,0 +1,157 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.bean.po.datasource;
+
+import org.hibernate.validator.constraints.NotBlank;
+import org.hsweb.web.bean.po.GenericPo;
+
+/**
+ * 数据源
+ * Created by hsweb-generator 2016-8-23 15:52:11
+ */
+public class DataSource extends GenericPo<String> {
+    //数据源名称
+    @NotBlank
+    private String name;
+    //驱动
+    @NotBlank
+    private String driver;
+    //url
+    @NotBlank
+    private String url;
+    //用户名
+    @NotBlank
+    private String username;
+    //测试sql
+    private String testSql;
+    //密码
+    private String password;
+    //是否启用
+    private int enabled;
+    //创建日期
+    private java.util.Date createDate;
+
+    /**
+     * 获取 数据源名称
+     *
+     * @return String 数据源名称
+     */
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * 设置 数据源名称
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 获取 用户名
+     *
+     * @return String 用户名
+     */
+    public String getUsername() {
+        return this.username;
+    }
+
+    /**
+     * 设置 用户名
+     */
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    /**
+     * 获取 密码
+     *
+     * @return String 密码
+     */
+    public String getPassword() {
+        return this.password;
+    }
+
+    /**
+     * 设置 密码
+     */
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    /**
+     * 获取 是否启用
+     *
+     * @return int 是否启用
+     */
+    public int getEnabled() {
+        return this.enabled;
+    }
+
+    /**
+     * 设置 是否启用
+     */
+    public void setEnabled(int enabled) {
+        this.enabled = enabled;
+    }
+
+    /**
+     * 获取 创建日期
+     *
+     * @return java.util.Date 创建日期
+     */
+    public java.util.Date getCreateDate() {
+        return this.createDate;
+    }
+
+    /**
+     * 设置 创建日期
+     */
+    public void setCreateDate(java.util.Date createDate) {
+        this.createDate = createDate;
+    }
+
+    public String getDriver() {
+        return driver;
+    }
+
+    public void setDriver(String driver) {
+        this.driver = driver;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getTestSql() {
+        return testSql;
+    }
+
+    public void setTestSql(String testSql) {
+        this.testSql = testSql;
+    }
+
+    public int getHash() {
+        StringBuilder builder = new StringBuilder();
+        builder.append(driver).append(url).append(username).append(password).append(enabled);
+        return builder.toString().hashCode();
+    }
+}

+ 26 - 0
hsweb-web-bean/src/main/resources/system/install/sql/h2/install.sql

@@ -262,6 +262,32 @@ COMMENT ON COLUMN "S_QUERY_PLAN"."SHARING" IS '是否共享方案';
 COMMENT ON COLUMN "S_QUERY_PLAN"."CREATOR_ID" IS '创建人ID';
 COMMENT ON COLUMN "S_QUERY_PLAN"."CREATE_DATE" IS '创建日期';
 
+CREATE TABLE S_DATA_SOURCE
+(
+  U_ID VARCHAR(32) PRIMARY KEY NOT NULL,
+  NAME VARCHAR(64) NOT NULL,
+  DRIVER VARCHAR(128) NOT NULL,
+  URL VARCHAR(512) NOT NULL,
+  USERNAME VARCHAR(128) NOT NULL,
+  PASSWORD VARCHAR(128) NOT NULL,
+  ENABLED DECIMAL(4) NOT NULL,
+  CREATE_DATE DATE NOT NULL,
+  PROPERTIES CLOB,
+  COMMENT VARCHAR(512),
+  TEST_SQL VARCHAR(512)
+);
+COMMENT ON COLUMN S_DATA_SOURCE.U_ID IS 'ID';
+COMMENT ON COLUMN S_DATA_SOURCE.NAME IS '数据源名称';
+COMMENT ON COLUMN S_DATA_SOURCE.DRIVER IS '驱动';
+COMMENT ON COLUMN S_DATA_SOURCE.URL IS 'URL';
+COMMENT ON COLUMN S_DATA_SOURCE.USERNAME IS '用户名';
+COMMENT ON COLUMN S_DATA_SOURCE.PASSWORD IS '密码';
+COMMENT ON COLUMN S_DATA_SOURCE.ENABLED IS '是否启用';
+COMMENT ON COLUMN S_DATA_SOURCE.CREATE_DATE IS '创建日期';
+COMMENT ON COLUMN S_DATA_SOURCE.PROPERTIES IS '其他配置';
+COMMENT ON COLUMN S_DATA_SOURCE.COMMENT IS '备注';
+COMMENT ON COLUMN S_DATA_SOURCE.TEST_SQL IS '测试链接时使用的sql';
+
 ALTER TABLE "S_QUERY_PLAN"
   ADD PRIMARY KEY ("U_ID");
 ALTER TABLE "S_USER_PROFILE"

+ 27 - 2
hsweb-web-bean/src/main/resources/system/install/sql/mysql/install.sql

@@ -249,8 +249,33 @@ CREATE TABLE s_query_plan
   `SHARING`     TINYINT COMMENT '是否共享',
   `CREATOR_ID`  VARCHAR(32)  NOT NULL
   COMMENT '创建人ID',
-  `CREATE_DATE` DATETIME         NOT NULL
+  `CREATE_DATE` DATETIME     NOT NULL
   COMMENT '创建日期'
 );
 ALTER TABLE `s_query_plan`
-  COMMENT '查询方案';
+  COMMENT '查询方案';
+
+CREATE TABLE s_data_source
+(
+  u_id        VARCHAR(32) PRIMARY KEY NOT NULL
+  COMMENT 'ID',
+  name        VARCHAR(64)             NOT NULL
+  COMMENT '名称',
+  driver      VARCHAR(128)            NOT NULL
+  COMMENT 'driver',
+  url         VARCHAR(512)            NOT NULL
+  COMMENT 'url',
+  username    VARCHAR(128)            NOT NULL
+  COMMENT '用户名',
+  password    VARCHAR(128)            NOT NULL
+  COMMENT '密码',
+  enabled     TINYINT                 NOT NULL
+  COMMENT '是否启用',
+  create_date DATETIME                NOT NULL
+  COMMENT '创建日期',
+  properties  TEXT COMMENT '其他配置',
+  comment     VARCHAR(512) COMMENT '备注',
+  test_sql    VARCHAR(512) COMMENT '测试sql'
+);
+ALTER TABLE s_data_source
+  COMMENT '数据源';

+ 26 - 0
hsweb-web-bean/src/main/resources/system/install/sql/oracle/install.sql

@@ -263,6 +263,32 @@ COMMENT ON COLUMN ${jdbc.username}."S_QUERY_PLAN"."SHARING" IS '是否共享方
 COMMENT ON COLUMN ${jdbc.username}."S_QUERY_PLAN"."CREATOR_ID" IS '创建人ID';
 COMMENT ON COLUMN ${jdbc.username}."S_QUERY_PLAN"."CREATE_DATE" IS '创建日期';
 
+CREATE TABLE ${jdbc.username}.S_DATA_SOURCE
+(
+  U_ID VARCHAR2(32) PRIMARY KEY NOT NULL,
+  NAME VARCHAR2(64) NOT NULL,
+  DRIVER VARCHAR2(128) NOT NULL,
+  URL VARCHAR2(512) NOT NULL,
+  USERNAME VARCHAR2(128) NOT NULL,
+  PASSWORD VARCHAR2(128) NOT NULL,
+  ENABLED NUMBER(4) NOT NULL,
+  CREATE_DATE DATE NOT NULL,
+  PROPERTIES CLOB,
+  COMMENT VARCHAR2(512),
+  TEST_SQL VARCHAR2(512)
+);
+COMMENT ON COLUMN ${jdbc.username}.S_DATA_SOURCE.U_ID IS 'ID';
+COMMENT ON COLUMN ${jdbc.username}.S_DATA_SOURCE.NAME IS '数据源名称';
+COMMENT ON COLUMN ${jdbc.username}.S_DATA_SOURCE.DRIVER IS '驱动';
+COMMENT ON COLUMN ${jdbc.username}.S_DATA_SOURCE.URL IS 'URL';
+COMMENT ON COLUMN ${jdbc.username}.S_DATA_SOURCE.USERNAME IS '用户名';
+COMMENT ON COLUMN ${jdbc.username}.S_DATA_SOURCE.PASSWORD IS '密码';
+COMMENT ON COLUMN ${jdbc.username}.S_DATA_SOURCE.ENABLED IS '是否启用';
+COMMENT ON COLUMN ${jdbc.username}.S_DATA_SOURCE.CREATE_DATE IS '创建日期';
+COMMENT ON COLUMN ${jdbc.username}.S_DATA_SOURCE.PROPERTIES IS '其他配置';
+COMMENT ON COLUMN ${jdbc.username}.S_DATA_SOURCE.COMMENT IS '备注';
+COMMENT ON COLUMN ${jdbc.username}.S_DATA_SOURCE.TEST_SQL IS '测试链接时使用的sql';
+
 ALTER TABLE ${jdbc.username}."S_QUERY_PLAN"
   ADD PRIMARY KEY ("U_ID");
 ALTER TABLE ${jdbc.username}."S_USER_PROFILE"

+ 73 - 0
hsweb-web-controller/src/main/java/org/hsweb/web/controller/datasource/DataSourceController.java

@@ -0,0 +1,73 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.controller.datasource;
+
+import org.hsweb.web.bean.common.QueryParam;
+import org.hsweb.web.bean.po.datasource.DataSource;
+import org.hsweb.web.controller.GenericController;
+import org.hsweb.web.core.authorize.annotation.Authorize;
+import org.hsweb.web.core.logger.annotation.AccessLogger;
+import org.hsweb.web.core.message.ResponseMessage;
+import org.hsweb.web.service.datasource.DataSourceService;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * 数据源管理控制器
+ * Created by hsweb-generator
+ */
+@RestController
+@RequestMapping(value = "/datasource")
+@AccessLogger("数据源管理")
+@Authorize(module = "datasource")
+public class DataSourceController extends GenericController<DataSource, String> {
+
+    @Resource
+    private DataSourceService dataSourceService;
+
+    @Override
+    public DataSourceService getService() {
+        return this.dataSourceService;
+    }
+
+    @RequestMapping(value = "/enable/{id}", method = RequestMethod.PUT)
+    @Authorize(action = "enable")
+    @AccessLogger("启用")
+    public ResponseMessage enable(@PathVariable("id") String id) {
+        dataSourceService.enable(id);
+        return ResponseMessage.ok();
+    }
+
+    @RequestMapping(value = "/disable/{id}", method = RequestMethod.PUT)
+    @Authorize(action = "disable")
+    @AccessLogger("禁用")
+    public ResponseMessage disable(@PathVariable("id") String id) {
+        dataSourceService.disable(id);
+        return ResponseMessage.ok();
+    }
+
+    @RequestMapping(value = "/test/{id}", method = RequestMethod.GET)
+    @Authorize(action = "R")
+    @AccessLogger("测试连接")
+    public ResponseMessage testConnection(@PathVariable("id") String id) {
+        return ResponseMessage.ok(dataSourceService.testConnection(id));
+    }
+}

+ 52 - 0
hsweb-web-dao-impl-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/mysql/datasource/DataSourceMapper.xml

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.hsweb.web.dao.datasource.DataSourceMapper">
+    <resultMap id="DataSourceResultMap" type="org.hsweb.web.bean.po.datasource.DataSource">
+        <id property="id" column="u_id" javaType="string" jdbcType="VARCHAR"/>
+        <result property="name" column="name" javaType="String" jdbcType="VARCHAR"/>
+        <result property="driver" column="driver" javaType="String" jdbcType="VARCHAR"/>
+        <result property="url" column="url" javaType="String" jdbcType="VARCHAR"/>
+        <result property="username" column="username" javaType="String" jdbcType="VARCHAR"/>
+        <result property="password" column="password" javaType="String" jdbcType="VARCHAR"/>
+        <result property="testSql" column="test_sql" javaType="String" jdbcType="VARCHAR"/>
+        <result property="enabled" column="enabled" javaType="int" jdbcType="NUMERIC"/>
+        <result property="createDate" column="create_date" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
+        <result property="properties" column="properties" javaType="java.util.Map" jdbcType="CLOB"/>
+    </resultMap>
+
+    <!--用于动态生成sql所需的配置-->
+    <sql id="config">
+        <bind name="resultMapId" value="'DataSourceResultMap'"/>
+        <bind name="tableName" value="'s_data_source'"/>
+    </sql>
+    <insert id="insert" parameterType="org.hsweb.web.bean.common.InsertParam" >
+        <include refid="config"/>
+        <include refid="BasicMapper.buildInsertSql"/>
+    </insert>
+
+    <delete id="delete" parameterType="org.hsweb.web.bean.common.DeleteParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildDeleteSql"/>
+    </delete>
+
+    <update id="update" parameterType="org.hsweb.web.bean.common.UpdateParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildUpdateSql"/>
+    </update>
+
+    <select id="selectByPk" parameterType="string" resultMap="DataSourceResultMap">
+        select * from s_data_source where u_id=#{id}
+    </select>
+
+    <select id="select" parameterType="org.hsweb.web.bean.common.QueryParam" resultMap="DataSourceResultMap">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildSelectSql"/>
+    </select>
+
+    <select id="total" parameterType="org.hsweb.web.bean.common.QueryParam" resultType="int">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildTotalSql"/>
+    </select>
+</mapper>

+ 52 - 0
hsweb-web-dao-impl-mybatis/src/main/resources/org/hsweb/web/dao/impl/mybatis/mapper/oracle/datasource/DataSourceMapper.xml

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.hsweb.web.dao.datasource.DataSourceMapper">
+    <resultMap id="DataSourceResultMap" type="org.hsweb.web.bean.po.datasource.DataSource">
+        <id property="id" column="u_id" javaType="string" jdbcType="VARCHAR"/>
+        <result property="name" column="name" javaType="String" jdbcType="VARCHAR"/>
+        <result property="driver" column="driver" javaType="String" jdbcType="VARCHAR"/>
+        <result property="url" column="url" javaType="String" jdbcType="VARCHAR"/>
+        <result property="username" column="username" javaType="String" jdbcType="VARCHAR"/>
+        <result property="password" column="password" javaType="String" jdbcType="VARCHAR"/>
+        <result property="testSql" column="test_sql" javaType="String" jdbcType="VARCHAR"/>
+        <result property="enabled" column="enabled" javaType="int" jdbcType="NUMERIC"/>
+        <result property="createDate" column="create_date" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
+        <result property="properties" column="properties" javaType="java.util.Map" jdbcType="CLOB"/>
+    </resultMap>
+
+    <!--用于动态生成sql所需的配置-->
+    <sql id="config">
+        <bind name="resultMapId" value="'DataSourceResultMap'"/>
+        <bind name="tableName" value="'s_data_source'"/>
+    </sql>
+    <insert id="insert" parameterType="org.hsweb.web.bean.common.InsertParam" >
+        <include refid="config"/>
+        <include refid="BasicMapper.buildInsertSql"/>
+    </insert>
+
+    <delete id="delete" parameterType="org.hsweb.web.bean.common.DeleteParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildDeleteSql"/>
+    </delete>
+
+    <update id="update" parameterType="org.hsweb.web.bean.common.UpdateParam">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildUpdateSql"/>
+    </update>
+
+    <select id="selectByPk" parameterType="string" resultMap="DataSourceResultMap">
+        select * from s_data_source where u_id=#{id}
+    </select>
+
+    <select id="select" parameterType="org.hsweb.web.bean.common.QueryParam" resultMap="DataSourceResultMap">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildSelectSql"/>
+    </select>
+
+    <select id="total" parameterType="org.hsweb.web.bean.common.QueryParam" resultType="int">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildTotalSql"/>
+    </select>
+</mapper>

+ 28 - 0
hsweb-web-dao-interface/src/main/java/org/hsweb/web/dao/datasource/DataSourceMapper.java

@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.dao.datasource;
+
+import org.hsweb.web.dao.GenericMapper;
+import org.hsweb.web.bean.po.datasource.DataSource;
+
+/**
+* 测试数据映射接口
+* Created by generator 
+*/
+public interface DataSourceMapper extends GenericMapper<DataSource,String> {
+
+}

+ 5 - 0
hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/basic/SqlExecutorService.java

@@ -90,4 +90,9 @@ public class SqlExecutorService extends AbstractJdbcSqlExecutor implements Expre
         SimpleSQL sql1 = new SimpleSQL(sql, param);
         return sql1;
     }
+
+    public SqlExecutorService setDataSource(DataSource dataSource) {
+        this.dataSource = dataSource;
+        return this;
+    }
 }

+ 157 - 0
hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/datasource/DataSourceServiceImpl.java

@@ -0,0 +1,157 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.impl.datasource;
+
+import org.hsweb.ezorm.executor.AbstractJdbcSqlExecutor;
+import org.hsweb.ezorm.render.support.simple.SimpleSQL;
+import org.hsweb.web.bean.common.QueryParam;
+import org.hsweb.web.bean.common.UpdateMapParam;
+import org.hsweb.web.bean.common.UpdateParam;
+import org.hsweb.web.bean.po.datasource.DataSource;
+import org.hsweb.web.core.exception.BusinessException;
+import org.hsweb.web.dao.datasource.DataSourceMapper;
+import org.hsweb.web.service.config.ConfigService;
+import org.hsweb.web.service.impl.AbstractServiceImpl;
+import org.hsweb.web.service.datasource.DataSourceService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.jdbc.datasource.DataSourceUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 数据源服务类
+ * Created by generator
+ */
+@Service("dataSourceService")
+public class DataSourceServiceImpl extends AbstractServiceImpl<DataSource, String> implements DataSourceService {
+
+    private static final String CACHE_NAME = "datasource";
+
+    @Resource
+    protected DataSourceMapper dataSourceMapper;
+
+    @Resource
+    protected ConfigService configService;
+
+    @Autowired
+    protected javax.sql.DataSource defaultDataSource;
+
+    @Override
+    protected DataSourceMapper getMapper() {
+        return this.dataSourceMapper;
+    }
+
+    @Override
+    public javax.sql.DataSource createDataSource(String id) {
+        DataSource dataSource = selectByPk(id);
+        DataSourceBuilder builder = DataSourceBuilder.create()
+                .driverClassName(dataSource.getDriver())
+                .url(dataSource.getUrl())
+                .username(dataSource.getUsername())
+                .password(dataSource.getPassword())
+                .type(defaultDataSource.getClass());
+        return builder.build();
+    }
+
+    @Override
+    @Cacheable(value = CACHE_NAME, key = "'id:'+#id")
+    public DataSource selectByPk(String id) {
+        return super.selectByPk(id);
+    }
+
+    @Override
+    public String insert(DataSource data) {
+        data.setCreateDate(new Date());
+        data.setEnabled(1);
+        tryValidPo(data);
+        DataSource old = selectSingle(QueryParam.build().where("name", data.getName()));
+        if (old != null) throw new BusinessException("名称" + data.getName() + "已存在");
+        return super.insert(data);
+    }
+
+    @Override
+    @CacheEvict(allEntries = true)
+    public int update(List<DataSource> data) {
+        return super.update(data);
+    }
+
+    @Override
+    @CacheEvict(value = CACHE_NAME, key = "'id:'+#data.id")
+    public int update(DataSource data) {
+        DataSource old = selectSingle(QueryParam.build()
+                .where("name", data.getName())
+                .and("id$not", data.getId()));
+        if (old != null) throw new BusinessException("名称" + data.getName() + "已存在");
+        return getMapper().update(UpdateParam.build(data).excludes("createDate", "enabled"));
+    }
+
+    @Override
+    @CacheEvict(value = CACHE_NAME, key = "'id:'+#id")
+    public void enable(String id) {
+        getMapper().update((UpdateParam) UpdateMapParam.build().set("enabled", 1).where("id", id));
+    }
+
+    @Override
+    @CacheEvict(value = CACHE_NAME, key = "'id:'+#id")
+    public void disable(String id) {
+        getMapper().update((UpdateParam) UpdateMapParam.build().set("enabled", 0).where("id", id));
+    }
+
+
+    @Override
+    @CacheEvict(value = CACHE_NAME, key = "'id:'+#id")
+    public int delete(String id) {
+        return super.delete(id);
+    }
+
+    @Override
+    public boolean testConnection(String id) {
+        DataSource old = selectByPk(id);
+        assertNotNull(old, "数据源不存在");
+        javax.sql.DataSource dataSource = createDataSource(id);
+        AbstractJdbcSqlExecutor sqlExecutor = new AbstractJdbcSqlExecutor() {
+            @Override
+            public Connection getConnection() {
+                return DataSourceUtils.getConnection(dataSource);
+            }
+
+            @Override
+            public void releaseConnection(Connection connection) throws SQLException {
+                DataSourceUtils.releaseConnection(connection, dataSource);
+            }
+        };
+        try {
+            sqlExecutor.exec(new SimpleSQL(old.getTestSql()));
+            return true;
+        } catch (SQLException e) {
+            return false;
+        }
+    }
+}

+ 106 - 0
hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/datasource/DynamicDataSourceServiceImpl.java

@@ -0,0 +1,106 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.impl.datasource;
+
+import org.hsweb.concurrent.lock.LockFactory;
+import org.hsweb.ezorm.executor.SqlExecutor;
+import org.hsweb.web.bean.po.datasource.DataSource;
+import org.hsweb.web.core.exception.NotFoundException;
+import org.hsweb.web.service.datasource.DataSourceService;
+import org.hsweb.web.service.datasource.DynamicDataSourceService;
+import org.hsweb.web.service.impl.basic.SqlExecutorService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.ReadWriteLock;
+
+@Service("dynamicDataSourceService")
+public class DynamicDataSourceServiceImpl implements DynamicDataSourceService {
+
+    @Resource
+    private DataSourceService dataSourceService;
+
+    @Autowired
+    private LockFactory lockFactory;
+
+    private ConcurrentMap<String, CacheInfo> cache = new ConcurrentHashMap<>();
+
+    @Override
+    public javax.sql.DataSource getDataSource(String id) {
+        return getCache(id).getDataSource();
+    }
+
+    @Override
+    public SqlExecutor getSqlExecutor(String id) {
+        return getCache(id).getSqlExecutor();
+    }
+
+    protected CacheInfo getCache(String id) {
+        DataSource old = dataSourceService.selectByPk(id);
+        if (old == null || old.getEnabled() != 1) throw new NotFoundException("数据源不存在或已禁用");
+        //创建锁
+        ReadWriteLock readWriteLock = lockFactory.createReadWriteLock("datasource.lock." + id);
+        readWriteLock.readLock().tryLock();
+        try {
+            CacheInfo cacheInfo = cache.get(id);
+            // 缓存存在,并且hash一致
+            if (cacheInfo != null && cacheInfo.getHash() == old.getHash())
+                return cacheInfo;
+        } finally {
+            readWriteLock.readLock().unlock();
+        }
+        //加载datasource到缓存
+        readWriteLock.writeLock().tryLock();
+        try {
+            javax.sql.DataSource dataSource = dataSourceService.createDataSource(id);
+            CacheInfo cacheInfo = new CacheInfo(old.getHash(), dataSource);
+            cache.put(id, cacheInfo);
+            return cacheInfo;
+        } finally {
+            readWriteLock.writeLock().unlock();
+        }
+    }
+
+    class CacheInfo {
+        int hash;
+
+        javax.sql.DataSource dataSource;
+
+        SqlExecutor sqlExecutor;
+
+        public CacheInfo(int hash, javax.sql.DataSource dataSource) {
+            this.hash = hash;
+            this.dataSource = dataSource;
+            sqlExecutor = new SqlExecutorService().setDataSource(dataSource);
+        }
+
+        public int getHash() {
+            return hash;
+        }
+
+        public javax.sql.DataSource getDataSource() {
+            return dataSource;
+        }
+
+        public SqlExecutor getSqlExecutor() {
+            return sqlExecutor;
+        }
+    }
+}

+ 108 - 2
hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/system/DataBaseManagerServiceImpl.java

@@ -6,6 +6,7 @@ import org.hsweb.ezorm.executor.SqlExecutor;
 import org.hsweb.ezorm.meta.DatabaseMetaData;
 import org.hsweb.ezorm.meta.TableMetaData;
 import org.hsweb.ezorm.meta.expand.SimpleMapWrapper;
+import org.hsweb.ezorm.meta.parser.H2TableMetaParser;
 import org.hsweb.ezorm.meta.parser.MysqlTableMetaParser;
 import org.hsweb.ezorm.meta.parser.OracleTableMetaParser;
 import org.hsweb.ezorm.meta.parser.TableMetaParser;
@@ -17,6 +18,9 @@ import org.hsweb.ezorm.render.support.simple.SimpleSQL;
 import org.hsweb.ezorm.run.simple.SimpleDatabase;
 import org.hsweb.web.core.Install;
 import org.hsweb.web.core.exception.BusinessException;
+import org.hsweb.web.core.exception.NotFoundException;
+import org.hsweb.web.service.datasource.DataSourceService;
+import org.hsweb.web.service.datasource.DynamicDataSourceService;
 import org.hsweb.web.service.impl.DatabaseMetaDataFactoryBean;
 import org.hsweb.web.service.system.DataBaseManagerService;
 import org.hsweb.web.service.system.SqlExecuteProcess;
@@ -26,6 +30,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
+import javax.sql.DataSource;
 import java.sql.SQLException;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
@@ -52,6 +57,12 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService {
     @Autowired
     private DatabaseMetaDataFactoryBean databaseMetaDataFactoryBean;
 
+    @Resource
+    private DynamicDataSourceService dynamicDataSourceService;
+
+    @Resource
+    private DataSourceService dataSourceService;
+
     @Override
     public List<TableMetaData> getTableList() throws SQLException {
         if (tableMetaParser == null) {
@@ -63,6 +74,10 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService {
     @Override
     @Transactional(rollbackFor = Throwable.class)
     public List<Map<String, Object>> execSql(List<String> sqlList) throws SQLException {
+        return execSql(sqlExecutor, sqlList);
+    }
+
+    public List<Map<String, Object>> execSql(SqlExecutor sqlExecutor, List<String> sqlList) throws SQLException {
         List<Map<String, Object>> response = new LinkedList<>();
         for (String s : sqlList) {
             Map<String, Object> msg = new LinkedHashMap<>();
@@ -100,7 +115,10 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService {
 
     @Override
     public String createAlterSql(TableMetaData newTable) throws Exception {
-        DatabaseMetaData databaseMetaData = databaseMetaDataFactoryBean.getObject();
+        return createAlterSql(databaseMetaDataFactoryBean.getObject(), tableMetaParser, newTable);
+    }
+
+    public String createAlterSql(DatabaseMetaData databaseMetaData, TableMetaParser tableMetaParser, TableMetaData newTable) throws Exception {
         databaseMetaData.putTable(tableMetaParser.parse(newTable.getName()));
         SQL sql = databaseMetaData.getRenderer(SqlRender.TYPE.META_ALTER).render(newTable, true);
         if (sql instanceof EmptySQL) return "";
@@ -113,7 +131,10 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService {
 
     @Override
     public String createCreateSql(TableMetaData newTable) throws Exception {
-        DatabaseMetaData databaseMetaData = databaseMetaDataFactoryBean.getObject();
+        return createCreateSql(databaseMetaDataFactoryBean.getObject(), newTable);
+    }
+
+    public String createCreateSql(DatabaseMetaData databaseMetaData, TableMetaData newTable) throws Exception {
         SQL sql = databaseMetaData.getRenderer(SqlRender.TYPE.META_CREATE).render(newTable, true);
         if (sql instanceof EmptySQL) return "";
         StringBuilder builder = new StringBuilder(sql.getSql());
@@ -123,4 +144,89 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService {
         return builder.toString();
     }
 
+    @Override
+    public List<TableMetaData> getTableList(String datasourceId) throws SQLException {
+        SqlExecutor sqlExecutor = dynamicDataSourceService.getSqlExecutor(datasourceId);
+        DBType dbType = getDBType(datasourceId);
+        return dbType.getTableMetaParser(sqlExecutor).parseAll();
+    }
+
+    @Override
+    @Transactional(rollbackFor = Throwable.class)
+    public List<Map<String, Object>> execSql(String datasourceId, List<String> sqlList) throws SQLException {
+        return execSql(dynamicDataSourceService.getSqlExecutor(datasourceId), sqlList);
+    }
+
+    @Override
+    public String createAlterSql(String datasourceId, TableMetaData newTable) throws Exception {
+        DBType dbType = getDBType(datasourceId);
+        SqlExecutor sqlExecutor = dynamicDataSourceService.getSqlExecutor(datasourceId);
+        return createAlterSql(dbType.getDatabaseMetaData(), dbType.getTableMetaParser(sqlExecutor), newTable);
+    }
+
+    @Override
+    public String createCreateSql(String datasourceId, TableMetaData newTable) throws Exception {
+        return createCreateSql(getDBType(datasourceId).getDatabaseMetaData(), newTable);
+    }
+
+    public DBType getDBType(String datasourceId) {
+        org.hsweb.web.bean.po.datasource.DataSource dataSource = dataSourceService.selectByPk(datasourceId);
+        String driver = dataSource.getDriver();
+        if (driver.contains("mysql")) {
+            return DBType.mysql;
+        }
+        if (driver.contains("oracle")) {
+            return DBType.oracle;
+        }
+        if (driver.contains("h2")) {
+            return DBType.h2;
+        }
+        throw new NotFoundException(driver);
+    }
+
+    enum DBType {
+        mysql {
+            @Override
+            public TableMetaParser getTableMetaParser(SqlExecutor sqlExecutor) {
+                return new MysqlTableMetaParser(sqlExecutor);
+            }
+
+            @Override
+            public DatabaseMetaData getDatabaseMetaData() {
+                DatabaseMetaData databaseMetaData = new MysqlDatabaseMeta();
+                databaseMetaData.init();
+                return databaseMetaData;
+            }
+        },
+        oracle {
+            @Override
+            public TableMetaParser getTableMetaParser(SqlExecutor sqlExecutor) {
+                return new OracleTableMetaParser(sqlExecutor);
+            }
+
+            @Override
+            public DatabaseMetaData getDatabaseMetaData() {
+                DatabaseMetaData databaseMetaData = new OracleDatabaseMeta();
+                databaseMetaData.init();
+                return databaseMetaData;
+            }
+        }, h2 {
+            @Override
+            public TableMetaParser getTableMetaParser(SqlExecutor sqlExecutor) {
+                return new H2TableMetaParser(sqlExecutor);
+            }
+
+            @Override
+            public DatabaseMetaData getDatabaseMetaData() {
+                DatabaseMetaData databaseMetaData = new H2DatabaseMeta();
+                databaseMetaData.init();
+                return databaseMetaData;
+            }
+        };
+
+        public abstract DatabaseMetaData getDatabaseMetaData();
+
+        public abstract TableMetaParser getTableMetaParser(SqlExecutor sqlExecutor);
+    }
+
 }

+ 1 - 0
hsweb-web-service-impl-common/src/test/java/org/hsweb/web/service/impl/system/DataBaseManagerServiceImplTest.java

@@ -35,4 +35,5 @@ public class DataBaseManagerServiceImplTest extends AbstractTestCase {
     }
 
 
+
 }

+ 42 - 0
hsweb-web-service-interface/src/main/java/org/hsweb/web/service/datasource/DataSourceService.java

@@ -0,0 +1,42 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.datasource;
+
+import org.hsweb.web.bean.po.datasource.DataSource;
+import org.hsweb.web.service.GenericService;
+
+/**
+ * 数据源服务类
+ * Created by generator
+ */
+public interface DataSourceService extends GenericService<DataSource, String> {
+
+    /**
+     * 根据数据源ID,创建数据源实例
+     *
+     * @param id 数据源ID
+     * @return 数据源实例
+     */
+    javax.sql.DataSource createDataSource(String id);
+
+    void enable(String id);
+
+    void disable(String id);
+
+    boolean testConnection(String id);
+
+}

+ 32 - 0
hsweb-web-service-interface/src/main/java/org/hsweb/web/service/datasource/DynamicDataSourceService.java

@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015-2016 http://hsweb.me
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hsweb.web.service.datasource;
+
+import org.hsweb.ezorm.executor.SqlExecutor;
+
+import javax.sql.DataSource;
+
+/**
+ * @author zhouhao
+ */
+public interface DynamicDataSourceService {
+
+    DataSource getDataSource(String id);
+
+    SqlExecutor getSqlExecutor(String id);
+
+}

+ 11 - 3
hsweb-web-service-interface/src/main/java/org/hsweb/web/service/system/DataBaseManagerService.java

@@ -21,9 +21,17 @@ public interface DataBaseManagerService {
      */
     List<TableMetaData> getTableList() throws SQLException;
 
-    List<Map<String,Object>> execSql(List<String> sqlList) throws SQLException;
+    List<Map<String, Object>> execSql(List<String> sqlList) throws SQLException;
 
-    String createAlterSql(TableMetaData newTable)throws Exception;
+    String createAlterSql(TableMetaData newTable) throws Exception;
 
-    String createCreateSql(TableMetaData newTable)throws Exception;
+    String createCreateSql(TableMetaData newTable) throws Exception;
+
+    List<TableMetaData> getTableList(String datasourceId) throws SQLException;
+
+    List<Map<String, Object>> execSql(String datasourceId, List<String> sqlList) throws SQLException;
+
+    String createAlterSql(String datasourceId, TableMetaData newTable) throws Exception;
+
+    String createCreateSql(String datasourceId, TableMetaData newTable) throws Exception;
 }