From d778b92d4a3c3c3faaa9a7ea1b6d598ca7f8fc57 Mon Sep 17 00:00:00 2001 From: zhouhao Date: Thu, 25 Aug 2016 18:02:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=A8=E6=80=81=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/DatabaseManagerController.java | 37 +++++++--- .../core/datasource/DynamicDataSource.java | 54 +++++++++++++++ hsweb-web-dao-impl-mybatis/pom.xml | 5 ++ .../DynamicDataSourceAutoConfiguration.java | 53 ++++++++++++++ .../datasource/DataSourceServiceImpl.java | 17 +++-- .../datasource/DynamicDataSourceImpl.java | 61 ++++++++++++++++ .../DynamicDataSourceServiceImpl.java | 53 +++++++++----- .../system/DataBaseManagerServiceImpl.java | 69 +++++-------------- .../system/DataBaseManagerService.java | 8 --- 9 files changed, 262 insertions(+), 95 deletions(-) create mode 100644 hsweb-web-core/src/main/java/org/hsweb/web/core/datasource/DynamicDataSource.java create mode 100644 hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/DynamicDataSourceAutoConfiguration.java create mode 100644 hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/datasource/DynamicDataSourceImpl.java diff --git a/hsweb-web-controller/src/main/java/org/hsweb/web/controller/system/DatabaseManagerController.java b/hsweb-web-controller/src/main/java/org/hsweb/web/controller/system/DatabaseManagerController.java index 1abcab61f..b5228cbe5 100644 --- a/hsweb-web-controller/src/main/java/org/hsweb/web/controller/system/DatabaseManagerController.java +++ b/hsweb-web-controller/src/main/java/org/hsweb/web/controller/system/DatabaseManagerController.java @@ -9,6 +9,7 @@ import org.hsweb.ezorm.render.SqlAppender; import org.hsweb.ezorm.render.SqlRender; import org.hsweb.web.bean.po.user.User; import org.hsweb.web.core.authorize.annotation.Authorize; +import org.hsweb.web.core.datasource.DynamicDataSource; import org.hsweb.web.core.exception.AuthorizeException; import org.hsweb.web.core.exception.AuthorizeForbiddenException; import org.hsweb.web.core.logger.annotation.AccessLogger; @@ -61,15 +62,19 @@ public class DatabaseManagerController { return ResponseMessage.ok(dataBaseManagerService.createCreateSql(createTableMetaDataByJson(jsonObject))); } - @RequestMapping(value = "/tables/{dataSourceId}", method = RequestMethod.GET) @Authorize(action = "R") @AccessLogger("指定数据源获取表结构") public ResponseMessage showTables(@PathVariable("dataSourceId") String dataSourceId) throws SQLException { - return ResponseMessage.ok(dataBaseManagerService.getTableList(dataSourceId)) - .include(TableMetaData.class, "name", "alias", "comment", "fields") - .include(FieldMetaData.class, "name", "alias", "comment", "dataType", "properties") - .onlyData(); + try { + DynamicDataSource.use(dataSourceId); + return ResponseMessage.ok(dataBaseManagerService.getTableList()) + .include(TableMetaData.class, "name", "alias", "comment", "fields") + .include(FieldMetaData.class, "name", "alias", "comment", "dataType", "properties") + .onlyData(); + } finally { + DynamicDataSource.useDefault(false); + } } public List buildSqlList(String sql) { @@ -104,20 +109,34 @@ public class DatabaseManagerController { @RequestMapping(value = "/exec/{dataSourceId}", method = RequestMethod.POST) @AccessLogger("指定数据源执行SQL") public ResponseMessage exec(@PathVariable("dataSourceId") String dataSourceId, @RequestBody String sql) throws Exception { - - return ResponseMessage.ok(dataBaseManagerService.execSql(dataSourceId, buildSqlList(sql))); + DynamicDataSource.use(dataSourceId); + try { + return ResponseMessage.ok(dataBaseManagerService.execSql(buildSqlList(sql))); + } finally { + DynamicDataSource.useDefault(false); + } } @RequestMapping(value = "/sql/alter/{dataSourceId}", method = RequestMethod.POST) @AccessLogger("指定数据源查询修改表结构SQL") public ResponseMessage showAlterSql(@PathVariable("dataSourceId") String dataSourceId, @RequestBody JSONObject jsonObject) throws Exception { - return ResponseMessage.ok(dataBaseManagerService.createAlterSql(dataSourceId, createTableMetaDataByJson(jsonObject))); + try { + DynamicDataSource.use(dataSourceId); + return ResponseMessage.ok(dataBaseManagerService.createAlterSql(createTableMetaDataByJson(jsonObject))); + } finally { + DynamicDataSource.useDefault(false); + } } @RequestMapping(value = "/sql/create/{dataSourceId}", method = RequestMethod.POST) @AccessLogger("指定数据源查询创建表结构SQL") public ResponseMessage showCreateSql(@PathVariable("dataSourceId") String dataSourceId, @RequestBody JSONObject jsonObject) throws Exception { - return ResponseMessage.ok(dataBaseManagerService.createCreateSql(dataSourceId, createTableMetaDataByJson(jsonObject))); + try { + DynamicDataSource.use(dataSourceId); + return ResponseMessage.ok(dataBaseManagerService.createCreateSql(createTableMetaDataByJson(jsonObject))); + } finally { + DynamicDataSource.useDefault(false); + } } protected TableMetaData createTableMetaDataByJson(JSONObject jsonObject) { diff --git a/hsweb-web-core/src/main/java/org/hsweb/web/core/datasource/DynamicDataSource.java b/hsweb-web-core/src/main/java/org/hsweb/web/core/datasource/DynamicDataSource.java new file mode 100644 index 000000000..d71a82b44 --- /dev/null +++ b/hsweb-web-core/src/main/java/org/hsweb/web/core/datasource/DynamicDataSource.java @@ -0,0 +1,54 @@ +/* + * 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.core.datasource; + +import org.hsweb.web.core.utils.ThreadLocalUtils; + +import javax.sql.DataSource; + +/** + * @author zhouhao + */ +public interface DynamicDataSource extends DataSource { + String DATA_SOURCE_FLAG = "data-source-id"; + + String DATA_SOURCE_FLAG_LAST = "data-source-id-last"; + + static void useLast() { + use(ThreadLocalUtils.get(DATA_SOURCE_FLAG_LAST)); + } + + static void use(String dataSourceId) { + ThreadLocalUtils.put(DATA_SOURCE_FLAG, dataSourceId); + } + + static String getActiveDataSourceId() { + return ThreadLocalUtils.get(DATA_SOURCE_FLAG); + } + + static void useDefault(boolean rememberLast) { + if (getActiveDataSourceId() != null && rememberLast) + ThreadLocalUtils.put(DATA_SOURCE_FLAG_LAST, getActiveDataSourceId()); + ThreadLocalUtils.remove(DATA_SOURCE_FLAG); + } + + static void useDefault() { + useDefault(true); + } + + DataSource getActiveDataSource(); +} diff --git a/hsweb-web-dao-impl-mybatis/pom.xml b/hsweb-web-dao-impl-mybatis/pom.xml index 3c45ef0c3..0ec25a884 100644 --- a/hsweb-web-dao-impl-mybatis/pom.xml +++ b/hsweb-web-dao-impl-mybatis/pom.xml @@ -22,6 +22,11 @@ hsweb-web-dao-interface + + org.hsweb + hsweb-web-core + + org.springframework.boot spring-boot-starter-jdbc diff --git a/hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/DynamicDataSourceAutoConfiguration.java b/hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/DynamicDataSourceAutoConfiguration.java new file mode 100644 index 000000000..c161aa5b0 --- /dev/null +++ b/hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/DynamicDataSourceAutoConfiguration.java @@ -0,0 +1,53 @@ +/* + * 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; + +import org.hsweb.web.service.impl.datasource.DynamicDataSourceImpl; +import org.springframework.beans.factory.annotation.Autowired; +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.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.sql.DataSource; + +/** + * Created by zhouhao on 16-4-20. + */ +@Configuration +public class DynamicDataSourceAutoConfiguration { + + @Autowired + private DataSourceProperties properties; + + @Bean + @ConfigurationProperties(prefix = DataSourceProperties.PREFIX) + public DataSource dataSource() { + DataSourceBuilder factory = DataSourceBuilder + .create(this.properties.getClassLoader()) + .driverClassName(this.properties.getDriverClassName()) + .url(this.properties.getUrl()).username(this.properties.getUsername()) + .password(this.properties.getPassword()); + if (this.properties.getType() != null) { + factory.type(this.properties.getType()); + } + + return new DynamicDataSourceImpl(factory.build()); + } +} diff --git a/hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/datasource/DataSourceServiceImpl.java b/hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/datasource/DataSourceServiceImpl.java index 5cece2810..564f15f14 100644 --- a/hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/datasource/DataSourceServiceImpl.java +++ b/hsweb-web-service-impl-common/src/main/java/org/hsweb/web/service/impl/datasource/DataSourceServiceImpl.java @@ -25,19 +25,17 @@ 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.hsweb.web.service.impl.AbstractServiceImpl; 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 org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.sql.Connection; @@ -54,15 +52,15 @@ public class DataSourceServiceImpl extends AbstractServiceImpl getTableList() throws SQLException { - if (tableMetaParser == null) { - throw new BusinessException("不支持的数据库"); - } - return tableMetaParser.parseAll(); + return getDBType().getTableMetaParser(sqlExecutor).parseAll(); } @Override @@ -77,6 +65,7 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService { return execSql(sqlExecutor, sqlList); } + @Transactional(rollbackFor = Throwable.class) public List> execSql(SqlExecutor sqlExecutor, List sqlList) throws SQLException { List> response = new LinkedList<>(); for (String s : sqlList) { @@ -115,7 +104,7 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService { @Override public String createAlterSql(TableMetaData newTable) throws Exception { - return createAlterSql(databaseMetaDataFactoryBean.getObject(), tableMetaParser, newTable); + return createAlterSql(getDBType().getDatabaseMetaData(), getDBType().getTableMetaParser(sqlExecutor), newTable); } public String createAlterSql(DatabaseMetaData databaseMetaData, TableMetaParser tableMetaParser, TableMetaData newTable) throws Exception { @@ -131,7 +120,7 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService { @Override public String createCreateSql(TableMetaData newTable) throws Exception { - return createCreateSql(databaseMetaDataFactoryBean.getObject(), newTable); + return createCreateSql(getDBType().getDatabaseMetaData(), newTable); } public String createCreateSql(DatabaseMetaData databaseMetaData, TableMetaData newTable) throws Exception { @@ -144,34 +133,13 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService { return builder.toString(); } - @Override - public List 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> execSql(String datasourceId, List 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(); + public DBType getDBType() { + String datasourceId = DynamicDataSource.getActiveDataSourceId(); + String driver = dataSourceProperties.getDriverClassName(); + if (datasourceId != null) { + org.hsweb.web.bean.po.datasource.DataSource dataSource = dataSourceService.selectByPk(datasourceId); + driver = dataSource.getDriver(); + } if (driver.contains("mysql")) { return DBType.mysql; } @@ -210,7 +178,8 @@ public class DataBaseManagerServiceImpl implements DataBaseManagerService { databaseMetaData.init(); return databaseMetaData; } - }, h2 { + }, + h2 { @Override public TableMetaParser getTableMetaParser(SqlExecutor sqlExecutor) { return new H2TableMetaParser(sqlExecutor); diff --git a/hsweb-web-service-interface/src/main/java/org/hsweb/web/service/system/DataBaseManagerService.java b/hsweb-web-service-interface/src/main/java/org/hsweb/web/service/system/DataBaseManagerService.java index 2cf490ac6..a391cea3c 100644 --- a/hsweb-web-service-interface/src/main/java/org/hsweb/web/service/system/DataBaseManagerService.java +++ b/hsweb-web-service-interface/src/main/java/org/hsweb/web/service/system/DataBaseManagerService.java @@ -26,12 +26,4 @@ public interface DataBaseManagerService { String createAlterSql(TableMetaData newTable) throws Exception; String createCreateSql(TableMetaData newTable) throws Exception; - - List getTableList(String datasourceId) throws SQLException; - - List> execSql(String datasourceId, List sqlList) throws SQLException; - - String createAlterSql(String datasourceId, TableMetaData newTable) throws Exception; - - String createCreateSql(String datasourceId, TableMetaData newTable) throws Exception; }