表数据导出优化,增加表关系图功能

This commit is contained in:
暮光:城中城
2021-06-08 23:04:15 +08:00
parent dcbb2b4ac8
commit 1d5e0e2bf1
42 changed files with 977 additions and 316 deletions

View File

@@ -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)) {

View File

@@ -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;
}
/**
* 执行数据查询
*

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
/**
* 模糊搜索表和字段
*

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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);
}
/**
* 模糊搜索表和字段
*

View File

@@ -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("不支持的操作");

View File

@@ -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) {

View File

@@ -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);
}
}
}
/**
* 是否是数值类型
*