优化SQL编辑器引入方式,优化自动提示,优化sqlserver表、字段注释获取和更新方式,数据查询时改为需指定数据库,便于库表检索提示

This commit is contained in:
暮光:城中城
2021-06-20 00:41:28 +08:00
parent da9146f75f
commit a30d9318da
23 changed files with 745 additions and 350 deletions

View File

@@ -83,12 +83,14 @@ public class DatabaseDocController {
}
/**
* 不再使用此接口,优化了
* 获取编辑器所需的所有信息,用于自动补全
* 此接口会返回所有库表结构,介意的话请自己手动屏蔽调此接口
*
* @param sourceId
* @return
*/
@Deprecated
@PostMapping(value = "/getEditorData")
public ResponseJson getEditorData(Long sourceId) {
// 没权限,返回空

View File

@@ -20,6 +20,8 @@ import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteType;
import com.zyplayer.doc.db.framework.db.mapper.base.SqlExecutor;
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
import com.zyplayer.doc.db.framework.utils.JSONUtil;
import com.zyplayer.doc.db.service.DatabaseServiceFactory;
import com.zyplayer.doc.db.service.DbBaseService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,9 +53,11 @@ public class DbSqlExecutorController {
DbHistoryService dbHistoryService;
@Resource
DbFavoriteService dbFavoriteService;
@Resource
DatabaseServiceFactory databaseServiceFactory;
@PostMapping(value = "/execute")
public ResponseJson execute(Long sourceId, String executeId, String sql, String params) {
public ResponseJson execute(Long sourceId, String executeId, String dbName, String sql, String params) {
if (StringUtils.isBlank(sql)) {
return DocDbResponseJson.warn("执行的SQL不能为空");
}
@@ -63,6 +67,8 @@ public class DbSqlExecutorController {
if (!manageAuth && !select && !update) {
return DocDbResponseJson.warn("没有该数据源的执行权限");
}
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(sourceId);
String useDbSql = dbBaseService.getUseDbSql(dbName);
// 保留历史记录
dbHistoryService.saveHistory(sql.trim(), sourceId);
List<String> resultList = new LinkedList<>();
@@ -80,13 +86,14 @@ public class DbSqlExecutorController {
executeParam.setExecuteId(executeId);
executeParam.setExecuteType(executeType);
executeParam.setSql(sqlItem);
executeParam.setPrefixSql(useDbSql);
executeParam.setMaxRows(1000);
ExecuteResult executeResult = sqlExecutor.execute(executeParam);
String resultJsonStr = JSON.toJSONString(executeResult, JSONUtil.serializeConfig, SerializerFeature.WriteMapNullValue);
resultList.add(resultJsonStr);
} catch (Exception e) {
logger.error("执行出错", e);
ExecuteResult executeResult = ExecuteResult.error(StringUtil.getException(e), sqlItem);
ExecuteResult executeResult = ExecuteResult.error(e.getMessage(), sqlItem);
resultList.add(JSON.toJSONString(executeResult));
}
}

View File

@@ -17,8 +17,12 @@ public class ExecuteParam {
private Long datasourceId;
private Integer maxRows;
private String executeId;
private String prefixSql;
private ExecuteType executeType;
public ExecuteParam() {
}
public Long getDatasourceId() {
return datasourceId;
}
@@ -74,4 +78,12 @@ public class ExecuteParam {
public void setMaxRows(Integer maxRows) {
this.maxRows = maxRows;
}
public String getPrefixSql() {
return prefixSql;
}
public void setPrefixSql(String prefixSql) {
this.prefixSql = prefixSql;
}
}

View File

@@ -2,10 +2,12 @@ package com.zyplayer.doc.db.framework.db.mapper.base;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.zyplayer.doc.core.util.StringUtil;
import com.zyplayer.doc.data.service.manage.DbHistoryService;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.builder.SqlSourceBuilder;
import org.apache.ibatis.builder.StaticSqlSource;
import org.apache.ibatis.mapping.BoundSql;
@@ -93,16 +95,23 @@ public class SqlExecutor {
// String sqlStr = SqlLogUtil.getSqlString(paramMap, boundSql);
// 有参数的时候不输出日志,暂时只有导数据才有参数
if (CollectionUtils.isEmpty(executeParam.getParamList())) {
if (StringUtils.isNotBlank(executeParam.getPrefixSql())) {
logger.info("prefix sql ==> {}", executeParam.getPrefixSql());
}
logger.info("sql ==> {}", executeParam.getSql());
}
// List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
PreparedStatement preparedStatement = null;
PreparedStatement prefixStatement = null;
DruidPooledConnection connection = null;
// 执行查询
try {
long startTime = System.currentTimeMillis();
connection = factoryBean.getDataSource().getConnection();
if (StringUtils.isNotBlank(executeParam.getPrefixSql())) {
prefixStatement = connection.prepareStatement(executeParam.getPrefixSql());
prefixStatement.execute();
}
preparedStatement = connection.prepareStatement(executeParam.getSql());
// 设置当前的PreparedStatement
statementMap.put(executeParam.getExecuteId(), preparedStatement);
@@ -150,6 +159,13 @@ public class SqlExecutor {
throw new RuntimeException(e);
} finally {
statementMap.remove(executeParam.getExecuteId());
try {
if (prefixStatement != null && !prefixStatement.isClosed()) {
prefixStatement.close();
}
} catch (Exception e) {
logger.error("关闭Statement失败");
}
try {
if (preparedStatement != null && !preparedStatement.isClosed()) {
preparedStatement.close();

View File

@@ -35,37 +35,37 @@
WITH PRIMARYINFO( COLUMNNAME ,ISPRAMARY) AS
(
SELECT C.NAME,'true' AS COLUMNNAME
FROM SYSINDEXES I
JOIN SYSINDEXKEYS K ON I.ID = K.ID AND I.INDID = K.INDID
JOIN SYSOBJECTS O ON I.ID = O.ID
JOIN SYSCOLUMNS C ON I.ID=C.ID AND K.COLID = C.COLID
FROM ${dbName}..SYSINDEXES I
JOIN ${dbName}..SYSINDEXKEYS K ON I.ID = K.ID AND I.INDID = K.INDID
JOIN ${dbName}..SYSOBJECTS O ON I.ID = O.ID
JOIN ${dbName}..SYSCOLUMNS C ON I.ID=C.ID AND K.COLID = C.COLID
WHERE O.XTYPE = 'U'
AND EXISTS(SELECT 1 FROM SYSOBJECTS WHERE XTYPE = 'PK' AND NAME = I.NAME)
AND EXISTS(SELECT 1 FROM ${dbName}..SYSOBJECTS WHERE XTYPE = 'PK' AND NAME = I.NAME)
AND O.NAME=#{tableName}
)
SELECT (
SELECT IS_IDENTITY FROM SYS.ALL_COLUMNS
WHERE SYS.ALL_COLUMNS.NAME=SYSCOLUMNS.NAME AND OBJECT_ID = OBJECT_ID(#{tableName})
SELECT IS_IDENTITY FROM ${dbName}.SYS.ALL_COLUMNS
WHERE ${dbName}.SYS.ALL_COLUMNS.NAME=SYSCOLUMNS.NAME AND OBJECT_ID = OBJECT_ID('${dbName}..${tableName}')
) selfIncrement, SYSCOLUMNS.NAME name,SYSTYPES.NAME type,Iif(SYSCOLUMNS.ISNULLABLE=1,'1','0') nullable,
SYSCOLUMNS.LENGTH length,PRIMARYINFO.ISPRAMARY primaryKey
FROM SYSCOLUMNS
FROM ${dbName}..SYSCOLUMNS
LEFT JOIN PRIMARYINFO ON PRIMARYINFO.COLUMNNAME=NAME
LEFT JOIN SYSTYPES ON SYSCOLUMNS.XUSERTYPE = SYSTYPES.XUSERTYPE
WHERE SYSCOLUMNS.ID = OBJECT_ID(#{tableName})
LEFT JOIN ${dbName}..SYSTYPES ON SYSCOLUMNS.XUSERTYPE = SYSTYPES.XUSERTYPE
WHERE SYSCOLUMNS.ID = OBJECT_ID('${dbName}..${tableName}')
</select>
<select id="getTableAndColumnBySearch" resultMap="QueryTableColumnDescDtoMap">
SELECT top 500
A.name AS TABLE_NAME,B.name AS COLUMN_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
FROM ${dbName}.sys.tables A
INNER JOIN ${dbName}.sys.columns B ON B.object_id = A.object_id
LEFT JOIN ${dbName}.sys.extended_properties C ON C.major_id = B.object_id AND C.minor_id = B.column_id
WHERE convert(nvarchar(max),C.value) like #{searchText} OR B.name like #{searchText}
</select>
<select id="getTableDescList" resultType="com.zyplayer.doc.db.framework.db.dto.TableDescDto">
select 'TABLEDESC_SYS' as tableName, value as description, major_id as majorId
from sys.extended_properties
from ${dbName}.sys.extended_properties
WHERE minor_id=0
<if test="tableName != null">
and major_id=object_id(#{tableName})
@@ -73,24 +73,24 @@
</select>
<insert id="updateTableDesc">
IF ((SELECT COUNT(*) from fn_listextendedproperty('MS_Description', 'SCHEMA', 'dbo', 'TABLE', #{tableName}, NULL, NULL)) > 0)
EXEC sp_updateextendedproperty @name = 'MS_Description', @value = #{newDesc}
IF ((SELECT COUNT(*) from ${dbName}..fn_listextendedproperty('MS_Description', 'SCHEMA', 'dbo', 'TABLE', #{tableName}, NULL, NULL)) > 0)
EXEC ${dbName}..sp_updateextendedproperty @name = 'MS_Description', @value = #{newDesc}
, @level0type = 'SCHEMA', @level0name = 'dbo'
, @level1type = 'TABLE', @level1name = #{tableName}
ELSE
EXEC sp_addextendedproperty @name = 'MS_Description', @value = #{newDesc}
EXEC ${dbName}..sp_addextendedproperty @name = 'MS_Description', @value = #{newDesc}
, @level0type = 'SCHEMA', @level0name = 'dbo'
, @level1type = 'TABLE', @level1name = #{tableName}
</insert>
<insert id="updateTableColumnDesc">
IF ((SELECT COUNT(*) from fn_listextendedproperty('MS_Description', 'SCHEMA', 'dbo', 'TABLE', #{tableName}, 'COLUMN', #{columnName})) > 0)
EXEC sp_updateextendedproperty @name = 'MS_Description', @value = #{newDesc}
IF ((SELECT COUNT(*) from ${dbName}..fn_listextendedproperty('MS_Description', 'SCHEMA', 'dbo', 'TABLE', #{tableName}, 'COLUMN', #{columnName})) > 0)
EXEC ${dbName}..sp_updateextendedproperty @name = 'MS_Description', @value = #{newDesc}
, @level0type = 'SCHEMA', @level0name = 'dbo'
, @level1type = 'TABLE', @level1name = #{tableName}
, @level2type = 'COLUMN', @level2name = #{columnName}
ELSE
EXEC sp_addextendedproperty @name = 'MS_Description', @value = #{newDesc}
EXEC ${dbName}..sp_addextendedproperty @name = 'MS_Description', @value = #{newDesc}
, @level0type = 'SCHEMA', @level0name = 'dbo'
, @level1type = 'TABLE', @level1name = #{tableName}
, @level2type = 'COLUMN', @level2name = #{columnName}

View File

@@ -370,6 +370,20 @@ public abstract class DbBaseService {
return sqlSb.toString();
}
/**
* 获取指定数据库的SQL
*
* @return use db
* @author 暮光:城中城
* @since 2020年4月24日
*/
public String getUseDbSql(String dbName) {
if (StringUtils.isNotBlank(dbName)) {
return "use " + dbName;
}
return null;
}
/**
* 获取查询总条数的SQL
*

View File

@@ -1 +1 @@
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=favicon-db.png><title>数据库文档管理</title><link href=css/app.f232fb4e.css rel=preload as=style><link href=css/chunk-vendors.8924efc6.css rel=preload as=style><link href=js/app.ae04f4d2.js rel=preload as=script><link href=js/chunk-vendors.96aa31ea.js rel=preload as=script><link href=css/chunk-vendors.8924efc6.css rel=stylesheet><link href=css/app.f232fb4e.css rel=stylesheet></head><body><noscript><strong>We're sorry but zyplayer-db-ui doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=js/chunk-vendors.96aa31ea.js></script><script src=js/app.ae04f4d2.js></script></body></html>
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=favicon-db.png><title>数据库文档管理</title><link href=css/app.f232fb4e.css rel=preload as=style><link href=css/chunk-vendors.8924efc6.css rel=preload as=style><link href=js/app.582f8c0f.js rel=preload as=script><link href=js/chunk-vendors.d15e5982.js rel=preload as=script><link href=css/chunk-vendors.8924efc6.css rel=stylesheet><link href=css/app.f232fb4e.css rel=stylesheet></head><body><noscript><strong>We're sorry but zyplayer-db-ui doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=js/chunk-vendors.d15e5982.js></script><script src=js/app.582f8c0f.js></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long