表数据导出优化,增加表关系图功能
This commit is contained in:
@@ -144,13 +144,6 @@ public class DatabaseDocController {
|
||||
return DocDbResponseJson.ok(tableColumnVo);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/getTableColumnDescList")
|
||||
public ResponseJson getTableColumnDescList(Long sourceId, String 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) {
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package com.zyplayer.doc.db.controller;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import com.alibaba.fastjson.util.TypeUtils;
|
||||
@@ -9,6 +12,7 @@ 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.core.util.StringUtil;
|
||||
import com.zyplayer.doc.core.util.ZyplayerDocVersion;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||
import com.zyplayer.doc.db.controller.param.DataViewParam;
|
||||
@@ -29,12 +33,14 @@ import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
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;
|
||||
@@ -57,6 +63,9 @@ public class DbDataViewController {
|
||||
DbBaseFactory dbBaseFactory;
|
||||
@Resource
|
||||
BaseDownloadService baseDownloadService;
|
||||
// 最大允许导出的行数,设置的过大有可能会导致内存溢出,默认10W条
|
||||
@Value("${zyplayer.doc.db.download-max-row:100000}")
|
||||
Integer downloadMaxRow;
|
||||
|
||||
@PostMapping(value = "/query")
|
||||
public ResponseJson query(DataViewParam param) {
|
||||
@@ -73,13 +82,7 @@ public class DbDataViewController {
|
||||
if (CollectionUtils.isNotEmpty(executeResult.getResult()) && Objects.equals(param.getPageNum(), 1)) {
|
||||
responseJson.setTotal((long) executeResult.getResult().size());
|
||||
if (executeResult.getResult().size() >= param.getPageSize()) {
|
||||
String queryCountSql = dbBaseService.getQueryCountSql(param);
|
||||
ExecuteResult countResult = this.query(param.getSourceId(), param.getExecuteId(), executeType, queryCountSql);
|
||||
if (CollectionUtils.isNotEmpty(countResult.getResult()) && MapUtils.isNotEmpty(countResult.getResult().get(0))) {
|
||||
Map<String, Object> countMap = countResult.getResult().get(0);
|
||||
Optional<Object> countAny = countMap.values().stream().findAny();
|
||||
countAny.ifPresent(count -> responseJson.setTotal(TypeUtils.castToLong(count)));
|
||||
}
|
||||
responseJson.setTotal(this.getDataCount(param, executeType));
|
||||
}
|
||||
}
|
||||
return responseJson;
|
||||
@@ -95,7 +98,11 @@ public class DbDataViewController {
|
||||
@PostMapping(value = "/download")
|
||||
public ResponseJson download(HttpServletResponse response, DataViewParam param) {
|
||||
param.setExecuteId(RandomUtil.simpleUUID());
|
||||
ExecuteType executeType = this.getExecuteType(param.getSourceId());
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(param.getSourceId());
|
||||
if (this.getDataCount(param, executeType) > downloadMaxRow) {
|
||||
return DocDbResponseJson.error(String.format("导出失败,表:%s 数据行数超过最大导出配置 %s,请联系管理员修改", param.getTableName(), downloadMaxRow));
|
||||
}
|
||||
// 获取列信息等
|
||||
TableColumnVo tableColumnVo = dbBaseService.getTableColumnList(param.getSourceId(), param.getDbName(), param.getTableName());
|
||||
Set<String> conditionSet = StringUtils.isBlank(param.getConditionColumn()) ? Collections.emptySet() : Stream.of(param.getConditionColumn().split(",")).collect(Collectors.toSet());
|
||||
@@ -106,10 +113,8 @@ public class DbDataViewController {
|
||||
ExecuteParam executeParam = new ExecuteParam();
|
||||
executeParam.setDatasourceId(param.getSourceId());
|
||||
executeParam.setExecuteId(param.getExecuteId());
|
||||
executeParam.setExecuteType(this.getExecuteType(param.getSourceId()));
|
||||
executeParam.setExecuteType(executeType);
|
||||
executeParam.setSql(queryAllSql);
|
||||
// 最大支持10w行数据,总得有个上限
|
||||
executeParam.setMaxRows(100000);
|
||||
try {
|
||||
dbBaseService.downloadSingleTableData(response, param, executeParam, columnList, conditionSet);
|
||||
} catch (Exception e) {
|
||||
@@ -131,45 +136,85 @@ public class DbDataViewController {
|
||||
if (StringUtils.isBlank(param.getTableNames())) {
|
||||
return DocDbResponseJson.warn("请选择导出的表");
|
||||
}
|
||||
param.setExecuteId(RandomUtil.simpleUUID());
|
||||
param.setExecuteId(IdUtil.simpleUUID());
|
||||
String tempDir = System.getProperty("java.io.tmpdir");
|
||||
boolean multipleFile = Objects.equals(param.getDownloadFileType(), 2);
|
||||
boolean isJson = Objects.equals(param.getDownloadType(), "json");
|
||||
StringBuilder resultSb = new StringBuilder("/*\n" +
|
||||
" zyplayer-doc 表数据导出\n" +
|
||||
"\n" +
|
||||
" 数据库 : " + param.getDbName() + "\n" +
|
||||
" 数据库类型 : " + dbBaseService.getDatabaseProduct().name() + "\n" +
|
||||
" 导出时间 : " + DateTime.now().toString() + "\n" +
|
||||
" 软件版本 : " + ZyplayerDocVersion.version + "\n" +
|
||||
"*/\n\n");
|
||||
String[] tableNameArr = param.getTableNames().split(",");
|
||||
String tempDirName = tempDir + "zyplayer-doc-" + IdUtil.fastSimpleUUID();
|
||||
try {
|
||||
for (String tabName : tableNameArr) {
|
||||
param.setTableName(tabName);
|
||||
// 先校验总条数是否超过限制
|
||||
for (String tableName : tableNameArr) {
|
||||
param.setTableName(tableName);
|
||||
ExecuteType executeType = this.getExecuteType(param.getSourceId());
|
||||
if (this.getDataCount(param, executeType) > downloadMaxRow) {
|
||||
return DocDbResponseJson.error(String.format("导出失败,表:%s 数据行数超过最大导出配置 %s,请联系管理员修改", tableName, downloadMaxRow));
|
||||
}
|
||||
}
|
||||
// 创建临时文件夹
|
||||
FileUtil.mkdir(tempDirName);
|
||||
// 再分表查数据
|
||||
String suffix = isJson ? ".json" : ".sql";
|
||||
for (String tableName : tableNameArr) {
|
||||
param.setTableName(tableName);
|
||||
ExecuteType executeType = this.getExecuteType(param.getSourceId());
|
||||
// 获取列信息等
|
||||
TableColumnVo tableColumnVo = dbBaseService.getTableColumnList(param.getSourceId(), param.getDbName(), tabName);
|
||||
TableColumnVo tableColumnVo = dbBaseService.getTableColumnList(param.getSourceId(), param.getDbName(), tableName);
|
||||
List<TableColumnDescDto> columnList = tableColumnVo.getColumnList();
|
||||
// 找主键作为更新条件
|
||||
Set<String> conditionSet = columnList.stream().filter(item -> Objects.equals(item.getIspramary(), "1")).map(TableColumnDescDto::getName).collect(Collectors.toSet());
|
||||
Set<String> conditionSet = columnList.stream().filter(item -> Objects.equals(item.getPrimaryKey(), "1")).map(TableColumnDescDto::getName).collect(Collectors.toSet());
|
||||
// 数据查询
|
||||
String queryAllSql = dbBaseService.getQueryAllSql(param);
|
||||
ExecuteParam executeParam = new ExecuteParam();
|
||||
executeParam.setDatasourceId(param.getSourceId());
|
||||
executeParam.setExecuteId(param.getExecuteId());
|
||||
executeParam.setExecuteType(this.getExecuteType(param.getSourceId()));
|
||||
executeParam.setExecuteType(executeType);
|
||||
executeParam.setSql(queryAllSql);
|
||||
// 最大支持10w行数据,总得有个上限
|
||||
executeParam.setMaxRows(100000);
|
||||
String downloadTableData = dbBaseService.getDownloadTableData(param, executeParam, columnList, conditionSet);
|
||||
resultSb.append(String.format("-- 导出数据表:`%s`.`%s` --\n", param.getDbName(), tabName));
|
||||
resultSb.append(downloadTableData).append("\n");
|
||||
// 写入临时文件
|
||||
if (multipleFile) {
|
||||
File tempFile = FileUtil.file(tempDirName + "/" + tableName + suffix);
|
||||
String tableDataSb = isJson ? downloadTableData : String.format("-- 导出数据表:`%s`.`%s` --\n", param.getDbName(), tableName) + downloadTableData;
|
||||
FileUtil.writeUtf8String(tableDataSb, tempFile);
|
||||
} else {
|
||||
resultSb.append(String.format("-- 导出数据表:`%s`.`%s` --\n", param.getDbName(), tableName));
|
||||
resultSb.append(downloadTableData).append("\n");
|
||||
}
|
||||
}
|
||||
if (multipleFile) {
|
||||
baseDownloadService.sendResponse(response, param.getDbName(), tempDirName);
|
||||
} else {
|
||||
baseDownloadService.sendResponse(response, param.getDbName(), suffix, resultSb.toString());
|
||||
}
|
||||
String prefix = Objects.equals(param.getDownloadType(), "json") ? ".json" : ".sql";
|
||||
baseDownloadService.sendResponse(response, param.getDbName(), prefix, resultSb.toString());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return DocDbResponseJson.error("导出失败:" + e.getMessage());
|
||||
} finally {
|
||||
FileUtil.del(tempDirName);
|
||||
}
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
|
||||
private Long getDataCount(DataViewParam param, ExecuteType executeType) {
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(param.getSourceId());
|
||||
String queryCountSql = dbBaseService.getQueryCountSql(param);
|
||||
ExecuteResult countResult = this.query(param.getSourceId(), param.getExecuteId(), executeType, queryCountSql);
|
||||
if (CollectionUtils.isNotEmpty(countResult.getResult()) && MapUtils.isNotEmpty(countResult.getResult().get(0))) {
|
||||
Map<String, Object> countMap = countResult.getResult().get(0);
|
||||
Optional<Object> countAny = countMap.values().stream().findAny();
|
||||
return TypeUtils.castToLong(countAny.orElse(0));
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行数据查询
|
||||
*
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.zyplayer.doc.db.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.json.ResponseJson;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.DbTableRelation;
|
||||
import com.zyplayer.doc.data.repository.manage.param.TableRelationParam;
|
||||
import com.zyplayer.doc.data.repository.manage.vo.TableRelationVo;
|
||||
import com.zyplayer.doc.data.service.manage.DbTableRelationService;
|
||||
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
|
||||
import com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto;
|
||||
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
|
||||
import com.zyplayer.doc.db.service.DbBaseFactory;
|
||||
import com.zyplayer.doc.db.service.DbBaseService;
|
||||
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.*;
|
||||
|
||||
/**
|
||||
* 表关系控制器
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2021年6月6日
|
||||
*/
|
||||
@AuthMan
|
||||
@RestController
|
||||
@RequestMapping("/zyplayer-doc-db/table-relation")
|
||||
public class DbTableRelationController {
|
||||
private static Logger logger = LoggerFactory.getLogger(DbTableRelationController.class);
|
||||
|
||||
@Resource
|
||||
DbBaseFactory dbBaseFactory;
|
||||
@Resource
|
||||
DbTableRelationService dbTableRelationService;
|
||||
|
||||
@PostMapping(value = "/update")
|
||||
public ResponseJson update(TableRelationParam param) {
|
||||
dbTableRelationService.update(param);
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
|
||||
@PostMapping(value = "/getRelation")
|
||||
public ResponseJson getRelation(TableRelationParam param) {
|
||||
TableRelationVo relationVo = new TableRelationVo();
|
||||
relationVo.setDbName(param.getDbName());
|
||||
relationVo.setName(param.getTableName());
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(param.getSourceId());
|
||||
TableColumnVo tableColumn = dbBaseService.getTableColumnList(param.getSourceId(), param.getDbName(), param.getTableName());
|
||||
if (CollectionUtils.isNotEmpty(tableColumn.getColumnList())) {
|
||||
Set<String> drillPath = new HashSet<>();
|
||||
List<TableRelationVo> childrenRelationList = new LinkedList<>();
|
||||
for (TableColumnDescDto columnDto : tableColumn.getColumnList()) {
|
||||
drillPath.add(param.getDbName() + "." + param.getTableName() + "." + columnDto.getName());
|
||||
TableRelationVo relationVoChildren = new TableRelationVo();
|
||||
relationVoChildren.setNodeType(1);
|
||||
relationVoChildren.setDbName(param.getDbName());
|
||||
relationVoChildren.setTableName(param.getTableName());
|
||||
relationVoChildren.setName(columnDto.getName());
|
||||
relationVoChildren.setColumnName(columnDto.getName());
|
||||
relationVoChildren.setChildren(this.getRelation(param.getSourceId(), param.getDbName(), param.getTableName(), columnDto.getName(), drillPath,1));
|
||||
childrenRelationList.add(relationVoChildren);
|
||||
}
|
||||
relationVo.setChildren(childrenRelationList);
|
||||
}
|
||||
return DocDbResponseJson.ok(relationVo);
|
||||
}
|
||||
|
||||
public List<TableRelationVo> getRelation(Long sourceId, String dbName, String tableName, String columnName, Set<String> drillPath, int recursion) {
|
||||
// 最大支持5层关系链展示
|
||||
if (recursion >= 5) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
QueryWrapper<DbTableRelation> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("datasource_id", sourceId);
|
||||
queryWrapper.and(wrapper -> wrapper.or(or -> or.eq("start_db_name", dbName)
|
||||
.eq("start_table_name", tableName)
|
||||
.eq("start_column_name", columnName)
|
||||
).or(or -> or.eq("end_db_name", dbName)
|
||||
.eq("end_table_name", tableName)
|
||||
.eq("end_column_name", columnName)
|
||||
));
|
||||
List<TableRelationVo> resultRelationList = new LinkedList<>();
|
||||
List<DbTableRelation> relationList = dbTableRelationService.list(queryWrapper);
|
||||
if (CollectionUtils.isEmpty(relationList)) {
|
||||
return resultRelationList;
|
||||
}
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
for (DbTableRelation tableRelation : relationList) {
|
||||
String endDbName = tableRelation.getStartDbName();
|
||||
String endTableName = tableRelation.getStartTableName();
|
||||
String endColumnName = tableRelation.getStartColumnName();
|
||||
if (Objects.equals(tableRelation.getStartDbName(), dbName)
|
||||
&& Objects.equals(tableRelation.getStartTableName(), tableName)
|
||||
&& Objects.equals(tableRelation.getStartColumnName(), columnName)) {
|
||||
endDbName = tableRelation.getEndDbName();
|
||||
endTableName = tableRelation.getEndTableName();
|
||||
endColumnName = tableRelation.getEndColumnName();
|
||||
}
|
||||
if (drillPath.contains(endDbName + "." + endTableName + "." + endColumnName)) {
|
||||
continue;
|
||||
}
|
||||
drillPath.add(endDbName + "." + endTableName + "." + endColumnName);
|
||||
TableRelationVo relationVo = new TableRelationVo();
|
||||
relationVo.setDbName(endDbName);
|
||||
relationVo.setTableName(endTableName);
|
||||
relationVo.setName("表:"+endTableName + "\n列:" + endColumnName);
|
||||
relationVo.setColumnName(endColumnName);
|
||||
TableColumnVo tableColumn = dbBaseService.getTableColumnList(sourceId, endDbName, endTableName);
|
||||
if (CollectionUtils.isNotEmpty(tableColumn.getColumnList())) {
|
||||
List<TableRelationVo> childrenRelationList = new LinkedList<>();
|
||||
for (TableColumnDescDto columnDto : tableColumn.getColumnList()) {
|
||||
TableRelationVo relationVoChildren = new TableRelationVo();
|
||||
relationVoChildren.setNodeType(1);
|
||||
relationVoChildren.setDbName(endDbName);
|
||||
relationVoChildren.setTableName(endTableName);
|
||||
relationVoChildren.setName(columnDto.getName());
|
||||
relationVoChildren.setColumnName(columnDto.getName());
|
||||
relationVoChildren.setChildren(this.getRelation(sourceId, endDbName, endTableName, columnDto.getName(), drillPath, recursion + 1));
|
||||
childrenRelationList.add(relationVoChildren);
|
||||
}
|
||||
relationVo.setChildren(childrenRelationList);
|
||||
}
|
||||
resultRelationList.add(relationVo);
|
||||
}
|
||||
return resultRelationList;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ public class DataViewParam {
|
||||
private String conditionColumn;
|
||||
private Integer dropTableFlag;
|
||||
private Integer createTableFlag;
|
||||
private Integer downloadFileType;
|
||||
|
||||
public Integer getOffset() {
|
||||
return ((this.pageNum - 1) * this.pageSize);
|
||||
@@ -141,4 +142,12 @@ public class DataViewParam {
|
||||
public void setTableNames(String tableNames) {
|
||||
this.tableNames = tableNames;
|
||||
}
|
||||
|
||||
public Integer getDownloadFileType() {
|
||||
return downloadFileType;
|
||||
}
|
||||
|
||||
public void setDownloadFileType(Integer downloadFileType) {
|
||||
this.downloadFileType = downloadFileType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ public class TableColumnDescDto {
|
||||
|
||||
@ColumnWidth(15)
|
||||
@ExcelProperty("是否自增")
|
||||
private String isidenity;
|
||||
private String selfIncrement;
|
||||
|
||||
@ColumnWidth(20)
|
||||
@ExcelProperty("类型")
|
||||
@@ -34,7 +34,7 @@ public class TableColumnDescDto {
|
||||
|
||||
@ColumnWidth(10)
|
||||
@ExcelProperty("主键")
|
||||
private String ispramary;
|
||||
private String primaryKey;
|
||||
|
||||
@ColumnWidth(80)
|
||||
@ExcelProperty("注释")
|
||||
@@ -48,14 +48,6 @@ public class TableColumnDescDto {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getIsidenity() {
|
||||
return isidenity;
|
||||
}
|
||||
|
||||
public void setIsidenity(String isidenity) {
|
||||
this.isidenity = isidenity;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
@@ -80,14 +72,6 @@ public class TableColumnDescDto {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public String getIspramary() {
|
||||
return ispramary;
|
||||
}
|
||||
|
||||
public void setIspramary(String ispramary) {
|
||||
this.ispramary = ispramary;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
@@ -111,4 +95,20 @@ public class TableColumnDescDto {
|
||||
public void setNumericScale(String numericScale) {
|
||||
this.numericScale = numericScale;
|
||||
}
|
||||
|
||||
public String getSelfIncrement() {
|
||||
return selfIncrement;
|
||||
}
|
||||
|
||||
public void setSelfIncrement(String selfIncrement) {
|
||||
this.selfIncrement = selfIncrement;
|
||||
}
|
||||
|
||||
public String getPrimaryKey() {
|
||||
return primaryKey;
|
||||
}
|
||||
|
||||
public void setPrimaryKey(String primaryKey) {
|
||||
this.primaryKey = primaryKey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,16 +55,6 @@ public interface BaseMapper {
|
||||
*/
|
||||
List<TableColumnDescDto> getTableColumnList(@Param("dbName") String dbName, @Param("tableName") String tableName);
|
||||
|
||||
/**
|
||||
* 获取字段注释
|
||||
*
|
||||
* @param tableName 表名
|
||||
* @return 表字段注释
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月8日
|
||||
*/
|
||||
List<TableColumnDescDto> getTableColumnDescList(@Param("tableName") String tableName);
|
||||
|
||||
/**
|
||||
* 模糊搜索表和字段
|
||||
*
|
||||
|
||||
@@ -2,51 +2,8 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper">
|
||||
|
||||
<resultMap id="TableColumnDescDtoMap" type="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto" >
|
||||
<result column="TABLE_NAME" property="tableName" jdbcType="VARCHAR" />
|
||||
<result column="NAME" property="name" jdbcType="VARCHAR" />
|
||||
<result column="ISIDENITY" property="isidenity" jdbcType="VARCHAR" />
|
||||
<result column="TYPE" property="type" jdbcType="VARCHAR" />
|
||||
<result column="NULLABLE" property="nullable" jdbcType="VARCHAR" />
|
||||
<result column="LENGTH" property="length" jdbcType="VARCHAR" />
|
||||
<result column="NUMERIC_SCALE" property="numericScale" jdbcType="VARCHAR" />
|
||||
<result column="ISPRAMARY" property="ispramary" jdbcType="VARCHAR" />
|
||||
<result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="QueryTableColumnDescDtoMap" type="com.zyplayer.doc.db.framework.db.dto.QueryTableColumnDescDto" >
|
||||
<result column="TABLE_NAME" property="tableName" jdbcType="VARCHAR" />
|
||||
<result column="COLUMN_NAME" property="columnName" jdbcType="VARCHAR" />
|
||||
<result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="TableStatusDtoMap" type="com.zyplayer.doc.db.controller.vo.TableStatusVo">
|
||||
<result column="Name" property="name"/>
|
||||
<result column="Engine" property="engine"/>
|
||||
<result column="Version" property="version"/>
|
||||
<result column="Row_format" property="rowFormat"/>
|
||||
<result column="Rows" property="rows"/>
|
||||
<result column="Avg_row_length" property="avgRowLength"/>
|
||||
<result column="Data_length" property="dataLength"/>
|
||||
<result column="Max_data_length" property="maxDataLength"/>
|
||||
<result column="Index_length" property="indexLength"/>
|
||||
<result column="Data_free" property="dataFree"/>
|
||||
<result column="Auto_increment" property="autoIncrement"/>
|
||||
<result column="Create_time" property="createTime"/>
|
||||
<result column="Update_time" property="updateTime"/>
|
||||
<result column="Check_time" property="checkTime"/>
|
||||
<result column="Collation" property="collation"/>
|
||||
<result column="Checksum" property="checksum"/>
|
||||
<result column="Create_options" property="createOptions"/>
|
||||
<result column="Comment" property="comment"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="getDatabaseList" resultType="com.zyplayer.doc.db.framework.db.dto.DatabaseInfoDto">
|
||||
select TABLE_SCHEMA dbName
|
||||
from `information_schema`.tables
|
||||
<!--排除系统库-->
|
||||
where TABLE_SCHEMA != 'information_schema'
|
||||
group by TABLE_SCHEMA
|
||||
select SCHEMA_NAME dbName from `information_schema`.SCHEMATA
|
||||
</select>
|
||||
|
||||
<select id="getTableDdl" resultType="java.util.Map">
|
||||
@@ -59,27 +16,35 @@
|
||||
<if test="dbName != null">where table_schema=#{dbName}</if>
|
||||
</select>
|
||||
|
||||
<select id="getTableColumnList" resultMap="TableColumnDescDtoMap">
|
||||
SELECT table_name as TABLE_NAME,COLUMN_NAME as NAME,column_comment DESCRIPTION,data_type TYPE,
|
||||
COALESCE(CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION) as `LENGTH`,NUMERIC_SCALE as NUMERIC_SCALE,
|
||||
if(COLUMN_KEY='PRI','1','0') as ISPRAMARY,
|
||||
if(is_nullable='YES','1','0') NULLABLE
|
||||
<select id="getTableColumnList" resultType="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto">
|
||||
SELECT table_name as tableName,COLUMN_NAME as name,column_comment description,data_type type,
|
||||
COALESCE(CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION) as `length`,NUMERIC_SCALE as numericScale,
|
||||
if(COLUMN_KEY='PRI','1','0') as primaryKey,
|
||||
if(is_nullable='YES','1','0') nullable
|
||||
FROM `INFORMATION_SCHEMA`.Columns
|
||||
WHERE table_schema=#{dbName}
|
||||
<if test="tableName != null">and table_name=#{tableName}</if>
|
||||
ORDER BY ordinal_position
|
||||
</select>
|
||||
|
||||
<select id="getTableStatus" resultMap="TableStatusDtoMap">
|
||||
show table status from `${dbName}` like #{tableName}
|
||||
<select id="getTableStatus" resultType="com.zyplayer.doc.db.controller.vo.TableStatusVo">
|
||||
<!-- show table status from `${dbName}` like #{tableName} -->
|
||||
select TABLE_NAME as name, ENGINE as engine, VERSION as version, ROW_FORMAT as rowFormat,
|
||||
TABLE_ROWS as `rows`, AVG_ROW_LENGTH as avgRowLength, DATA_LENGTH as dataLength,
|
||||
MAX_DATA_LENGTH as maxDataLength, INDEX_LENGTH as indexLength, DATA_FREE as dataFree,
|
||||
AUTO_INCREMENT as autoIncrement, CREATE_TIME as createTime, UPDATE_TIME as updateTime,
|
||||
CHECK_TIME as checkTime, TABLE_COLLATION as `collation`, CHECKSUM as checksum,
|
||||
CREATE_OPTIONS as createOptions, TABLE_COMMENT as comment
|
||||
from `information_schema`.tables
|
||||
where table_schema=#{dbName} and table_name=#{tableName}
|
||||
</select>
|
||||
|
||||
<select id="getTableColumnDescList" resultMap="TableColumnDescDtoMap">
|
||||
<select id="getTableColumnDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto">
|
||||
select 1
|
||||
</select>
|
||||
|
||||
<select id="getTableAndColumnBySearch" resultMap="QueryTableColumnDescDtoMap">
|
||||
SELECT TABLE_NAME, COLUMN_NAME, column_comment DESCRIPTION
|
||||
<select id="getTableAndColumnBySearch" resultType="com.zyplayer.doc.db.framework.db.dto.QueryTableColumnDescDto">
|
||||
SELECT TABLE_NAME as tableName, column_name as columnName, column_comment as description
|
||||
FROM `INFORMATION_SCHEMA`.Columns
|
||||
WHERE table_schema=#{dbName} AND (COLUMN_NAME like #{searchText} or column_comment like #{searchText})
|
||||
</select>
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
<resultMap id="TableColumnDescDtoMap" type="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto">
|
||||
<result column="TABLE_NAME" property="tableName" jdbcType="VARCHAR"/>
|
||||
<result column="NAME" property="name" jdbcType="VARCHAR"/>
|
||||
<result column="ISIDENITY" property="isidenity" jdbcType="VARCHAR"/>
|
||||
<result column="ISIDENITY" property="selfIncrement" jdbcType="VARCHAR"/>
|
||||
<result column="TYPE" property="type" jdbcType="VARCHAR"/>
|
||||
<result column="NULLABLE" property="nullable" jdbcType="VARCHAR"/>
|
||||
<result column="LENGTH" property="length" jdbcType="VARCHAR"/>
|
||||
<result column="ISPRAMARY" property="ispramary" jdbcType="VARCHAR"/>
|
||||
<result column="ISPRAMARY" property="primaryKey" jdbcType="VARCHAR"/>
|
||||
<result column="DESCRIPTION" property="description" jdbcType="VARCHAR"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
<resultMap id="TableColumnDescDtoMap" type="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto" >
|
||||
<result column="NAME" property="name" jdbcType="VARCHAR" />
|
||||
<result column="ISIDENITY" property="isidenity" jdbcType="VARCHAR" />
|
||||
<result column="ISIDENITY" property="selfIncrement" jdbcType="VARCHAR" />
|
||||
<result column="TYPE" property="type" jdbcType="VARCHAR" />
|
||||
<result column="NULLABLE" property="nullable" jdbcType="VARCHAR" />
|
||||
<result column="LENGTH" property="length" jdbcType="VARCHAR" />
|
||||
<result column="ISPRAMARY" property="ispramary" jdbcType="VARCHAR" />
|
||||
<result column="ISPRAMARY" property="primaryKey" jdbcType="VARCHAR" />
|
||||
<result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />
|
||||
</resultMap>
|
||||
|
||||
@@ -53,14 +53,6 @@
|
||||
WHERE SYSCOLUMNS.ID = OBJECT_ID(#{tableName})
|
||||
</select>
|
||||
|
||||
<select id="getTableColumnDescList" resultMap="TableColumnDescDtoMap">
|
||||
SELECT B.name AS NAME,C.value AS DESCRIPTION
|
||||
FROM sys.tables A
|
||||
INNER JOIN sys.columns B ON B.object_id = A.object_id
|
||||
LEFT JOIN sys.extended_properties C ON C.major_id = B.object_id AND C.minor_id = B.column_id
|
||||
WHERE A.name = #{tableName}
|
||||
</select>
|
||||
|
||||
<select id="getTableAndColumnBySearch" resultMap="QueryTableColumnDescDtoMap">
|
||||
SELECT top 500
|
||||
A.name AS TABLE_NAME,B.name AS COLUMN_NAME,C.value AS DESCRIPTION
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
package com.zyplayer.doc.db.framework.db.mapper.sqlserver;
|
||||
|
||||
import com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* sqlserver数据库的mapper持有对象
|
||||
*
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月8日
|
||||
*/
|
||||
public interface SqlServerMapper {
|
||||
|
||||
|
||||
/**
|
||||
* 获取字段注释
|
||||
*
|
||||
* @param tableName 表名
|
||||
* @return 表字段注释
|
||||
* @author 暮光:城中城
|
||||
* @since 2018年8月8日
|
||||
*/
|
||||
List<TableColumnDescDto> getTableColumnDescList(@Param("tableName") String tableName);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper">
|
||||
|
||||
<select id="getTableColumnDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto">
|
||||
SELECT B.name AS name,C.value AS description
|
||||
FROM sys.tables A
|
||||
INNER JOIN sys.columns B ON B.object_id = A.object_id
|
||||
LEFT JOIN sys.extended_properties C ON C.major_id = B.object_id AND C.minor_id = B.column_id
|
||||
WHERE A.name = #{tableName}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.ExcelWriter;
|
||||
import com.alibaba.excel.write.metadata.WriteSheet;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.zyplayer.doc.core.util.ZyplayerDocVersion;
|
||||
import com.zyplayer.doc.db.controller.vo.DatabaseExportVo;
|
||||
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
|
||||
import com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto;
|
||||
@@ -47,6 +48,7 @@ public class PoiUtil {
|
||||
" 数据库 : " + dbName + "\n" +
|
||||
" 数据库类型 : " + dbType + "\n" +
|
||||
" 导出时间 : " + DateTime.now().toString() + "\n" +
|
||||
" 软件版本 : " + ZyplayerDocVersion.version + "\n" +
|
||||
"*/\n\n");
|
||||
for (Map.Entry<String, String> entry : ddlSqlMap.entrySet()) {
|
||||
ddlSqlSb.append("-- ----------------------------\n")
|
||||
@@ -145,8 +147,8 @@ public class PoiUtil {
|
||||
// 写入表格
|
||||
for (TableColumnDescDto dto : tableColumnDescDtos) {
|
||||
String nullable = Objects.equals(dto.getNullable(), "1") ? "允许" : "不允许";
|
||||
dataList.add(Arrays.asList(dto.getName(), dto.getIsidenity(), dto.getType(), nullable, dto.getLength(),
|
||||
dto.getNumericScale(), dto.getIspramary(), dto.getDescription()));
|
||||
dataList.add(Arrays.asList(dto.getName(), dto.getSelfIncrement(), dto.getType(), nullable, dto.getLength(),
|
||||
dto.getNumericScale(), dto.getPrimaryKey(), dto.getDescription()));
|
||||
}
|
||||
PoiUtil.createTable(document, dataList);
|
||||
}
|
||||
|
||||
@@ -144,19 +144,6 @@ public abstract class DbBaseService {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模糊搜索表和字段
|
||||
*
|
||||
|
||||
@@ -52,11 +52,6 @@ public class HiveServiceImpl extends DbBaseService {
|
||||
return tableDdlVo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TableColumnDescDto> getTableColumnDescList(Long sourceId, String tableName) {
|
||||
throw new ConfirmException("不支持的操作");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QueryTableColumnDescDto> getTableAndColumnBySearch(Long sourceId, String dbName, String searchText) {
|
||||
throw new ConfirmException("不支持的操作");
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.zyplayer.doc.db.service;
|
||||
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
|
||||
import com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto;
|
||||
import com.zyplayer.doc.db.framework.db.enums.DatabaseProductEnum;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.sqlserver.SqlServerMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
@@ -22,8 +22,8 @@ public class SqlserverServiceImpl extends DbBaseService {
|
||||
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);
|
||||
SqlServerMapper sqlServerMapper = databaseRegistrationBean.getBaseMapper(sourceId, SqlServerMapper.class);
|
||||
List<TableColumnDescDto> columnDescList = sqlServerMapper.getTableColumnDescList(tableName);
|
||||
Map<String, TableColumnDescDto> columnMap = tableColumnVo.getColumnList().stream().collect(Collectors.toMap(TableColumnDescDto::getName, val -> val));
|
||||
// 字段注释
|
||||
for (TableColumnDescDto descDto : columnDescList) {
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
package com.zyplayer.doc.db.service.download;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.zyplayer.doc.db.controller.param.DataViewParam;
|
||||
import com.zyplayer.doc.db.controller.vo.TableDdlVo;
|
||||
@@ -10,10 +14,13 @@ import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteParam;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.SqlExecutor;
|
||||
import com.zyplayer.doc.db.service.DbBaseFactory;
|
||||
import com.zyplayer.doc.db.service.DbBaseService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -25,6 +32,7 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
@Service
|
||||
public class BaseDownloadService {
|
||||
private static Logger logger = LoggerFactory.getLogger(BaseDownloadService.class);
|
||||
|
||||
@Resource
|
||||
SqlExecutor sqlExecutor;
|
||||
@@ -141,10 +149,13 @@ public class BaseDownloadService {
|
||||
}
|
||||
resultSb.append(resultData);
|
||||
});
|
||||
resultSb.append("]");
|
||||
resultSb.append("]\n");
|
||||
return resultSb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送字符串到response
|
||||
*/
|
||||
public void sendResponse(HttpServletResponse response, String tableName, String prefix, String dataStr) throws Exception {
|
||||
String fileNameOrigin = tableName + "." + DateTime.now().toString("yyyyMMddHHmmss");
|
||||
String fileName = URLEncoder.encode(fileNameOrigin, "UTF-8") + prefix;
|
||||
@@ -154,6 +165,31 @@ public class BaseDownloadService {
|
||||
IoUtil.write(response.getOutputStream(), "utf-8", true, dataStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 把文件夹压缩为zip后发送
|
||||
*/
|
||||
public void sendResponse(HttpServletResponse response, String tableName, String tempDirName) throws Exception {
|
||||
File zipTempFile = File.createTempFile("zyplayer-doc-" + IdUtil.fastSimpleUUID(), ".zip");
|
||||
ZipUtil.zip(zipTempFile, CharsetUtil.defaultCharset(), false, FileUtil.file(tempDirName));
|
||||
String fileNameOrigin = tableName + "." + DateTime.now().toString("yyyyMMddHHmmss");
|
||||
String fileName = URLEncoder.encode(fileNameOrigin, "UTF-8") + ".zip";
|
||||
response.setContentType("application/octet-stream");
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + fileName);
|
||||
response.setCharacterEncoding("utf-8");
|
||||
try {
|
||||
IoUtil.write(response.getOutputStream(), true, FileUtil.readBytes(zipTempFile));
|
||||
} catch (Exception e) {
|
||||
logger.error("发送数据流失败", e);
|
||||
} finally {
|
||||
// 删除临时文件
|
||||
try {
|
||||
zipTempFile.delete();
|
||||
} catch (Exception e) {
|
||||
logger.error("删除临时ZIP文件失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是数值类型
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user