sql执行器开发,增加权限

This commit is contained in:
暮光:城中城
2019-08-22 22:21:49 +08:00
parent 48e4a73ea9
commit ec9674441f
25 changed files with 504 additions and 110 deletions

View File

@@ -5,12 +5,19 @@ import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.exception.ConfirmException;
import com.zyplayer.doc.core.json.ResponseJson;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.DbDatasource;
import com.zyplayer.doc.data.repository.manage.entity.UserAuth;
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
import com.zyplayer.doc.data.service.manage.DbDatasourceService;
import com.zyplayer.doc.data.service.manage.UserAuthService;
import com.zyplayer.doc.db.controller.vo.DatabaseExportVo;
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
import com.zyplayer.doc.db.controller.vo.TableColumnVo.TableInfoVo;
import com.zyplayer.doc.db.framework.consts.DbAuthType;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean.DatabaseProduct;
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
@@ -19,6 +26,7 @@ import com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper;
import com.zyplayer.doc.db.framework.db.mapper.mysql.MysqlMapper;
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@@ -46,11 +54,27 @@ public class DatabaseDocController {
DatabaseRegistrationBean databaseRegistrationBean;
@Resource
DbDatasourceService dbDatasourceService;
@Resource
UserAuthService userAuthService;
@PostMapping(value = "/getDataSourceList")
public ResponseJson getDataSourceList() {
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
QueryWrapper<DbDatasource> wrapper = new QueryWrapper<>();
wrapper.eq("yn", 1);
// 没管理权限只返回有权限的数据源
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE)) {
QueryWrapper<UserAuth> updateWrapper = new QueryWrapper<>();
updateWrapper.likeRight("auth_custom_suffix", DocAuthConst.DB);
updateWrapper.eq("del_flag", 0);
updateWrapper.eq("user_id", currentUser.getUserId());
List<UserAuth> userAuthList = userAuthService.list(updateWrapper);
if (userAuthList == null || userAuthList.isEmpty()) {
return DocDbResponseJson.ok();
}
List<Long> userAuthDbIds = userAuthList.stream().map(val -> NumberUtils.toLong(val.getAuthCustomSuffix().replace(DocAuthConst.DB, ""))).collect(Collectors.toList());
wrapper.in("id", userAuthDbIds);
}
List<DbDatasource> datasourceList = dbDatasourceService.list(wrapper);
List<DatabaseFactoryBean> dataSourceList = datasourceList.stream().map(val -> {
DatabaseFactoryBean bean = new DatabaseFactoryBean();
@@ -63,26 +87,23 @@ public class DatabaseDocController {
@PostMapping(value = "/getDatabaseList")
public ResponseJson getDatabaseList(Long sourceId) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
BaseMapper baseMapper = this.getBaseMapper(sourceId);
List<DatabaseInfoDto> dbNameDtoList = baseMapper.getDatabaseList();
return DocDbResponseJson.ok(dbNameDtoList);
}
@PostMapping(value = "/getTableList")
public ResponseJson getTableList(Long sourceId, String dbName) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
BaseMapper baseMapper = this.getBaseMapper(sourceId);
List<TableInfoDto> dbTableList = baseMapper.getTableList(dbName);
return DocDbResponseJson.ok(dbTableList);
}
@PostMapping(value = "/getTableColumnList")
public ResponseJson getTableColumnList(Long sourceId, String dbName, String tableName) {
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE) && !DocUserUtil.haveCustomAuth(DbAuthType.VIEW.getName(), DocAuthConst.DB + sourceId)) {
return DocDbResponseJson.warn("没有查看该库表信息的权限");
}
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getFactoryById(sourceId);
if (databaseFactoryBean == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
@@ -93,20 +114,14 @@ public class DatabaseDocController {
@PostMapping(value = "/getTableColumnDescList")
public ResponseJson getTableColumnDescList(Long sourceId, String tableName) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
BaseMapper baseMapper = this.getBaseMapper(sourceId);
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnDescList(tableName);
return DocDbResponseJson.ok(columnDescDto);
}
@PostMapping(value = "/getTableAndColumnBySearch")
public ResponseJson getTableAndColumnBySearch(Long sourceId, String dbName, String searchText) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
BaseMapper baseMapper = this.getBaseMapper(sourceId);
if (StringUtils.isBlank(searchText)) {
return DocDbResponseJson.ok();
}
@@ -117,26 +132,23 @@ public class DatabaseDocController {
@PostMapping(value = "/getTableDescList")
public ResponseJson getTableDescList(Long sourceId, String tableName) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
BaseMapper baseMapper = this.getBaseMapper(sourceId);
List<TableDescDto> columnDescDto = baseMapper.getTableDescList(tableName);
return DocDbResponseJson.ok(columnDescDto);
}
@PostMapping(value = "/updateTableDesc")
public ResponseJson updateTableDesc(Long sourceId, String dbName, String tableName, String newDesc) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
BaseMapper baseMapper = this.getBaseMapper(sourceId);
baseMapper.updateTableDesc(dbName, tableName, newDesc);
return DocDbResponseJson.ok();
}
@PostMapping(value = "/updateTableColumnDesc")
public ResponseJson updateTableColumnDesc(Long sourceId, String dbName, String tableName, String columnName, String newDesc) {
if (!DocUserUtil.haveCustomAuth(DbAuthType.DESC_EDIT.getName(), DocAuthConst.DB + sourceId)) {
return DocDbResponseJson.warn("没有修改该表字段注释的权限");
}
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(sourceId);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
@@ -163,6 +175,9 @@ public class DatabaseDocController {
@GetMapping(value = "/exportDatabase")
public ResponseJson exportDatabase(HttpServletResponse response, Long sourceId, String dbName, String tableNames) {
if (!DocUserUtil.haveCustomAuth(DbAuthType.VIEW.getName(), DocAuthConst.DB + sourceId)) {
return DocDbResponseJson.warn("没有查看该库表信息的权限");
}
if (StringUtils.isBlank(tableNames)) {
return DocDbResponseJson.warn("请选择需要导出的表");
}
@@ -232,6 +247,18 @@ public class DatabaseDocController {
return tableColumnVo;
}
private BaseMapper getBaseMapper(Long sourceId) {
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE)
&& !DocUserUtil.haveCustomAuth(DbAuthType.VIEW.getName(), DocAuthConst.DB + sourceId)) {
throw new ConfirmException("没有查看该库表信息的权限");
}
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
if (baseMapper == null) {
throw new ConfirmException("未找到对应的数据库连接");
}
return baseMapper;
}
public static void main(String[] args) {
//File zipFile = ZipUtil.zip("d:/aaa");
File zipFile = new File("d:/111.zip");

View File

@@ -0,0 +1,155 @@
package com.zyplayer.doc.db.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.json.DocResponseJson;
import com.zyplayer.doc.core.json.ResponseJson;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.AuthInfo;
import com.zyplayer.doc.data.repository.manage.entity.UserAuth;
import com.zyplayer.doc.data.repository.manage.entity.UserInfo;
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
import com.zyplayer.doc.data.service.manage.AuthInfoService;
import com.zyplayer.doc.data.service.manage.UserAuthService;
import com.zyplayer.doc.data.service.manage.UserInfoService;
import com.zyplayer.doc.db.controller.vo.UserDbAuthVo;
import com.zyplayer.doc.db.framework.consts.DbAuthType;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 数据库权限控制器
*
* @author 暮光:城中城
* @since 2019年8月18日
*/
@RestController
@AuthMan("DB_DATASOURCE_MANAGE")
@RequestMapping("/zyplayer-doc-db/auth")
public class DbDataSourceAuthController {
private static Logger logger = LoggerFactory.getLogger(DbDataSourceAuthController.class);
@Resource
UserInfoService userInfoService;
@Resource
UserAuthService userAuthService;
@Resource
AuthInfoService authInfoService;
@PostMapping("/assign")
public ResponseJson<Object> assign(Long sourceId, String authList) {
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
List<String> authNameList = Stream.of(DbAuthType.values()).map(DbAuthType::getName).collect(Collectors.toList());
QueryWrapper<AuthInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.in("auth_name", authNameList);
Collection<AuthInfo> authInfoList = authInfoService.list(queryWrapper);
Map<String, Long> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getAuthName, AuthInfo::getId));
// 先删除所有用户的权限
QueryWrapper<UserAuth> updateWrapper = new QueryWrapper<>();
updateWrapper.eq("auth_custom_suffix", DocAuthConst.DB + sourceId);
updateWrapper.eq("del_flag", 0);
userAuthService.remove(updateWrapper);
List<UserDbAuthVo> authVoList = JSON.parseArray(authList, UserDbAuthVo.class);
for (UserDbAuthVo authVo : authVoList) {
List<UserAuth> userAuthList = new LinkedList<>();
Integer executeAuth = Optional.ofNullable(authVo.getExecuteAuth()).orElse(0);
if (executeAuth <= 0) {
Long authId = authInfoMap.get(DbAuthType.NO_AUTH.getName());
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth);
}
if (executeAuth >= 1) {
Long authId = authInfoMap.get(DbAuthType.VIEW.getName());
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth);
}
if (executeAuth >= 2) {
Long authId = authInfoMap.get(DbAuthType.SELECT.getName());
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth);
}
if (executeAuth >= 3) {
Long authId = authInfoMap.get(DbAuthType.UPDATE.getName());
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth);
}
if (Objects.equals(authVo.getDescEditAuth(), 1)) {
Long authId = authInfoMap.get(DbAuthType.DESC_EDIT.getName());
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
userAuthList.add(userAuth);
}
if (userAuthList.size() <= 0) {
continue;
}
// 保存权限,重新登录后可用,后期可以考虑在这里直接修改缓存里的用户权限
userAuthService.saveBatch(userAuthList);
}
return DocResponseJson.ok();
}
@PostMapping("/list")
public ResponseJson<Object> list(Long sourceId) {
QueryWrapper<UserAuth> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("auth_custom_suffix", DocAuthConst.DB + sourceId);
queryWrapper.eq("del_flag", 0);
List<UserAuth> authList = userAuthService.list(queryWrapper);
if (CollectionUtils.isEmpty(authList)) {
return DocResponseJson.ok();
}
// 权限ID对应的权限名
Collection<AuthInfo> authInfoList = authInfoService.listByIds(authList.stream().map(UserAuth::getAuthId).collect(Collectors.toList()));
Map<Long, String> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getId, AuthInfo::getAuthName));
// 查询用户信息
Map<Long, List<UserAuth>> userAuthGroup = authList.stream().collect(Collectors.groupingBy(UserAuth::getUserId));
Collection<UserInfo> userInfos = userInfoService.listByIds(userAuthGroup.keySet());
Map<Long, String> userInfoMap = userInfos.stream().collect(Collectors.toMap(UserInfo::getId, UserInfo::getUserName));
List<UserDbAuthVo> authVoList = new LinkedList<>();
// 组装结果集
userAuthGroup.forEach((key, value) -> {
Set<String> authNameSet = value.stream().map(auth -> authInfoMap.get(auth.getAuthId())).collect(Collectors.toSet());
UserDbAuthVo authVo = new UserDbAuthVo();
authVo.setExecuteAuth(0);
if (this.haveAuth(authNameSet, DbAuthType.UPDATE) == 1) {
authVo.setExecuteAuth(3);
} else if (this.haveAuth(authNameSet, DbAuthType.SELECT) == 1) {
authVo.setExecuteAuth(2);
} else if (this.haveAuth(authNameSet, DbAuthType.VIEW) == 1) {
authVo.setExecuteAuth(1);
}
authVo.setDescEditAuth(this.haveAuth(authNameSet, DbAuthType.DESC_EDIT));
authVo.setUserId(key);
authVo.setUserName(userInfoMap.get(key));
authVoList.add(authVo);
});
return DocResponseJson.ok(authVoList);
}
private Integer haveAuth(Set<String> authNameSet, DbAuthType dbAuthType) {
return authNameSet.contains(dbAuthType.getName()) ? 1 : 0;
}
private UserAuth createUserAuth(Long sourceId, Long loginUserId, Long userId, Long authId) {
UserAuth userAuth = new UserAuth();
userAuth.setAuthCustomSuffix(DocAuthConst.DB + sourceId);
userAuth.setCreationTime(new Date());
userAuth.setCreateUid(loginUserId);
userAuth.setDelFlag(0);
userAuth.setUserId(userId);
userAuth.setAuthId(authId);
return userAuth;
}
}

