数据库文档查询优化
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
package com.zyplayer.doc.db.controller;
|
||||
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.exception.ConfirmException;
|
||||
@@ -23,22 +22,18 @@ 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;
|
||||
import com.zyplayer.doc.db.framework.db.dto.*;
|
||||
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 com.zyplayer.doc.db.framework.utils.PoiUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import com.zyplayer.doc.db.service.DbBaseFactory;
|
||||
import com.zyplayer.doc.db.service.DbBaseService;
|
||||
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;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -60,6 +55,8 @@ public class DatabaseDocController {
|
||||
DbDatasourceService dbDatasourceService;
|
||||
@Resource
|
||||
UserAuthService userAuthService;
|
||||
@Resource
|
||||
DbBaseFactory dbBaseFactory;
|
||||
|
||||
@PostMapping(value = "/getDataSourceList")
|
||||
public ResponseJson getDataSourceList() {
|
||||
@@ -103,46 +100,8 @@ public class DatabaseDocController {
|
||||
if (resultObj != null) {
|
||||
return DocDbResponseJson.ok(resultObj);
|
||||
}
|
||||
BaseMapper baseMapper = this.getBaseMapper(sourceId);
|
||||
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
|
||||
List<DatabaseInfoDto> dbNameDtoList = baseMapper.getDatabaseList();
|
||||
Map<String, List<TableInfoDto>> dbTableMap = new HashMap<>();
|
||||
Map<String, List<TableColumnDescDto>> tableColumnsMap = new HashMap<>();
|
||||
|
||||
Map<String, List<TableInfoDto>> tableMapList = new HashMap<>();
|
||||
// MYSQL可以一次性查询所有库表
|
||||
if (databaseFactoryBean.getDatabaseProduct() == DatabaseProduct.MYSQL) {
|
||||
List<TableInfoDto> dbTableList = baseMapper.getTableList(null);
|
||||
tableMapList = dbTableList.stream().collect(Collectors.groupingBy(TableInfoDto::getDbName));
|
||||
}
|
||||
for (DatabaseInfoDto infoDto : dbNameDtoList) {
|
||||
List<TableInfoDto> tableInfoDtoList = tableMapList.get(infoDto.getDbName());
|
||||
// SQLSERVER必须要库才能查
|
||||
if (databaseFactoryBean.getDatabaseProduct() == DatabaseProduct.SQLSERVER) {
|
||||
tableInfoDtoList = baseMapper.getTableList(infoDto.getDbName());
|
||||
}
|
||||
if (CollectionUtils.isEmpty(tableInfoDtoList)) {
|
||||
continue;
|
||||
}
|
||||
dbTableMap.put(infoDto.getDbName(), tableInfoDtoList);
|
||||
// 小于10个库,查所有库,否则只查询当前链接的库,防止库表太多,数据量太大
|
||||
// 如果觉得没必要就自己改吧!
|
||||
Map<String, List<TableColumnDescDto>> columnDescDtoMap = new HashMap<>();
|
||||
if (dbNameDtoList.size() <= 10 || Objects.equals(databaseFactoryBean.getDbName(), infoDto.getDbName())) {
|
||||
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnList(infoDto.getDbName(), null);
|
||||
columnDescDtoMap = columnDescDto.stream().collect(Collectors.groupingBy(TableColumnDescDto::getTableName));
|
||||
}
|
||||
for (TableInfoDto tableInfoDto : tableInfoDtoList) {
|
||||
List<TableColumnDescDto> descDtoList = columnDescDtoMap.get(tableInfoDto.getTableName());
|
||||
if (CollectionUtils.isNotEmpty(descDtoList)) {
|
||||
tableColumnsMap.put(tableInfoDto.getTableName(), descDtoList);
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, Object> dbResultMap = new HashMap<>();
|
||||
dbResultMap.put("db", dbNameDtoList);
|
||||
dbResultMap.put("table", dbTableMap);
|
||||
dbResultMap.put("column", tableColumnsMap);
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
Map<String, Object> dbResultMap = dbBaseService.getEditorData(sourceId);
|
||||
// 缓存10分钟,如果10分钟内库里面增删改了表或字段,则提示不出来
|
||||
CacheUtil.put(cacheKey, dbResultMap, 6000);
|
||||
return DocDbResponseJson.ok(dbResultMap);
|
||||
@@ -150,110 +109,81 @@ public class DatabaseDocController {
|
||||
|
||||
@PostMapping(value = "/getTableDdl")
|
||||
public ResponseJson getTableDdl(Long sourceId, String dbName, String tableName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
Map<String, String> dataMap = baseMapper.getTableDdl(dbName, tableName);
|
||||
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
|
||||
// 不同数据源类型获取方式不一致
|
||||
if (Objects.equals(DatabaseProduct.MYSQL, databaseFactoryBean.getDatabaseProduct())) {
|
||||
return DocDbResponseJson.ok(dataMap.get("Create Table"));
|
||||
}
|
||||
return DocDbResponseJson.ok("暂未支持的数据库类型");
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
String tableDdl = dbBaseService.getTableDdl(sourceId, dbName, tableName);
|
||||
return DocDbResponseJson.ok(tableDdl);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/getDatabaseList")
|
||||
public ResponseJson getDatabaseList(Long sourceId) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
List<DatabaseInfoDto> dbNameDtoList = baseMapper.getDatabaseList();
|
||||
return DocDbResponseJson.ok(dbNameDtoList);
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
List<DatabaseInfoDto> databaseList = dbBaseService.getDatabaseList(sourceId);
|
||||
return DocDbResponseJson.ok(databaseList);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/getTableStatus")
|
||||
public ResponseJson getTableStatus(Long sourceId, String dbName, String tableName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
TableStatusVo tableStatusVo = baseMapper.getTableStatus(dbName, tableName);
|
||||
DatabaseFactoryBean factoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
|
||||
tableStatusVo.setDbType(factoryBean.getDatabaseProduct().name().toLowerCase());
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
TableStatusVo tableStatusVo = dbBaseService.getTableStatus(sourceId, dbName, tableName);
|
||||
return DocDbResponseJson.ok(tableStatusVo);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/getTableList")
|
||||
public ResponseJson getTableList(Long sourceId, String dbName) {
|
||||
BaseMapper baseMapper = this.getBaseMapper(sourceId);
|
||||
List<TableInfoDto> dbTableList = baseMapper.getTableList(dbName);
|
||||
return DocDbResponseJson.ok(dbTableList);
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
List<TableInfoDto> tableList = dbBaseService.getTableList(sourceId, dbName);
|
||||
return DocDbResponseJson.ok(tableList);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/getTableColumnList")
|
||||
public ResponseJson getTableColumnList(Long sourceId, String dbName, String tableName) {
|
||||
this.judgeAuth(sourceId, DbAuthType.VIEW.getName(), "没有查看该库表信息的权限");
|
||||
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
|
||||
if (databaseFactoryBean == null) {
|
||||
return DocDbResponseJson.warn("未找到对应的数据库连接");
|
||||
}
|
||||
TableColumnVo tableColumnVo = this.getTableColumnVo(databaseFactoryBean, dbName, tableName);
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
TableColumnVo tableColumnVo = dbBaseService.getTableColumnList(sourceId, dbName, tableName);
|
||||
return DocDbResponseJson.ok(tableColumnVo);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/getTableColumnDescList")
|
||||
public ResponseJson getTableColumnDescList(Long sourceId, String tableName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnDescList(tableName);
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
List<TableColumnDescDto> columnDescDto = dbBaseService.getTableColumnDescList(sourceId, tableName);
|
||||
return DocDbResponseJson.ok(columnDescDto);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/getTableAndColumnBySearch")
|
||||
public ResponseJson getTableAndColumnBySearch(Long sourceId, String dbName, String searchText) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
searchText = "%" + searchText + "%";
|
||||
List<QueryTableColumnDescDto> columnDescDto = baseMapper.getTableAndColumnBySearch(dbName, searchText);
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
List<QueryTableColumnDescDto> columnDescDto = dbBaseService.getTableAndColumnBySearch(sourceId, dbName, searchText);
|
||||
return DocDbResponseJson.ok(columnDescDto);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/getTableDescList")
|
||||
public ResponseJson getTableDescList(Long sourceId, String dbName, String tableName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
List<TableDescDto> columnDescDto = baseMapper.getTableDescList(dbName, tableName);
|
||||
return DocDbResponseJson.ok(columnDescDto);
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
List<TableDescDto> tableDescList = dbBaseService.getTableDescList(sourceId, dbName, tableName);
|
||||
return DocDbResponseJson.ok(tableDescList);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/updateTableDesc")
|
||||
public ResponseJson updateTableDesc(Long sourceId, String dbName, String tableName, String newDesc) {
|
||||
this.judgeAuth(sourceId, DbAuthType.DESC_EDIT.getName(), "没有修改该表注释的权限");
|
||||
BaseMapper baseMapper = this.getBaseMapper(sourceId);
|
||||
baseMapper.updateTableDesc(dbName, tableName, newDesc);
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
dbBaseService.updateTableDesc(sourceId, dbName, tableName, newDesc);
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
|
||||
@PostMapping(value = "/updateTableColumnDesc")
|
||||
public ResponseJson updateTableColumnDesc(Long sourceId, String dbName, String tableName, String columnName, String newDesc) {
|
||||
this.judgeAuth(sourceId, DbAuthType.DESC_EDIT.getName(), "没有修改该表字段注释的权限");
|
||||
BaseMapper baseMapper = this.getBaseMapper(sourceId);
|
||||
ColumnInfoDto columnInfo = null;
|
||||
// mysql要同时修改类型默认值等,所以先查出来
|
||||
MysqlMapper mysqlMapper = databaseRegistrationBean.getBaseMapper(sourceId, MysqlMapper.class);
|
||||
if (mysqlMapper != null) {
|
||||
columnInfo = mysqlMapper.getColumnInfo(dbName, tableName, columnName);
|
||||
String isNullable = Optional.ofNullable(columnInfo.getIsNullable()).orElse("");
|
||||
columnInfo.setIsNullable("yes".equalsIgnoreCase(isNullable) ? "null" : "not null");
|
||||
String columnDefault = columnInfo.getColumnDefault();
|
||||
if (StringUtils.isNotBlank(columnDefault)) {
|
||||
columnInfo.setColumnDefault("DEFAULT " + columnDefault);
|
||||
} else {
|
||||
columnInfo.setColumnDefault("");
|
||||
}
|
||||
String extra = columnInfo.getExtra();
|
||||
columnInfo.setExtra(StringUtils.isBlank(extra) ? "" : extra);
|
||||
}
|
||||
baseMapper.updateTableColumnDesc(dbName, tableName, columnName, newDesc, columnInfo);
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
dbBaseService.updateTableColumnDesc(sourceId, dbName, tableName, columnName, newDesc);
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
|
||||
@PostMapping(value = "/exportDatabase")
|
||||
public ResponseJson exportDatabase(HttpServletResponse response, Long sourceId, String dbName, String tableNames, Integer exportType, Integer exportFormat) {
|
||||
this.judgeAuth(sourceId, DbAuthType.VIEW.getName(), "没有查看该库表信息的权限");
|
||||
if (StringUtils.isBlank(tableNames)) {
|
||||
return DocDbResponseJson.warn("请选择需要导出的表");
|
||||
}
|
||||
@@ -267,18 +197,15 @@ public class DatabaseDocController {
|
||||
}
|
||||
|
||||
private DocDbResponseJson exportForTableDdl(HttpServletResponse response, Long sourceId, String dbName, List<String> tableNameList, Integer exportFormat) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
|
||||
DatabaseProduct databaseProduct = databaseFactoryBean.getDatabaseProduct();
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
Map<String, String> ddlSqlMap = new HashMap<>();
|
||||
for (String tableName : tableNameList) {
|
||||
Map<String, String> dataMap = baseMapper.getTableDdl(dbName, tableName);
|
||||
// 不同数据源类型获取方式不一致
|
||||
if (Objects.equals(DatabaseProduct.MYSQL, databaseProduct)) {
|
||||
ddlSqlMap.put(tableName, dataMap.get("Create Table"));
|
||||
}
|
||||
String tableDdl = dbBaseService.getTableDdl(sourceId, dbName, tableName);
|
||||
ddlSqlMap.put(tableName, tableDdl);
|
||||
}
|
||||
try {
|
||||
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
|
||||
DatabaseProduct databaseProduct = databaseFactoryBean.getDatabaseProduct();
|
||||
PoiUtil.exportByDdl(ddlSqlMap, dbName, databaseProduct.name(), response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -288,14 +215,12 @@ public class DatabaseDocController {
|
||||
}
|
||||
|
||||
private DocDbResponseJson exportForTableDoc(HttpServletResponse response, Long sourceId, String dbName, List<String> tableNameList, Integer exportFormat) {
|
||||
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
|
||||
if (databaseFactoryBean == null) {
|
||||
return DocDbResponseJson.warn("未找到对应的数据库连接");
|
||||
}
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
// 数据组装
|
||||
List<TableInfoVo> tableList = new LinkedList<>();
|
||||
Map<String, List<TableColumnDescDto>> columnList = new HashMap<>();
|
||||
for (String tableName : tableNameList) {
|
||||
TableColumnVo tableColumnVo = this.getTableColumnVo(databaseFactoryBean, dbName, tableName);
|
||||
TableColumnVo tableColumnVo = dbBaseService.getTableColumnList(sourceId, dbName, tableName);
|
||||
columnList.put(tableName, tableColumnVo.getColumnList());
|
||||
tableList.add(tableColumnVo.getTableInfo());
|
||||
}
|
||||
@@ -315,39 +240,6 @@ public class DatabaseDocController {
|
||||
}
|
||||
}
|
||||
|
||||
private TableColumnVo getTableColumnVo(DatabaseFactoryBean databaseFactoryBean, String dbName, String tableName) {
|
||||
SqlSessionTemplate sessionTemplate = databaseFactoryBean.getSqlSessionTemplate();
|
||||
BaseMapper baseMapper = sessionTemplate.getMapper(BaseMapper.class);
|
||||
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnList(dbName, tableName);
|
||||
// SQLSERVER要单独查字段注释
|
||||
if (databaseFactoryBean.getDatabaseProduct() == DatabaseProduct.SQLSERVER) {
|
||||
List<TableColumnDescDto> columnDescList = baseMapper.getTableColumnDescList(tableName);
|
||||
Map<String, TableColumnDescDto> columnMap = columnDescDto.stream().collect(Collectors.toMap(TableColumnDescDto::getName, val -> val));
|
||||
// 字段注释
|
||||
for (TableColumnDescDto descDto : columnDescList) {
|
||||
TableColumnDescDto tempDesc = columnMap.get(descDto.getName());
|
||||
if (tempDesc != null) {
|
||||
tempDesc.setDescription(descDto.getDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
TableColumnVo tableColumnVo = new TableColumnVo();
|
||||
tableColumnVo.setColumnList(columnDescDto);
|
||||
// 表注释
|
||||
TableInfoVo tableInfoVo = new TableInfoVo();
|
||||
List<TableDescDto> tableDescList = baseMapper.getTableDescList(dbName, tableName);
|
||||
String description = null;
|
||||
if (tableDescList.size() > 0) {
|
||||
TableDescDto descDto = tableDescList.get(0);
|
||||
description = descDto.getDescription();
|
||||
}
|
||||
description = Optional.ofNullable(description).orElse("");
|
||||
tableInfoVo.setDescription(description);
|
||||
tableInfoVo.setTableName(tableName);
|
||||
tableColumnVo.setTableInfo(tableInfoVo);
|
||||
return tableColumnVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限判断
|
||||
*
|
||||
@@ -359,35 +251,5 @@ public class DatabaseDocController {
|
||||
throw new ConfirmException(noAuthInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取BaseMapper
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
*/
|
||||
private BaseMapper getBaseMapper(Long sourceId) {
|
||||
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
|
||||
if (baseMapper == null) {
|
||||
throw new ConfirmException("未找到对应的数据库连接");
|
||||
}
|
||||
return baseMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断查看权和获取BaseMapper
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
*/
|
||||
private BaseMapper getViewAuthBaseMapper(Long sourceId) {
|
||||
this.judgeAuth(sourceId, DbAuthType.VIEW.getName(), "没有查看该库表信息的权限");
|
||||
return this.getBaseMapper(sourceId);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
//File zipFile = ZipUtil.zip("d:/aaa");
|
||||
File zipFile = new File("d:/111.zip");
|
||||
ZipUtil.zip(zipFile, true, new File("d:/111.txt"),
|
||||
new File("d:/222.txt"), new File("d:/aaa"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.zyplayer.doc.db.service;
|
||||
|
||||
import com.zyplayer.doc.core.exception.ConfirmException;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class DbBaseFactory {
|
||||
|
||||
@Resource
|
||||
DatabaseRegistrationBean databaseRegistrationBean;
|
||||
@Resource
|
||||
private List<DbBaseService> dbBaseServiceList;
|
||||
private Map<DatabaseFactoryBean.DatabaseProduct, DbBaseService> dbBaseServiceMap;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
dbBaseServiceMap = new HashMap<>();
|
||||
dbBaseServiceList.forEach(item -> dbBaseServiceMap.put(item.getDatabaseProduct(), item));
|
||||
}
|
||||
|
||||
public DbBaseService getDbBaseService(Long sourceId) {
|
||||
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
|
||||
if (databaseFactoryBean == null) {
|
||||
throw new ConfirmException("未找到对应的数据库连接");
|
||||
}
|
||||
return dbBaseServiceMap.get(databaseFactoryBean.getDatabaseProduct());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
package com.zyplayer.doc.db.service;
|
||||
|
||||
import com.zyplayer.doc.core.exception.ConfirmException;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
|
||||
import com.zyplayer.doc.db.controller.vo.TableStatusVo;
|
||||
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.DatabaseRegistrationBean;
|
||||
import com.zyplayer.doc.db.framework.db.dto.*;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 数据库的mapper持有对象接口
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月8日
|
||||
*/
|
||||
public abstract class DbBaseService {
|
||||
|
||||
@Resource
|
||||
DatabaseRegistrationBean databaseRegistrationBean;
|
||||
|
||||
/**
|
||||
* 判断查看权和获取BaseMapper
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
*/
|
||||
public BaseMapper getViewAuthBaseMapper(Long sourceId) {
|
||||
this.judgeAuth(sourceId, DbAuthType.VIEW.getName(), "没有查看该库表信息的权限");
|
||||
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
|
||||
if (baseMapper == null) {
|
||||
throw new ConfirmException("未找到对应的数据库连接");
|
||||
}
|
||||
return baseMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限判断
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
*/
|
||||
private void judgeAuth(Long sourceId, String authName, String noAuthInfo) {
|
||||
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE)
|
||||
&& !DocUserUtil.haveCustomAuth(authName, DocAuthConst.DB + sourceId)) {
|
||||
throw new ConfirmException(noAuthInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前是什么数据源服务
|
||||
* @return 服务类型
|
||||
*/
|
||||
abstract DatabaseFactoryBean.DatabaseProduct getDatabaseProduct();
|
||||
|
||||
/**
|
||||
* 获取库列表
|
||||
*
|
||||
* @return 数据库列表
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月8日
|
||||
*/
|
||||
public String getTableDdl(Long sourceId, String dbName, String tableName) {
|
||||
// 需要各数据服务自己实现,各数据库产品的实现都不一样
|
||||
throw new ConfirmException("暂未支持的数据库类型");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取库列表
|
||||
*
|
||||
* @return 数据库列表
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月8日
|
||||
*/
|
||||
public List<DatabaseInfoDto> getDatabaseList(Long sourceId) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
return baseMapper.getDatabaseList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表列表
|
||||
*
|
||||
* @param dbName 数据库名
|
||||
* @return 数据库表列表
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月8日
|
||||
*/
|
||||
public List<TableInfoDto> getTableList(Long sourceId, String dbName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
return baseMapper.getTableList(dbName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字段列表
|
||||
*
|
||||
* @param dbName 数据库名
|
||||
* @param tableName 表名
|
||||
* @return 字段列表
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月8日
|
||||
*/
|
||||
public TableColumnVo getTableColumnList(Long sourceId, String dbName, String tableName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnList(dbName, tableName);
|
||||
TableColumnVo tableColumnVo = new TableColumnVo();
|
||||
tableColumnVo.setColumnList(columnDescDto);
|
||||
// 表注释
|
||||
TableColumnVo.TableInfoVo tableInfoVo = new TableColumnVo.TableInfoVo();
|
||||
List<TableDescDto> tableDescList = baseMapper.getTableDescList(dbName, tableName);
|
||||
String description = null;
|
||||
if (tableDescList.size() > 0) {
|
||||
TableDescDto descDto = tableDescList.get(0);
|
||||
description = descDto.getDescription();
|
||||
}
|
||||
description = Optional.ofNullable(description).orElse("");
|
||||
tableInfoVo.setDescription(description);
|
||||
tableInfoVo.setTableName(tableName);
|
||||
tableColumnVo.setTableInfo(tableInfoVo);
|
||||
return tableColumnVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字段注释
|
||||
*
|
||||
* @param tableName 表名
|
||||
* @return 表字段注释
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月8日
|
||||
*/
|
||||
public List<TableColumnDescDto> getTableColumnDescList(Long sourceId, String tableName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
return baseMapper.getTableColumnDescList(tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模糊搜索表和字段
|
||||
*
|
||||
* @param dbName 数据库名
|
||||
* @param searchText 搜索内容
|
||||
* @return 表和字段信息
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月8日
|
||||
*/
|
||||
public List<QueryTableColumnDescDto> getTableAndColumnBySearch(Long sourceId, String dbName, String searchText) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
searchText = "%" + searchText + "%";
|
||||
return baseMapper.getTableAndColumnBySearch(dbName, searchText);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表注释
|
||||
*
|
||||
* @param tableName 可不传,传了只查询指定表的注释
|
||||
* @return 表注释
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月8日
|
||||
*/
|
||||
public List<TableDescDto> getTableDescList(Long sourceId, String dbName, String tableName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
return baseMapper.getTableDescList(dbName, tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加表注释
|
||||
*
|
||||
* @param tableName 表名
|
||||
* @param newDesc 新的注释
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月8日
|
||||
*/
|
||||
public void updateTableDesc(Long sourceId, String dbName, String tableName, String newDesc) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
baseMapper.updateTableDesc(dbName, tableName, newDesc);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加字段注释
|
||||
*
|
||||
* @param dbName 数据库名
|
||||
* @param tableName 表名
|
||||
* @param columnName 字段名
|
||||
* @param newDesc 新的注释
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月8日
|
||||
*/
|
||||
public void updateTableColumnDesc(Long sourceId, String dbName, String tableName, String columnName, String newDesc) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
baseMapper.updateTableColumnDesc(dbName, tableName, columnName, newDesc, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表基本信息
|
||||
*
|
||||
* @param dbName 数据库名
|
||||
* @param tableName 表名
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年9月1日
|
||||
*/
|
||||
public TableStatusVo getTableStatus(Long sourceId, String dbName, String tableName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
TableStatusVo tableStatusVo = baseMapper.getTableStatus(dbName, tableName);
|
||||
DatabaseFactoryBean factoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
|
||||
tableStatusVo.setDbType(factoryBean.getDatabaseProduct().name().toLowerCase());
|
||||
return tableStatusVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取编辑器所需的所有信息,用于自动补全
|
||||
* 此接口会返回所有库表结构,介意的话请自己手动屏蔽调此接口
|
||||
*
|
||||
* @param sourceId sourceId
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年9月1日
|
||||
*/
|
||||
public Map<String, Object> getEditorData(Long sourceId) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
|
||||
List<DatabaseInfoDto> dbNameDtoList = baseMapper.getDatabaseList();
|
||||
Map<String, List<TableInfoDto>> dbTableMap = new HashMap<>();
|
||||
Map<String, List<TableColumnDescDto>> tableColumnsMap = new HashMap<>();
|
||||
|
||||
Map<String, List<TableInfoDto>> tableMapList = new HashMap<>();
|
||||
// MYSQL可以一次性查询所有库表
|
||||
if (databaseFactoryBean.getDatabaseProduct() == DatabaseFactoryBean.DatabaseProduct.MYSQL) {
|
||||
List<TableInfoDto> dbTableList = baseMapper.getTableList(null);
|
||||
tableMapList = dbTableList.stream().collect(Collectors.groupingBy(TableInfoDto::getDbName));
|
||||
}
|
||||
for (DatabaseInfoDto infoDto : dbNameDtoList) {
|
||||
List<TableInfoDto> tableInfoDtoList = tableMapList.get(infoDto.getDbName());
|
||||
// SQLSERVER必须要库才能查
|
||||
if (databaseFactoryBean.getDatabaseProduct() == DatabaseFactoryBean.DatabaseProduct.SQLSERVER) {
|
||||
tableInfoDtoList = baseMapper.getTableList(infoDto.getDbName());
|
||||
}
|
||||
if (CollectionUtils.isEmpty(tableInfoDtoList)) {
|
||||
continue;
|
||||
}
|
||||
dbTableMap.put(infoDto.getDbName(), tableInfoDtoList);
|
||||
// 小于10个库,查所有库,否则只查询当前链接的库,防止库表太多,数据量太大
|
||||
// 如果觉得没必要就自己改吧!
|
||||
Map<String, List<TableColumnDescDto>> columnDescDtoMap = new HashMap<>();
|
||||
if (dbNameDtoList.size() <= 10 || Objects.equals(databaseFactoryBean.getDbName(), infoDto.getDbName())) {
|
||||
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnList(infoDto.getDbName(), null);
|
||||
columnDescDtoMap = columnDescDto.stream().collect(Collectors.groupingBy(TableColumnDescDto::getTableName));
|
||||
}
|
||||
for (TableInfoDto tableInfoDto : tableInfoDtoList) {
|
||||
List<TableColumnDescDto> descDtoList = columnDescDtoMap.get(tableInfoDto.getTableName());
|
||||
if (CollectionUtils.isNotEmpty(descDtoList)) {
|
||||
tableColumnsMap.put(tableInfoDto.getTableName(), descDtoList);
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, Object> dbResultMap = new HashMap<>();
|
||||
dbResultMap.put("db", dbNameDtoList);
|
||||
dbResultMap.put("table", dbTableMap);
|
||||
dbResultMap.put("column", tableColumnsMap);
|
||||
return dbResultMap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.zyplayer.doc.db.service;
|
||||
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
|
||||
import com.zyplayer.doc.db.framework.db.dto.ColumnInfoDto;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.mysql.MysqlMapper;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class MysqlServiceImpl extends DbBaseService {
|
||||
|
||||
@Override
|
||||
public DatabaseFactoryBean.DatabaseProduct getDatabaseProduct() {
|
||||
return DatabaseFactoryBean.DatabaseProduct.MYSQL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableDdl(Long sourceId, String dbName, String tableName) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
Map<String, String> tableDdl = baseMapper.getTableDdl(dbName, tableName);
|
||||
return tableDdl.get("Create Table");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTableColumnDesc(Long sourceId, String dbName, String tableName, String columnName, String newDesc) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
// mysql要同时修改类型默认值等,所以先查出来
|
||||
MysqlMapper mysqlMapper = databaseRegistrationBean.getBaseMapper(sourceId, MysqlMapper.class);
|
||||
ColumnInfoDto columnInfo = mysqlMapper.getColumnInfo(dbName, tableName, columnName);
|
||||
String isNullable = Optional.ofNullable(columnInfo.getIsNullable()).orElse("");
|
||||
columnInfo.setIsNullable("yes".equalsIgnoreCase(isNullable) ? "null" : "not null");
|
||||
String columnDefault = columnInfo.getColumnDefault();
|
||||
if (StringUtils.isNotBlank(columnDefault)) {
|
||||
columnInfo.setColumnDefault("DEFAULT " + columnDefault);
|
||||
} else {
|
||||
columnInfo.setColumnDefault("");
|
||||
}
|
||||
String extra = columnInfo.getExtra();
|
||||
columnInfo.setExtra(StringUtils.isBlank(extra) ? "" : extra);
|
||||
baseMapper.updateTableColumnDesc(dbName, tableName, columnName, newDesc, columnInfo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.zyplayer.doc.db.service;
|
||||
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class OracleServiceImpl extends DbBaseService {
|
||||
|
||||
@Override
|
||||
DatabaseFactoryBean.DatabaseProduct getDatabaseProduct() {
|
||||
return DatabaseFactoryBean.DatabaseProduct.ORACLE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.zyplayer.doc.db.service;
|
||||
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class PostgresqlServiceImpl extends DbBaseService {
|
||||
|
||||
@Override
|
||||
DatabaseFactoryBean.DatabaseProduct getDatabaseProduct() {
|
||||
return DatabaseFactoryBean.DatabaseProduct.POSTGRESQL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.zyplayer.doc.db.service;
|
||||
|
||||
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
|
||||
import com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class SqlserverServiceImpl extends DbBaseService {
|
||||
|
||||
@Override
|
||||
DatabaseFactoryBean.DatabaseProduct getDatabaseProduct() {
|
||||
return DatabaseFactoryBean.DatabaseProduct.SQLSERVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableColumnVo getTableColumnList(Long sourceId, String dbName, String tableName) {
|
||||
TableColumnVo tableColumnVo = super.getTableColumnList(sourceId, dbName, tableName);
|
||||
// SQLSERVER 要单独查字段注释
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
List<TableColumnDescDto> columnDescList = baseMapper.getTableColumnDescList(tableName);
|
||||
Map<String, TableColumnDescDto> columnMap = tableColumnVo.getColumnList().stream().collect(Collectors.toMap(TableColumnDescDto::getName, val -> val));
|
||||
// 字段注释
|
||||
for (TableColumnDescDto descDto : columnDescList) {
|
||||
TableColumnDescDto tempDesc = columnMap.get(descDto.getName());
|
||||
if (tempDesc != null) {
|
||||
tempDesc.setDescription(descDto.getDescription());
|
||||
}
|
||||
}
|
||||
return tableColumnVo;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user