View File

@@ -25,8 +25,8 @@ import java.util.*;
* @author 暮光:城中城
* @since 2019年6月29日
*/
@AuthMan("DB_DATASOURCE_MANAGE")
@RestController
@AuthMan("DB_DATASOURCE_MANAGE")
@RequestMapping("/zyplayer-doc-db/datasource")
public class DbDatasourceController {

View File

@@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zyplayer.doc.core.annotation.AuthMan;
import com.zyplayer.doc.core.json.ResponseJson;
@@ -13,10 +12,12 @@ import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.DbFavorite;
import com.zyplayer.doc.data.repository.manage.entity.DbHistory;
import com.zyplayer.doc.data.repository.manage.mapper.DbFavoriteMapper;
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
import com.zyplayer.doc.data.service.manage.DbFavoriteService;
import com.zyplayer.doc.data.service.manage.DbHistoryService;
import com.zyplayer.doc.db.framework.consts.DbAuthType;
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteResult;
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteType;
import com.zyplayer.doc.db.framework.db.mapper.base.SqlExecutor;
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
import org.apache.commons.lang.StringUtils;
@@ -54,9 +55,16 @@ public class DbSqlExecutorController {
if (StringUtils.isBlank(sql)) {
return DocDbResponseJson.warn("执行的SQL不能为空");
}
boolean manageAuth = DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE);
boolean select = DocUserUtil.haveCustomAuth(DbAuthType.SELECT.getName(), DocAuthConst.DB + sourceId);
boolean update = DocUserUtil.haveCustomAuth(DbAuthType.UPDATE.getName(), DocAuthConst.DB + sourceId);
if (!manageAuth && !select && !update) {
return DocDbResponseJson.warn("没有该数据源的执行权限");
}
try {
Map<String, Object> paramMap = JSON.parseObject(params);
ExecuteResult executeResult = sqlExecutor.execute(sourceId, executeId, sql, paramMap);
ExecuteType executeType = (!manageAuth && select) ? ExecuteType.SELECT : ExecuteType.ALL;
ExecuteResult executeResult = sqlExecutor.execute(sourceId, executeId, executeType, sql, paramMap);
SerializeConfig mapping = new SerializeConfig();
mapping.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
mapping.put(Timestamp.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));

View File

@@ -0,0 +1,40 @@
package com.zyplayer.doc.db.controller.vo;
public class UserDbAuthVo {
private String userName;
private Long userId;
private Integer executeAuth;
private Integer descEditAuth;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Integer getExecuteAuth() {
return executeAuth;
}
public void setExecuteAuth(Integer executeAuth) {
this.executeAuth = executeAuth;
}
public Integer getDescEditAuth() {
return descEditAuth;
}
public void setDescEditAuth(Integer descEditAuth) {
this.descEditAuth = descEditAuth;
}
}

View File

@@ -1,17 +1,16 @@
package com.zyplayer.doc.db.framework.configuration;
import com.alibaba.druid.pool.DruidDataSource;
import com.zyplayer.doc.data.repository.manage.entity.DbDatasource;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.interceptor.SqlLogInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import java.sql.DatabaseMetaData;
import java.util.Properties;
public class DatasourceUtil {
private static SqlLogInterceptor sqlLogInterceptor = new SqlLogInterceptor();
@@ -19,24 +18,22 @@ public class DatasourceUtil {
public static DatabaseFactoryBean createDatabaseFactoryBean(DbDatasource dbDatasource){
try {
// 数据源配置
Properties xaProperties = new Properties();
xaProperties.setProperty("driverClassName", dbDatasource.getDriverClassName());
xaProperties.setProperty("url", dbDatasource.getSourceUrl());
xaProperties.setProperty("username", dbDatasource.getSourceName());
xaProperties.setProperty("password", dbDatasource.getSourcePassword());
xaProperties.setProperty("maxActive", "500");
xaProperties.setProperty("breakAfterAcquireFailure", "true");
xaProperties.setProperty("testOnBorrow", "true");
xaProperties.setProperty("testWhileIdle", "true");
xaProperties.setProperty("validationQuery", "select 'x'");
// 数据源
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
dataSource.setXaProperties(xaProperties);
dataSource.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
dataSource.setUniqueResourceName("zyplayer-doc-db" + dbDatasource.getId());
dataSource.setMaxPoolSize(500);
dataSource.setMinPoolSize(1);
dataSource.setMaxLifetime(60);
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(dbDatasource.getDriverClassName());
dataSource.setUrl(dbDatasource.getSourceUrl());
dataSource.setUsername(dbDatasource.getSourceName());
dataSource.setPassword(dbDatasource.getSourcePassword());
dataSource.setInitialSize(2);
dataSource.setMinIdle(2);
dataSource.setMaxActive(50);
dataSource.setTestWhileIdle(true);
dataSource.setTestOnBorrow(false);
dataSource.setTestOnReturn(false);
dataSource.setValidationQuery("select 1");
dataSource.setMaxWait(3000);
dataSource.setTimeBetweenEvictionRunsMillis(60000);
dataSource.setMinEvictableIdleTimeMillis(3600000);
dataSource.setName("zyplayer-doc-db" + dbDatasource.getId());
// 描述连接信息的对象
DatabaseFactoryBean databaseFactoryBean = new DatabaseFactoryBean();
DatabaseMetaData metaData = dataSource.getConnection().getMetaData();
@@ -44,7 +41,7 @@ public class DatasourceUtil {
Resource[] resources = null;
String dbUrl = metaData.getURL();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
if (productName.indexOf("mysql") >= 0) {
if (productName.contains("mysql")) {
// jdbc:mysql://192.168.0.1:3306/user_info?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
String[] urlParamArr = dbUrl.split("\\?");
String[] urlDbNameArr = urlParamArr[0].split("/");
@@ -54,7 +51,7 @@ public class DatasourceUtil {
}
databaseFactoryBean.setDatabaseProduct(DatabaseFactoryBean.DatabaseProduct.MYSQL);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/mysql/*.xml");
} else if (productName.indexOf("sql server") >= 0) {
} else if (productName.contains("sql server")) {
// jdbc:jtds:sqlserver://192.168.0.1:33434;socketTimeout=60;DatabaseName=user_info;
String[] urlParamArr = dbUrl.split(";");
String[] urlDbNameArr = urlParamArr[0].split("/");

View File

@@ -0,0 +1,33 @@
package com.zyplayer.doc.db.framework.consts;
public enum DbAuthType {
NO_AUTH(0, "DB_NO_AUTH_"),
VIEW(1, "DB_VIEW_"),
SELECT(2, "DB_SELECT_"),
UPDATE(3, "DB_UPDATE_"),
DESC_EDIT(3, "DB_DESC_EDIT_"),
;
private Integer type;
private String name;
DbAuthType(Integer type, String name) {
this.type = type;
this.name = name;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -1,7 +1,7 @@
package com.zyplayer.doc.db.framework.db.bean;
import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
/**
* 描述连接信息的对象
@@ -10,7 +10,7 @@ import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
*/
public class DatabaseFactoryBean {
private Long id;
private AtomikosDataSourceBean dataSource;
private DruidDataSource dataSource;
private SqlSessionTemplate sqlSessionTemplate;
private String url;
private String host;
@@ -38,11 +38,11 @@ public class DatabaseFactoryBean {
MYSQL, SQLSERVER
}
public AtomikosDataSourceBean getDataSource() {
public DruidDataSource getDataSource() {
return dataSource;
}
public void setDataSource(AtomikosDataSourceBean dataSource) {
public void setDataSource(DruidDataSource dataSource) {
this.dataSource = dataSource;
}

View File

@@ -0,0 +1,5 @@
package com.zyplayer.doc.db.framework.db.mapper.base;
public enum ExecuteType {
ALL, SELECT,
}

View File

@@ -1,11 +1,7 @@
package com.zyplayer.doc.db.framework.db.mapper.base;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.zyplayer.doc.data.config.security.DocUserDetails;
import com.zyplayer.doc.data.config.security.DocUserUtil;
import com.zyplayer.doc.data.repository.manage.entity.DbFavorite;
import com.zyplayer.doc.data.repository.manage.entity.DbHistory;
import com.zyplayer.doc.data.service.manage.DbFavoriteService;
import com.zyplayer.doc.data.service.manage.DbHistoryService;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
@@ -20,11 +16,13 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.*;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -64,9 +62,9 @@ public class SqlExecutor {
* @author 暮光:城中城
* @since 2019年8月18日
*/
public ExecuteResult execute(Long datasourceId, String executeId, String sql, Map<String, Object> paramMap) {
public ExecuteResult execute(Long datasourceId, String executeId, ExecuteType executeType, String sql, Map<String, Object> paramMap) {
DatabaseFactoryBean factoryBean = databaseRegistrationBean.getFactoryById(datasourceId);
return this.execute(factoryBean, executeId, sql, paramMap, null);
return this.execute(factoryBean, executeId, executeType, sql, paramMap, null);
}
/**
@@ -74,19 +72,11 @@ public class SqlExecutor {
* @author 暮光:城中城
* @since 2019年8月18日
*/
public ExecuteResult execute(DatabaseFactoryBean factoryBean, String executeId, String sql, Map<String, Object> paramMap, ResultHandler handler) {
public ExecuteResult execute(DatabaseFactoryBean factoryBean, String executeId, ExecuteType executeType, String sql, Map<String, Object> paramMap, ResultHandler handler) {
if (factoryBean == null) {
return new ExecuteResult();
}
// 组装参数
GenericTokenParser parser = new GenericTokenParser("${", "}", content -> {
Object o = paramMap.get(content);
return (o == null) ? null : String.valueOf(o);
});
sql = parser.parse(sql);
SqlSourceBuilder sqlSourceBuilder = new SqlSourceBuilder(new MybatisConfiguration());
StaticSqlSource parse = (StaticSqlSource) sqlSourceBuilder.parse(sql, Object.class, paramMap);
BoundSql boundSql = parse.getBoundSql(new Object());
BoundSql boundSql = getBoundSql(sql, paramMap);
sql = boundSql.getSql();
String sqlStr = SqlLogUtil.getSqlString(paramMap, boundSql);
logger.info("sql ==> {}", sqlStr);
@@ -95,16 +85,23 @@ public class SqlExecutor {
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
PreparedStatement preparedStatement = null;
DruidPooledConnection connection = null;
// 执行查询
try {
Connection connection = factoryBean.getDataSource().getConnection();
connection = factoryBean.getDataSource().getConnection();
preparedStatement = connection.prepareStatement(sql);
// 设置当前的PreparedStatement
statementMap.put(executeId, preparedStatement);
for (int i = 0; i < parameterMappings.size(); i++) {
preparedStatement.setObject(i + 1, paramMap.get(parameterMappings.get(i).getProperty()));
}
preparedStatement.execute();
// 限制下最大数量
preparedStatement.setMaxRows(1000);
if (ExecuteType.SELECT.equals(executeType)) {
preparedStatement.executeQuery();
} else {
preparedStatement.execute();
}
// 查询的结果集
ResultSet resultSet = preparedStatement.getResultSet();
List<Map<String, Object>> resultList = new LinkedList<>();
@@ -137,6 +134,25 @@ public class SqlExecutor {
} catch (Exception e) {
logger.error("关闭Statement失败");
}
try {
if (connection != null && !connection.isClosed()) {
connection.recycle();
}
} catch (Exception e) {
logger.error("回收connection失败");
}
}
}
private BoundSql getBoundSql(String sql, Map<String, Object> paramMap){
// 组装参数
GenericTokenParser parser = new GenericTokenParser("${", "}", content -> {
Object o = paramMap.get(content);
return (o == null) ? null : String.valueOf(o);
});
sql = parser.parse(sql);
SqlSourceBuilder sqlSourceBuilder = new SqlSourceBuilder(new MybatisConfiguration());
StaticSqlSource parse = (StaticSqlSource) sqlSourceBuilder.parse(sql, Object.class, paramMap);
return parse.getBoundSql(new Object());
}
}