功能优化

This commit is contained in:
暮光:城中城
2018-12-19 23:12:40 +08:00
parent 1ebd6fcfc1
commit 16b4940d5a
18 changed files with 1196 additions and 1038 deletions

View File

@@ -1,226 +1,230 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-db</artifactId>
<version>1.0.1</version>
<packaging>jar</packaging>
<name>zyplayer-doc-db</name>
<description>数据库文档工具</description>
<url>https://gitee.com/zyplayer/zyplayer-doc/zyplayer-doc-db</url>
<developers>
<developer>
<id>zyplayer</id>
<name>暮光:城中城</name>
<email>806783409@qq.com</email>
<roles>
<role>Java Development Engineer</role>
</roles>
<timezone>2018-05-22 16:06:06</timezone>
</developer>
</developers>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.44</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
<version>4.1.8</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<!-- 打包跳过单元测试 -->
<skipTests>true</skipTests>
<destDir>${project.build.outputDirectory}/META-INF/resources/webjars/${project.artifactId}/${project.version}</destDir>
</properties>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<scm>
<connection>scm:git@git.oschina.net:zyplayer/zyplayer-doc.git</connection>
<developerConnection>scm:git@git.oschina.net:zyplayer/zyplayer-doc.git</developerConnection>
<url>git@git.oschina.net:zyplayer/zyplayer-doc.git</url>
</scm>
<distributionManagement>
<snapshotRepository>
<id>snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
<repository>
<id>snapshots</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<targetPath>META-INF/resources/</targetPath>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/webapp</directory>
<includes>
<include>**/*</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.2</version>
<configuration>
<aggregate>true</aggregate>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<skipTests>${skipTests}</skipTests>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.2</version>
<configuration>
<aggregate>true</aggregate>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-db</artifactId>
<version>1.0.1</version>
<packaging>jar</packaging>
<name>zyplayer-doc-db</name>
<description>数据库文档工具</description>
<url>https://gitee.com/zyplayer/zyplayer-doc/zyplayer-doc-db</url>
<developers>
<developer>
<id>zyplayer</id>
<name>暮光:城中城</name>
<email>806783409@qq.com</email>
<roles>
<role>Java Development Engineer</role>
</roles>
<timezone>2018-05-22 16:06:06</timezone>
</developer>
</developers>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.44</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
<version>4.1.8</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<!-- 打包跳过单元测试 -->
<skipTests>true</skipTests>
<destDir>${project.build.outputDirectory}/META-INF/resources/webjars/${project.artifactId}/${project.version}</destDir>
</properties>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<scm>
<connection>scm:git@git.oschina.net:zyplayer/zyplayer-doc.git</connection>
<developerConnection>scm:git@git.oschina.net:zyplayer/zyplayer-doc.git</developerConnection>
<url>git@git.oschina.net:zyplayer/zyplayer-doc.git</url>
</scm>
<distributionManagement>
<snapshotRepository>
<id>snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
<repository>
<id>snapshots</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<targetPath>META-INF/resources/</targetPath>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/webapp</directory>
<includes>
<include>**/*</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.2</version>
<configuration>
<aggregate>true</aggregate>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<skipTests>${skipTests}</skipTests>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.2</version>
<configuration>
<aggregate>true</aggregate>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -1,240 +1,240 @@
package com.zyplayer.doc.db.controller;
import java.io.File;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
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 com.alibaba.fastjson.JSON;
import com.zyplayer.doc.db.controller.vo.DatabaseExportVo;
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
import com.zyplayer.doc.db.controller.vo.TableColumnVo.TableInfoVo;
import com.zyplayer.doc.db.framework.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.ColumnInfoDto;
import com.zyplayer.doc.db.framework.db.dto.DatabaseInfoDto;
import com.zyplayer.doc.db.framework.db.dto.QueryTableColumnDescDto;
import com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto;
import com.zyplayer.doc.db.framework.db.dto.TableDescDto;
import com.zyplayer.doc.db.framework.db.dto.TableInfoDto;
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.json.ResponseJson;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ZipUtil;
/**
* 文档控制器
*
* @author 暮光:城中城
* @since 2018年8月8日
*/
@RestController
@RequestMapping("/zyplayer-doc-db/doc-db")
public class DatabaseDocController {
@Autowired(required = false)
DatabaseRegistrationBean databaseRegistrationBean;
@PostMapping(value = "/getDataSourceList")
public ResponseJson getDataSourceList() {
List<DatabaseFactoryBean> factoryBeanList = databaseRegistrationBean.getDatabaseFactoryBeanList();
Set<String> dataSourceList = factoryBeanList.stream().collect(Collectors.mapping(DatabaseFactoryBean::getHost, Collectors.toSet()));
return DocDbResponseJson.ok(dataSourceList);
}
@PostMapping(value = "/getDatabaseList")
public ResponseJson getDatabaseList(String host) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperByHost(host);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
List<DatabaseInfoDto> dbNameDtoList = baseMapper.getDatabaseList();
return DocDbResponseJson.ok(dbNameDtoList);
}
@PostMapping(value = "/getTableList")
public ResponseJson getTableList(String host, String dbName) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(host, dbName);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
List<TableInfoDto> dbTableList = baseMapper.getTableList(dbName);
return DocDbResponseJson.ok(dbTableList);
}
@PostMapping(value = "/getTableColumnList")
public ResponseJson getTableColumnList(String host, String dbName, String tableName) {
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getDatabaseFactoryBean(host, dbName);
if (databaseFactoryBean == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
TableColumnVo tableColumnVo = this.getTableColumnVo(databaseFactoryBean, dbName, tableName);
return DocDbResponseJson.ok(tableColumnVo);
}
@PostMapping(value = "/getTableColumnDescList")
public ResponseJson getTableColumnDescList(String host, String dbName, String tableName) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(host, dbName);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnDescList(tableName);
return DocDbResponseJson.ok(columnDescDto);
}
@PostMapping(value = "/getTableAndColumnBySearch")
public ResponseJson getTableAndColumnBySearch(String host, String dbName, String tableName, String searchText) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(host, dbName);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
if (StringUtils.isNotBlank(searchText)) {
searchText = "%" + searchText + "%";
}
List<QueryTableColumnDescDto> columnDescDto = baseMapper.getTableAndColumnBySearch(dbName, searchText);
return DocDbResponseJson.ok(columnDescDto);
}
@PostMapping(value = "/getTableDescList")
public ResponseJson getTableDescList(String host, String dbName, String tableName) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(host, dbName);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
List<TableDescDto> columnDescDto = baseMapper.getTableDescList(tableName);
return DocDbResponseJson.ok(columnDescDto);
}
@PostMapping(value = "/updateTableDesc")
public ResponseJson updateTableDesc(String host, String dbName, String tableName, String newDesc) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(host, dbName);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
baseMapper.updateTableDesc(dbName, tableName, newDesc);
return DocDbResponseJson.ok();
}
@PostMapping(value = "/updateTableColumnDesc")
public ResponseJson updateTableColumnDesc(String host, String dbName, String tableName, String columnName, String newDesc) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(host, dbName);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
ColumnInfoDto columnInfo = null;
// mysql要同时修改类型默认值等所以先查出来
MysqlMapper mysqlMapper = databaseRegistrationBean.getBaseMapper(host, dbName, 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);
return DocDbResponseJson.ok();
}
@GetMapping(value = "/exportDatabase")
public ResponseJson exportDatabase(HttpServletResponse response, String host, String dbName, String tableNames) {
if (StringUtils.isBlank(tableNames)) {
return DocDbResponseJson.warn("请选择需要导出的表");
}
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getDatabaseFactoryBean(host, dbName);
if (databaseFactoryBean == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
List<TableInfoVo> tableList = new LinkedList<>();
Map<String, List<TableColumnDescDto>> columnList = new HashMap<>();
String[] tableNameArr = tableNames.split(",");
for (String tableName : tableNameArr) {
if (StringUtils.isBlank(tableName)) {
continue;
}
TableColumnVo tableColumnVo = this.getTableColumnVo(databaseFactoryBean, dbName, tableName);
columnList.put(tableName, tableColumnVo.getColumnList());
tableList.add(tableColumnVo.getTableInfo());
}
DatabaseExportVo exportVo = new DatabaseExportVo();
exportVo.setColumnList(columnList);
exportVo.setTableList(tableList);
String content = JSON.toJSONString(exportVo);
content = "var database = " + content;
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=database.js");
response.setCharacterEncoding("utf-8");
// 将文件输入流写入response的输出流中
try {
IoUtil.write(response.getOutputStream(), "utf-8", true, content);
} catch (Exception e) {
e.printStackTrace();
}
return DocDbResponseJson.ok();
}
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(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;
}
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"));
}
}
package com.zyplayer.doc.db.controller;
import java.io.File;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
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 com.alibaba.fastjson.JSON;
import com.zyplayer.doc.db.controller.vo.DatabaseExportVo;
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
import com.zyplayer.doc.db.controller.vo.TableColumnVo.TableInfoVo;
import com.zyplayer.doc.db.framework.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.ColumnInfoDto;
import com.zyplayer.doc.db.framework.db.dto.DatabaseInfoDto;
import com.zyplayer.doc.db.framework.db.dto.QueryTableColumnDescDto;
import com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto;
import com.zyplayer.doc.db.framework.db.dto.TableDescDto;
import com.zyplayer.doc.db.framework.db.dto.TableInfoDto;
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.json.ResponseJson;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ZipUtil;
/**
* 文档控制器
*
* @author 暮光:城中城
* @since 2018年8月8日
*/
@RestController
@RequestMapping("/zyplayer-doc-db/doc-db")
public class DatabaseDocController {
@Autowired
DatabaseRegistrationBean databaseRegistrationBean;
@PostMapping(value = "/getDataSourceList")
public ResponseJson getDataSourceList() {
List<DatabaseFactoryBean> factoryBeanList = databaseRegistrationBean.getDatabaseFactoryBeanList();
Set<String> dataSourceList = factoryBeanList.stream().collect(Collectors.mapping(DatabaseFactoryBean::getHost, Collectors.toSet()));
return DocDbResponseJson.ok(dataSourceList);
}
@PostMapping(value = "/getDatabaseList")
public ResponseJson getDatabaseList(String host) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperByHost(host);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
List<DatabaseInfoDto> dbNameDtoList = baseMapper.getDatabaseList();
return DocDbResponseJson.ok(dbNameDtoList);
}
@PostMapping(value = "/getTableList")
public ResponseJson getTableList(String host, String dbName) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(host, dbName);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
List<TableInfoDto> dbTableList = baseMapper.getTableList(dbName);
return DocDbResponseJson.ok(dbTableList);
}
@PostMapping(value = "/getTableColumnList")
public ResponseJson getTableColumnList(String host, String dbName, String tableName) {
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getDatabaseFactoryBean(host, dbName);
if (databaseFactoryBean == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
TableColumnVo tableColumnVo = this.getTableColumnVo(databaseFactoryBean, dbName, tableName);
return DocDbResponseJson.ok(tableColumnVo);
}
@PostMapping(value = "/getTableColumnDescList")
public ResponseJson getTableColumnDescList(String host, String dbName, String tableName) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(host, dbName);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnDescList(tableName);
return DocDbResponseJson.ok(columnDescDto);
}
@PostMapping(value = "/getTableAndColumnBySearch")
public ResponseJson getTableAndColumnBySearch(String host, String dbName, String tableName, String searchText) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(host, dbName);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
if (StringUtils.isNotBlank(searchText)) {
searchText = "%" + searchText + "%";
}
List<QueryTableColumnDescDto> columnDescDto = baseMapper.getTableAndColumnBySearch(dbName, searchText);
return DocDbResponseJson.ok(columnDescDto);
}
@PostMapping(value = "/getTableDescList")
public ResponseJson getTableDescList(String host, String dbName, String tableName) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(host, dbName);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
List<TableDescDto> columnDescDto = baseMapper.getTableDescList(tableName);
return DocDbResponseJson.ok(columnDescDto);
}
@PostMapping(value = "/updateTableDesc")
public ResponseJson updateTableDesc(String host, String dbName, String tableName, String newDesc) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(host, dbName);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
baseMapper.updateTableDesc(dbName, tableName, newDesc);
return DocDbResponseJson.ok();
}
@PostMapping(value = "/updateTableColumnDesc")
public ResponseJson updateTableColumnDesc(String host, String dbName, String tableName, String columnName, String newDesc) {
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(host, dbName);
if (baseMapper == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
ColumnInfoDto columnInfo = null;
// mysql要同时修改类型默认值等所以先查出来
MysqlMapper mysqlMapper = databaseRegistrationBean.getBaseMapper(host, dbName, 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);
return DocDbResponseJson.ok();
}
@GetMapping(value = "/exportDatabase")
public ResponseJson exportDatabase(HttpServletResponse response, String host, String dbName, String tableNames) {
if (StringUtils.isBlank(tableNames)) {
return DocDbResponseJson.warn("请选择需要导出的表");
}
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getDatabaseFactoryBean(host, dbName);
if (databaseFactoryBean == null) {
return DocDbResponseJson.warn("未找到对应的数据库连接");
}
List<TableInfoVo> tableList = new LinkedList<>();
Map<String, List<TableColumnDescDto>> columnList = new HashMap<>();
String[] tableNameArr = tableNames.split(",");
for (String tableName : tableNameArr) {
if (StringUtils.isBlank(tableName)) {
continue;
}
TableColumnVo tableColumnVo = this.getTableColumnVo(databaseFactoryBean, dbName, tableName);
columnList.put(tableName, tableColumnVo.getColumnList());
tableList.add(tableColumnVo.getTableInfo());
}
DatabaseExportVo exportVo = new DatabaseExportVo();
exportVo.setColumnList(columnList);
exportVo.setTableList(tableList);
String content = JSON.toJSONString(exportVo);
content = "var database = " + content;
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment;filename=database.js");
response.setCharacterEncoding("utf-8");
// 将文件输入流写入response的输出流中
try {
IoUtil.write(response.getOutputStream(), "utf-8", true, content);
} catch (Exception e) {
e.printStackTrace();
}
return DocDbResponseJson.ok();
}
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(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;
}
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"));
}
}

View File

@@ -1,90 +1,115 @@
package com.zyplayer.doc.db.framework.configuration;
import java.sql.DatabaseMetaData;
import java.util.LinkedList;
import java.util.List;
import javax.sql.DataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Component;
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;
@Component
public class ApplicationListenerBean implements ApplicationListener<ContextRefreshedEvent> {
@Autowired(required = false)
DatabaseRegistrationBean databaseRegistrationBean;
private volatile static boolean IS_INIT = false;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (databaseRegistrationBean == null || IS_INIT) {
return;
}
// 会被调用两次
IS_INIT = true;
List<DatabaseFactoryBean> databaseFactoryBeanList = new LinkedList<>();
for (DataSource dataSource : databaseRegistrationBean.getDataSourceList()) {
try {
DatabaseFactoryBean databaseFactoryBean = new DatabaseFactoryBean();
DatabaseMetaData metaData = dataSource.getConnection().getMetaData();
String productName = metaData.getDatabaseProductName().toLowerCase();
Resource[] resources = null;
String dbUrl = metaData.getURL();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
if (productName.indexOf("mysql") >= 0) {
// jdbc:mysql://192.168.0.1:3306/user_info?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
String[] urlParamArr = dbUrl.split("\\?");
String[] urlDbNameArr = urlParamArr[0].split("/");
if (urlDbNameArr.length >= 2) {
databaseFactoryBean.setDbName(urlDbNameArr[urlDbNameArr.length - 1]);
databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 2]);
}
databaseFactoryBean.setDatabaseProduct(DatabaseProduct.MYSQL);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/mysql/*.xml");
} else if (productName.indexOf("sql server") >= 0) {
// jdbc:jtds:sqlserver://192.168.0.1:33434;socketTimeout=60;DatabaseName=user_info;
String[] urlParamArr = dbUrl.split(";");
String[] urlDbNameArr = urlParamArr[0].split("/");
databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 1]);
for (String urlParam : urlParamArr) {
String[] keyValArr = urlParam.split("=");
if (keyValArr.length >= 2 && keyValArr[0].equalsIgnoreCase("DatabaseName")) {
databaseFactoryBean.setDbName(keyValArr[1]);
}
}
databaseFactoryBean.setDatabaseProduct(DatabaseProduct.SQLSERVER);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/sqlserver/*.xml");
}
if (resources == null) {
continue;
}
// 创建sqlSessionTemplate
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(resources);
SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactoryBean.getObject());
// 组装自定义的bean
databaseFactoryBean.setDataSource(dataSource);
databaseFactoryBean.setSqlSessionTemplate(sqlSessionTemplate);
databaseFactoryBean.setUrl(dbUrl);
databaseFactoryBeanList.add(databaseFactoryBean);
} catch (Exception e) {
e.printStackTrace();
}
}
databaseRegistrationBean.setDatabaseFactoryBeanList(databaseFactoryBeanList);
}
}
package com.zyplayer.doc.db.framework.configuration;
import java.sql.DatabaseMetaData;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import javax.sql.DataSource;
import com.zyplayer.doc.db.framework.db.bean.DbConfigBean;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.ApplicationListener;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Component;
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;
@Component
public class ApplicationListenerBean implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
DatabaseRegistrationBean databaseRegistrationBean;
private volatile static boolean IS_INIT = false;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (databaseRegistrationBean == null || IS_INIT) {
return;
}
// 会被调用两次
IS_INIT = true;
Integer dataSourceIndex = 0;
List<DatabaseFactoryBean> databaseFactoryBeanList = new LinkedList<>();
for (DbConfigBean dbConfigBean : databaseRegistrationBean.getDbConfigList()) {
try {
// 数据源配置
Properties xaProperties = new Properties();
xaProperties.setProperty("driverClassName", dbConfigBean.getDriverClassName());
xaProperties.setProperty("url", dbConfigBean.getUrl());
xaProperties.setProperty("username", dbConfigBean.getUsername());
xaProperties.setProperty("password", dbConfigBean.getPassword());
xaProperties.setProperty("maxActive", "500");
xaProperties.setProperty("testOnBorrow", "true");
xaProperties.setProperty("testWhileIdle", "true");
xaProperties.setProperty("validationQuery", "select 'x'");
// 数据源
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
dataSource.setXaProperties(xaProperties);
dataSource.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
dataSource.setUniqueResourceName("zyplayer-doc-db" + (dataSourceIndex++));
dataSource.setMaxPoolSize(500);
dataSource.setMinPoolSize(1);
dataSource.setMaxLifetime(60);
// 描述连接信息的对象
DatabaseFactoryBean databaseFactoryBean = new DatabaseFactoryBean();
DatabaseMetaData metaData = dataSource.getConnection().getMetaData();
String productName = metaData.getDatabaseProductName().toLowerCase();
Resource[] resources = null;
String dbUrl = metaData.getURL();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
if (productName.indexOf("mysql") >= 0) {
// jdbc:mysql://192.168.0.1:3306/user_info?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
String[] urlParamArr = dbUrl.split("\\?");
String[] urlDbNameArr = urlParamArr[0].split("/");
if (urlDbNameArr.length >= 2) {
databaseFactoryBean.setDbName(urlDbNameArr[urlDbNameArr.length - 1]);
databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 2]);
}
databaseFactoryBean.setDatabaseProduct(DatabaseProduct.MYSQL);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/mysql/*.xml");
} else if (productName.indexOf("sql server") >= 0) {
// jdbc:jtds:sqlserver://192.168.0.1:33434;socketTimeout=60;DatabaseName=user_info;
String[] urlParamArr = dbUrl.split(";");
String[] urlDbNameArr = urlParamArr[0].split("/");
databaseFactoryBean.setHost(urlDbNameArr[urlDbNameArr.length - 1]);
for (String urlParam : urlParamArr) {
String[] keyValArr = urlParam.split("=");
if (keyValArr.length >= 2 && keyValArr[0].equalsIgnoreCase("DatabaseName")) {
databaseFactoryBean.setDbName(keyValArr[1]);
}
}
databaseFactoryBean.setDatabaseProduct(DatabaseProduct.SQLSERVER);
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/sqlserver/*.xml");
}
if (resources == null) {
continue;
}
// 创建sqlSessionTemplate
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(resources);
SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactoryBean.getObject());
// 组装自定义的bean
databaseFactoryBean.setDataSource(dataSource);
databaseFactoryBean.setSqlSessionTemplate(sqlSessionTemplate);
databaseFactoryBean.setUrl(dbUrl);
databaseFactoryBeanList.add(databaseFactoryBean);
} catch (Exception e) {
e.printStackTrace();
}
}
databaseRegistrationBean.setDatabaseFactoryBeanList(databaseFactoryBeanList);
}
}

View File

@@ -1,92 +1,89 @@
package com.zyplayer.doc.db.framework.db.bean;
import java.util.LinkedList;
import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.lang.StringUtils;
import org.mybatis.spring.SqlSessionTemplate;
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.mapper.base.BaseMapper;
/**
* 需要声明注入的对象只需要设置dataSourceList即可
* databaseFactoryBeanList是后面生成的
*
* @author 暮光:城中城
* @since 2018年8月8日
*/
public class DatabaseRegistrationBean {
private List<DataSource> dataSourceList = new LinkedList<>();
private List<DatabaseFactoryBean> databaseFactoryBeanList = new LinkedList<>();
public List<DataSource> getDataSourceList() {
return dataSourceList;
}
public void setDataSourceList(List<DataSource> dataSourceList) {
this.dataSourceList = dataSourceList;
}
public List<DatabaseFactoryBean> getDatabaseFactoryBeanList() {
return databaseFactoryBeanList;
}
public void setDatabaseFactoryBeanList(List<DatabaseFactoryBean> databaseFactoryBeanList) {
this.databaseFactoryBeanList = databaseFactoryBeanList;
}
public DatabaseFactoryBean getDatabaseFactoryBean(String host, String dbName) {
if (StringUtils.isBlank(dbName)) {
return null;
}
DatabaseFactoryBean resultBean = null;
for (DatabaseFactoryBean databaseFactoryBean : databaseFactoryBeanList) {
if (host.equalsIgnoreCase(databaseFactoryBean.getHost())) {
if (dbName.equalsIgnoreCase(databaseFactoryBean.getDbName())) {
return databaseFactoryBean;
}
if (databaseFactoryBean.getDatabaseProduct() == DatabaseProduct.MYSQL) {
resultBean = databaseFactoryBean;
}
}
}
return resultBean;
}
public BaseMapper getBaseMapper(String host, String dbName) {
return getBaseMapper(host, dbName, BaseMapper.class);
}
public <T> T getBaseMapper(String host, String dbName, Class<T> cls) {
DatabaseFactoryBean factoryBean = getDatabaseFactoryBean(host, dbName);
if (factoryBean != null) {
SqlSessionTemplate sessionTemplate = factoryBean.getSqlSessionTemplate();
try {
return sessionTemplate.getMapper(cls);
} catch (Exception e) {}
}
return null;
}
public BaseMapper getBaseMapperByHost(String host) {
if (StringUtils.isBlank(host)) {
return null;
}
for (DatabaseFactoryBean databaseFactoryBean : databaseFactoryBeanList) {
if (host.equalsIgnoreCase(databaseFactoryBean.getHost())) {
try {
SqlSessionTemplate sessionTemplate = databaseFactoryBean.getSqlSessionTemplate();
return sessionTemplate.getMapper(BaseMapper.class);
} catch (Exception e) {}
}
}
return null;
}
package com.zyplayer.doc.db.framework.db.bean;
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean.DatabaseProduct;
import com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper;
import org.apache.commons.lang.StringUtils;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.LinkedList;
import java.util.List;
/**
* 需要声明注入的对象只需要设置dbConfigList即可
* databaseFactoryBeanList是后面生成的
*
* @author 暮光:城中城
* @since 2018年8月8日
*/
public class DatabaseRegistrationBean {
// 注入此对象必须配置的参数
// 配置的数据源连接、账号密码等信息,通过注入得到
private List<DbConfigBean> dbConfigList = new LinkedList<>();
// 描述连接信息的对象列表
private List<DatabaseFactoryBean> databaseFactoryBeanList = new LinkedList<>();
public List<DatabaseFactoryBean> getDatabaseFactoryBeanList() {
return databaseFactoryBeanList;
}
public void setDatabaseFactoryBeanList(List<DatabaseFactoryBean> databaseFactoryBeanList) {
this.databaseFactoryBeanList = databaseFactoryBeanList;
}
public DatabaseFactoryBean getDatabaseFactoryBean(String host, String dbName) {
if (StringUtils.isBlank(dbName)) {
return null;
}
DatabaseFactoryBean resultBean = null;
for (DatabaseFactoryBean databaseFactoryBean : databaseFactoryBeanList) {
if (host.equalsIgnoreCase(databaseFactoryBean.getHost())) {
if (dbName.equalsIgnoreCase(databaseFactoryBean.getDbName())) {
return databaseFactoryBean;
}
if (databaseFactoryBean.getDatabaseProduct() == DatabaseProduct.MYSQL) {
resultBean = databaseFactoryBean;
}
}
}
return resultBean;
}
public BaseMapper getBaseMapper(String host, String dbName) {
return getBaseMapper(host, dbName, BaseMapper.class);
}
public <T> T getBaseMapper(String host, String dbName, Class<T> cls) {
DatabaseFactoryBean factoryBean = getDatabaseFactoryBean(host, dbName);
if (factoryBean != null) {
SqlSessionTemplate sessionTemplate = factoryBean.getSqlSessionTemplate();
try {
return sessionTemplate.getMapper(cls);
} catch (Exception e) {}
}
return null;
}
public BaseMapper getBaseMapperByHost(String host) {
if (StringUtils.isBlank(host)) {
return null;
}
for (DatabaseFactoryBean databaseFactoryBean : databaseFactoryBeanList) {
if (host.equalsIgnoreCase(databaseFactoryBean.getHost())) {
try {
SqlSessionTemplate sessionTemplate = databaseFactoryBean.getSqlSessionTemplate();
return sessionTemplate.getMapper(BaseMapper.class);
} catch (Exception e) {}
}
}
return null;
}
public List<DbConfigBean> getDbConfigList() {
return dbConfigList;
}
public void setDbConfigList(List<DbConfigBean> dbConfigList) {
this.dbConfigList = dbConfigList;
}
}

View File

@@ -0,0 +1,44 @@
package com.zyplayer.doc.db.framework.db.bean;
/**
* @Author
* @Date 2018/11/11
**/
public class DbConfigBean {
private String driverClassName;
private String url;
private String username;
private String password;
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@@ -1,162 +1,162 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
<head>
<meta charset="UTF-8">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>zyplayer-doc-db</title>
<link rel="shortcut icon" href="webjars/doc-db/img/api.ico"/>
<link rel="stylesheet" href="webjars/zui/css/zui.min.css" />
<link rel="stylesheet" href="webjars/zui/css/zui-theme.min.css">
<link rel="stylesheet" href="webjars/zui/lib/chosen/chosen.min.css" />
<link rel="stylesheet" href="webjars/doc-db/css/doc-db.css" />
</head>
<body>
<div class="container">
<div class="row choise-db">
<div class="col-md-3">
<select id="choiseHost" data-placeholder="选择一个连接" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-3">
<select id="choiseDatabase" data-placeholder="选择一个数据库" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-3">
<select id="choiseTable" data-placeholder="选择一张表" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-3">
<button class="btn btn-primary" type="button" id="fuzzySearchBtn">模糊查询</button>
<button class="btn btn-primary" type="button" id="exportBtn">导出</button>
<button class="btn" type="button" id="showEchartsBtn">显示表关系图</button>
</div>
</div>
<div class="table-info">
<div>表名:<span class="table-name"></span></div>
<div class="desc">
<div id="tableDescShow">
<span class="table-desc"></span>
<i class="icon icon-edit" title="编辑表注释"></i>
</div>
<textarea id="tableDescInput" rows="2" class="form-control"></textarea>
</div>
</div>
<div class="table-columns">
<table class="table table-bordered table-striped table-hover" id="tableCloumnsTable">
<thead>
<tr><th>字段名</th><th>自增</th><th>类型</th><th>长度</th><th>NULL</th><th>主键</th><th>注释</th></tr>
</thead>
<tbody></tbody>
</table>
</div>
<div id="tableRelationBox" class="hide" style="width: 100%;height:100px;">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<p>
Tips本关系图不是通过外键生成所以需要在字段注释最后按规则添加外键关系才能生成图表支持的格式有<br/>
1、T:表XXX(字段注释)T:user_info<br/>
2、T:表.关联IDXXX(字段注释)T:user_info.id<br/>
3、T:库.表.关联IDXXX(字段注释)T:order_db.user_info.id<br/>
实验功能,有更好的建议或展示方式欢迎<a target="_blank" href="https://gitee.com/zyplayer/zyplayer-doc-db">提交建议</a>
</p>
</div>
<div id="tableRelationCharts" style="width: 100%;height:100%;margin-bottom: 50px;"></div>
</div>
<!-- 模糊查询 -->
<div class="modal fade" id="fuzzySearchModal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span><span class="sr-only">关闭</span>
</button>
<h4 class="modal-title">通过字段名或释义模糊查询</h4>
</div>
<div class="modal-body">
<div class="row choise-db">
<div class="col-md-3">
<select id="choiseFuzzyHost" data-placeholder="选择一个连接" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-3">
<select id="choiseFuzzyDatabase" data-placeholder="选择一个数据库" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-4">
<input id="searchText" type="text" class="form-control" placeholder="搜索内容,字段名或注释">
</div>
<div class="col-md-2">
<button id="doSearch" class="btn btn-primary" type="button">查询 <i class="icon icon-spin icon-spinner-snake hidden"></i></button>
</div>
</div>
<div class="modal-table-box">
<table class="table table-bordered table-striped table-hover" id="fuzzySearchTable">
<thead>
<tr><th>表名</th><th>字段名</th><th>注释</th></tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- 导出弹出框 -->
<div class="modal fade" id="exportModal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span><span class="sr-only">关闭</span>
</button>
<h4 class="modal-title">导出数据库文档</h4>
</div>
<div class="modal-body">
<div class="row choise-db">
<div class="col-md-3">
<select id="choiseExportHost" data-placeholder="选择一个连接" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-3">
<select id="choiseExportDatabase" data-placeholder="选择一个数据库" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-6">
<button id="doExport" class="btn btn-primary" type="button">确认导出 <i class="icon icon-spin icon-spinner-snake hidden"></i></button>
<button id="checkAllTable" class="btn" type="button">全选</button>
<button id="notCheckAllTable" class="btn" type="button">全不选</button>
</div>
</div>
<div class="alert alert-danger">
请到 <a target="_blank" href="https://gitee.com/zyplayer/zyplayer-doc-db">源码处下载</a>《对外文档模板.zip》解压
然后将“确认导出”后的文件放至/js目录下文件名必须为database.js<br/>
然后双击打开目录下的doc-db.html 即可看到导出的文档
</div>
<div class="modal-table-box">
<ul id="exportUl"></ul>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script type="text/javascript" src="webjars/doc-db/js/jquery-3.1.0.min.js"></script>
<script type="text/javascript" src="webjars/zui/js/zui.min.js"></script>
<script type="text/javascript" src="webjars/zui/lib/chosen/chosen.min.js"></script>
<script type="text/javascript" src="webjars/doc-db/js/echarts.min.js"></script>
<script type="text/javascript" src="webjars/doc-db/js/option-table-relation.js"></script>
<script type="text/javascript" src="webjars/doc-db/js/formatjson.js"></script>
<script type="text/javascript" src="webjars/doc-db/js/toast.js"></script>
<script type="text/javascript" src="webjars/doc-db/js/common.js"></script>
<script type="text/javascript" src="webjars/doc-db/js/doc-db.js"></script>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
<head>
<meta charset="UTF-8">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>数据库文档</title>
<link rel="shortcut icon" href="webjars/doc-db/img/api.ico"/>
<link rel="stylesheet" href="webjars/zui/css/zui.min.css" />
<link rel="stylesheet" href="webjars/zui/css/zui-theme.min.css">
<link rel="stylesheet" href="webjars/zui/lib/chosen/chosen.min.css" />
<link rel="stylesheet" href="webjars/doc-db/css/doc-db.css" />
</head>
<body>
<div class="container">
<div class="row choise-db">
<div class="col-md-3">
<select id="choiseHost" data-placeholder="选择一个连接" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-3">
<select id="choiseDatabase" data-placeholder="选择一个数据库" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-3">
<select id="choiseTable" data-placeholder="选择一张表" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-3">
<button class="btn btn-primary" type="button" id="fuzzySearchBtn">模糊查询</button>
<button class="btn btn-primary" type="button" id="exportBtn">导出</button>
<button class="btn" type="button" id="showEchartsBtn">显示表关系图</button>
</div>
</div>
<div class="table-info">
<div>表名:<span class="table-name"></span></div>
<div class="desc">
<div id="tableDescShow">
<span class="table-desc"></span>
<i class="icon icon-edit" title="编辑表注释"></i>
</div>
<textarea id="tableDescInput" rows="2" class="form-control"></textarea>
</div>
</div>
<div class="table-columns">
<table class="table table-bordered table-striped table-hover" id="tableCloumnsTable">
<thead>
<tr><th>字段名</th><th>自增</th><th>类型</th><th>长度</th><th>NULL</th><th>主键</th><th>注释</th></tr>
</thead>
<tbody></tbody>
</table>
</div>
<div id="tableRelationBox" class="hide" style="width: 100%;height:100px;">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<p>
Tips本关系图不是通过外键生成所以需要在字段注释最后按规则添加外键关系才能生成图表支持的格式有<br/>
1、T:表XXX(字段注释)T:user_info<br/>
2、T:表.关联IDXXX(字段注释)T:user_info.id<br/>
3、T:库.表.关联IDXXX(字段注释)T:order_db.user_info.id<br/>
实验功能,有更好的建议或展示方式欢迎<a target="_blank" href="https://gitee.com/zyplayer/zyplayer-doc">提交建议</a>
</p>
</div>
<div id="tableRelationCharts" style="width: 100%;height:100%;margin-bottom: 50px;"></div>
</div>
<!-- 模糊查询 -->
<div class="modal fade" id="fuzzySearchModal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span><span class="sr-only">关闭</span>
</button>
<h4 class="modal-title">通过字段名或释义模糊查询</h4>
</div>
<div class="modal-body">
<div class="row choise-db">
<div class="col-md-3">
<select id="choiseFuzzyHost" data-placeholder="选择一个连接" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-3">
<select id="choiseFuzzyDatabase" data-placeholder="选择一个数据库" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-4">
<input id="searchText" type="text" class="form-control" placeholder="搜索内容,字段名或注释">
</div>
<div class="col-md-2">
<button id="doSearch" class="btn btn-primary" type="button">查询 <i class="icon icon-spin icon-spinner-snake hidden"></i></button>
</div>
</div>
<div class="modal-table-box">
<table class="table table-bordered table-striped table-hover" id="fuzzySearchTable">
<thead>
<tr><th>表名</th><th>字段名</th><th>注释</th></tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- 导出弹出框 -->
<div class="modal fade" id="exportModal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span><span class="sr-only">关闭</span>
</button>
<h4 class="modal-title">导出数据库文档</h4>
</div>
<div class="modal-body">
<div class="row choise-db">
<div class="col-md-3">
<select id="choiseExportHost" data-placeholder="选择一个连接" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-3">
<select id="choiseExportDatabase" data-placeholder="选择一个数据库" class="chosen-select form-control" tabindex="2">
<option value=""></option>
</select>
</div>
<div class="col-md-6">
<button id="doExport" class="btn btn-primary" type="button">确认导出 <i class="icon icon-spin icon-spinner-snake hidden"></i></button>
<button id="checkAllTable" class="btn" type="button">全选</button>
<button id="notCheckAllTable" class="btn" type="button">全不选</button>
</div>
</div>
<div class="alert alert-danger">
请到 <a target="_blank" href="https://gitee.com/zyplayer/zyplayer-doc-db">源码处下载</a>《对外文档模板.zip》解压
然后将“确认导出”后的文件放至/js目录下文件名必须为database.js<br/>
然后双击打开目录下的doc-db.html 即可看到导出的文档
</div>
<div class="modal-table-box">
<ul id="exportUl"></ul>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script type="text/javascript" src="webjars/doc-db/js/jquery-3.1.0.min.js"></script>
<script type="text/javascript" src="webjars/zui/js/zui.min.js"></script>
<script type="text/javascript" src="webjars/zui/lib/chosen/chosen.min.js"></script>
<script type="text/javascript" src="webjars/doc-db/js/echarts.min.js"></script>
<script type="text/javascript" src="webjars/doc-db/js/option-table-relation.js"></script>
<script type="text/javascript" src="webjars/doc-db/js/formatjson.js"></script>
<script type="text/javascript" src="webjars/doc-db/js/toast.js"></script>
<script type="text/javascript" src="webjars/doc-db/js/common.js"></script>
<script type="text/javascript" src="webjars/doc-db/js/doc-db.js"></script>
</html>

View File

@@ -30,6 +30,7 @@
<swagger.bootstrap.ui.version>1.8.7</swagger.bootstrap.ui.version>
<springfox.swagger.ui.version>2.9.2</springfox.swagger.ui.version>
<springfox.swagger.version>2.9.2</springfox.swagger.version>
<zyplayer.doc.db.version>1.0.1</zyplayer.doc.db.version>
</properties>
<dependencies>
@@ -117,6 +118,12 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.zyplayer</groupId>
<artifactId>zyplayer-doc-db</artifactId>
<version>${zyplayer.doc.db.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>

View File

@@ -40,10 +40,10 @@ public class Application extends SpringBootServletInitializer {
"zyplayer-doc-swaggerhttp://{}document.html\n\t" +
"swagger-bootstrap-uihttp://{}doc.html\n\t" +
"springfox-swagger-uihttp://{}swagger-ui.html\n\t" +
//"数据库地址http://{}document.html\n " +
"数据库文档管理地址http://{}doc-db.html\n\t" +
"管理地址http://{}statics/manage/home.html\n" +
"----------------------------------------------------------",
urlCtx, urlCtx, urlCtx, urlCtx
urlCtx, urlCtx, urlCtx, urlCtx, urlCtx
);
}
}

View File

@@ -0,0 +1,23 @@
package com.zyplayer.doc.manage.framework.config;
import com.zyplayer.doc.db.framework.configuration.EnableDocDb;
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author
* @Date 2018/11/11
**/
@EnableDocDb
@Configuration
public class DocDatabaseRegistrationConfig {
@Bean
@ConfigurationProperties(prefix = "zyplayer.doc.db")
public DatabaseRegistrationBean databaseRegistrationBean(){
return new DatabaseRegistrationBean();
}
}

View File

@@ -1,141 +1,141 @@
package com.zyplayer.doc.manage.framework.config;
import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.zyplayer.doc.manage.repository.support.interceptor.SqlLogInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.jta.JtaTransactionManager;
import javax.sql.DataSource;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
import java.util.Properties;
/**
* mybatis plus数据库配置
*/
@Configuration
public class MybatisPlusConfig {
/**
* sql日志
**/
private static final SqlLogInterceptor SQL_LOG_INTERCEPTOR;
static {
SQL_LOG_INTERCEPTOR = new SqlLogInterceptor();
Properties properties = new Properties();
SQL_LOG_INTERCEPTOR.setProperties(properties);
}
/**
* 分布式事务配置
*/
@Configuration
static class JTATransactionManagerConfig {
@Bean(name = "userTransaction")
public UserTransaction userTransaction() throws Throwable {
UserTransactionImp userTransactionImp = new UserTransactionImp();
userTransactionImp.setTransactionTimeout(300);
return userTransactionImp;
}
@Bean(name = "atomikosTransactionManager")
public TransactionManager atomikosTransactionManager() {
UserTransactionManager userTransactionManager = new UserTransactionManager();
userTransactionManager.setForceShutdown(true);
return userTransactionManager;
}
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() throws Throwable {
UserTransaction userTransaction = userTransaction();
TransactionManager atomikosTransactionManager = atomikosTransactionManager();
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(userTransaction, atomikosTransactionManager);
jtaTransactionManager.setAllowCustomIsolationLevels(true);
jtaTransactionManager.setGlobalRollbackOnParticipationFailure(true);
jtaTransactionManager.setDefaultTimeout(30);
return jtaTransactionManager;
}
}
/**
* 数据库配置
*/
@Configuration
@EnableTransactionManagement
@MapperScan(value = "com.zyplayer.doc.manage.repository.manage.mapper", sqlSessionFactoryRef = "manageSqlSessionFactory")
static class ManageMybatisDbConfig {
@Value("${zyplayer.datasource.manage.driverClassName}")
private String driverClassName;
@Value("${zyplayer.datasource.manage.url}")
private String url;
@Value("${zyplayer.datasource.manage.username}")
private String username;
@Value("${zyplayer.datasource.manage.password}")
private String password;
@Bean(name = "manageDatasource")
public DataSource manageDatasource() {
Properties xaProperties = new Properties();
xaProperties.setProperty("driverClassName", driverClassName);
xaProperties.setProperty("url", url);
xaProperties.setProperty("username", username);
xaProperties.setProperty("password", password);
xaProperties.setProperty("maxActive", "500");
xaProperties.setProperty("testOnBorrow", "true");
xaProperties.setProperty("testWhileIdle", "true");
xaProperties.setProperty("validationQuery", "select 'x'");
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaProperties(xaProperties);
xaDataSource.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
xaDataSource.setUniqueResourceName("manageDatasource");
xaDataSource.setMaxPoolSize(500);
xaDataSource.setMinPoolSize(1);
xaDataSource.setMaxLifetime(60);
return xaDataSource;
}
@Bean(name = "manageSqlSessionFactory")
public MybatisSqlSessionFactoryBean manageSqlSessionFactory() throws Exception {
MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(manageDatasource());
sqlSessionFactoryBean.setPlugins(new Interceptor[]{SQL_LOG_INTERCEPTOR});
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mapper/manage/*Mapper.xml"));
return sqlSessionFactoryBean;
}
}
@Bean
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
/* <!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 --> */
performanceInterceptor.setMaxTime(1000);
/* <!--SQL是否格式化 默认false--> */
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
package com.zyplayer.doc.manage.framework.config;
import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.zyplayer.doc.manage.repository.support.interceptor.SqlLogInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.jta.JtaTransactionManager;
import javax.sql.DataSource;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
import java.util.Properties;
/**
* mybatis plus数据库配置
*/
@Configuration
public class MybatisPlusConfig {
/**
* sql日志
**/
private static final SqlLogInterceptor SQL_LOG_INTERCEPTOR;
static {
SQL_LOG_INTERCEPTOR = new SqlLogInterceptor();
Properties properties = new Properties();
SQL_LOG_INTERCEPTOR.setProperties(properties);
}
/**
* 分布式事务配置
*/
@Configuration
static class JTATransactionManagerConfig {
@Bean(name = "userTransaction")
public UserTransaction userTransaction() throws Throwable {
UserTransactionImp userTransactionImp = new UserTransactionImp();
userTransactionImp.setTransactionTimeout(300);
return userTransactionImp;
}
@Bean(name = "atomikosTransactionManager")
public TransactionManager atomikosTransactionManager() {
UserTransactionManager userTransactionManager = new UserTransactionManager();
userTransactionManager.setForceShutdown(true);
return userTransactionManager;
}
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() throws Throwable {
UserTransaction userTransaction = userTransaction();
TransactionManager atomikosTransactionManager = atomikosTransactionManager();
JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(userTransaction, atomikosTransactionManager);
jtaTransactionManager.setAllowCustomIsolationLevels(true);
jtaTransactionManager.setGlobalRollbackOnParticipationFailure(true);
jtaTransactionManager.setDefaultTimeout(30);
return jtaTransactionManager;
}
}
/**
* 数据库配置
*/
@Configuration
@EnableTransactionManagement
@MapperScan(value = "com.zyplayer.doc.manage.repository.manage.mapper", sqlSessionFactoryRef = "manageSqlSessionFactory")
static class ManageMybatisDbConfig {
@Value("${zyplayer.doc.manage.datasource.driverClassName}")
private String driverClassName;
@Value("${zyplayer.doc.manage.datasource.url}")
private String url;
@Value("${zyplayer.doc.manage.datasource.username}")
private String username;
@Value("${zyplayer.doc.manage.datasource.password}")
private String password;
@Bean(name = "manageDatasource")
public DataSource manageDatasource() {
Properties xaProperties = new Properties();
xaProperties.setProperty("driverClassName", driverClassName);
xaProperties.setProperty("url", url);
xaProperties.setProperty("username", username);
xaProperties.setProperty("password", password);
xaProperties.setProperty("maxActive", "500");
xaProperties.setProperty("testOnBorrow", "true");
xaProperties.setProperty("testWhileIdle", "true");
xaProperties.setProperty("validationQuery", "select 'x'");
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaProperties(xaProperties);
xaDataSource.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
xaDataSource.setUniqueResourceName("manageDatasource");
xaDataSource.setMaxPoolSize(500);
xaDataSource.setMinPoolSize(1);
xaDataSource.setMaxLifetime(60);
return xaDataSource;
}
@Bean(name = "manageSqlSessionFactory")
public MybatisSqlSessionFactoryBean manageSqlSessionFactory() throws Exception {
MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(manageDatasource());
sqlSessionFactoryBean.setPlugins(new Interceptor[]{SQL_LOG_INTERCEPTOR});
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mapper/manage/*Mapper.xml"));
return sqlSessionFactoryBean;
}
}
@Bean
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
/* <!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 --> */
performanceInterceptor.setMaxTime(1000);
/* <!--SQL是否格式化 默认false--> */
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}

View File

@@ -1,72 +1,81 @@
spring:
application:
name: zyplayer-doc-manage
velocity:
layout-url: common/default.vm
cache: false
suffix: .vm
expose-spring-macro-helpers: true
date-tool-attribute: dateTool
number-tool-attribute: numberTool
contentType: text/html;charset=UTF-8
resource-loader-path: classpath:/vm/
default-content-type: text/html
ignore-accept-header: true
charset: UTF-8
properties:
input:
encoding: UTF-8
output:
encoding: UTF-8
# datasource:
# driver-class-name: com.mysql.jdbc.Driver
# url: jdbc:mysql://127.0.0.1:3306/zyplayer-doc-manage?characterEncoding=utf8&amp;zeroDateTimeBehavior=convertToNull&amp;autoReconnect=true
# username: root
# password: root
server:
port: 8082
servlet:
context-path: /zyplayer-doc-manage
zyplayer:
datasource:
manage:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/zyplayer-doc-manage?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&useSSL=false
username: root
password: root
mybatis-plus:
mapper-locations: classpath:/mapper/**/*Mapper.xml
#实体扫描多个package用逗号或者分号分隔
typeAliasesPackage: com.baomidou.springboot.entity
typeEnumsPackage: com.baomidou.springboot.entity.enums
global-config:
# 数据库相关配置
db-config:
#主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
id-type: id_worker
#字段策略 IGNORED:"忽略判断",NOT_NULL:"非 NULL 判断"),NOT_EMPTY:"非空判断"
field-strategy: not_empty
#驼峰下划线转换
column-underline: true
#数据库大写下划线转换
#capital-mode: true
#逻辑删除配置
logic-delete-value: 0
logic-not-delete-value: 1
db-type: mysql
#刷新mapper 调试神器
refresh: true
# 原生配置
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
#一些测试地址
#https://gitee.com/GeekPerson/central-platform 项目的文档
spring:
application:
name: zyplayer-doc-manage
velocity:
layout-url: common/default.vm
cache: false
suffix: .vm
expose-spring-macro-helpers: true
date-tool-attribute: dateTool
number-tool-attribute: numberTool
contentType: text/html;charset=UTF-8
resource-loader-path: classpath:/vm/
default-content-type: text/html
ignore-accept-header: true
charset: UTF-8
properties:
input:
encoding: UTF-8
output:
encoding: UTF-8
server:
port: 8082
servlet:
context-path: /zyplayer-doc-manage
zyplayer:
doc:
# zyplayer-doc-manage管理端的数据库配置
manage:
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/zyplayer-doc-manage?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&useSSL=false
username: root
password: root
# 数据库文档相关
# 打开/zyplayer-doc-manage/doc-db.html即可看到这里配置的数据库的文档
db:
dbConfigList:
- driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/zyplayer-doc-manage?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&useSSL=false
username: root
password: root
# 多个数据源直接这样累加
# - driverClassName: com.mysql.jdbc.Driver
# url: jdbc:mysql://127.0.0.1:3306/zyplayer-doc-manage?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&useSSL=false
# username: root
# password: root
mybatis-plus:
mapper-locations: classpath:/mapper/**/*Mapper.xml
#实体扫描多个package用逗号或者分号分隔
typeAliasesPackage: com.baomidou.springboot.entity
typeEnumsPackage: com.baomidou.springboot.entity.enums
global-config:
# 数据库相关配置
db-config:
#主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
id-type: id_worker
#字段策略 IGNORED:"忽略判断",NOT_NULL:"非 NULL 判断"),NOT_EMPTY:"非空判断"
field-strategy: not_empty
#驼峰下划线转换
column-underline: true
#数据库大写下划线转换
#capital-mode: true
#逻辑删除配置
logic-delete-value: 0
logic-not-delete-value: 1
db-type: mysql
#刷新mapper 调试神器
refresh: true
# 原生配置
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
#一些测试地址
#https://gitee.com/GeekPerson/central-platform 项目的文档
#http://47.99.88.28:9200/swagger-resources

View File

@@ -2,7 +2,7 @@ body{width: 100%;height: 100%;margin: 0;padding: 0;}
a:focus{outline:none;}
ul{list-style: none;list-style-type: none;}
.tree li a{white-space: nowrap;}
.tree-menu li > ul{background-color: #f1f1f1;}
.tree-menu li > ul{background-color: #555980;}
.tree-menu li li li li a{padding-left: 68px;}
.tree-menu li li li li li a{padding-left: 88px;}
.tree-menu li li li li li li a{padding-left: 108px;}
@@ -11,6 +11,11 @@ ul{list-style: none;list-style-type: none;}
.tree-menu li li li li li li li li li a{padding-left: 168px;}
.tree-menu li li li li li li li li li li a{padding-left: 188px;}
.table td, .table th {vertical-align: middle;}
.tree-menu li > a:active, .tree-menu li > a:focus, .tree-menu li > a:hover{color: #fff;}
.tree-menu li > a{color: #fff;}
.tree-menu > li > a{border-bottom-color: #555980;}
.tree-menu > li.open + li > a{border-bottom-color: #555980;border-top-color: #555980;}
.tree-lines ul > li::after{border-top:0;}
/**lable的覆盖样式*/
.label{font-size: 100%;}
@@ -32,7 +37,7 @@ label{font-weight: normal;}
width: 360px; height:100%; position: fixed; top: 0; bottom: 0; left: 0;
}
.left-header{
background: #3280fc;width: 100%; height:60px;line-height:60px;
background: #464a6e;width: 100%; height:60px;line-height:60px;
position: absolute; top: 0; bottom: 0; left: 0;text-align: center;
}
.left-header .logo{
@@ -42,7 +47,7 @@ label{font-weight: normal;}
font-size: 24px;float: right;margin: 18px 18px 0 0;color: #fff;cursor: pointer;
}
.left-container{
width: 100%;position: absolute;background: #f1f1f1;color: rgba(163, 175, 183, .9);
width: 100%;position: absolute;background: #555980;color: #fff;
top: 60px; bottom: 0; left: 0; overflow-y: auto; padding: 10px;
}
.left-container .projects{border: 0px; border-radius: 0px;}
@@ -59,7 +64,14 @@ label{font-weight: normal;}
#rightContentMask{background-color: rgba(0, 0, 0, 0);padding: 0;z-index:9999; height: 100%;display: none;position: absolute;top: 0;bottom: 0;left:0;right: 0;}
#rightZpages{height: 100%;position: relative;top: 0;bottom: 0;left:0;right: 0;}
#rightZpages .tabs-container .tab-pane{padding: 10px;}
/*#rightZpages .tabs-container .tab-pane{padding: 10px;}*/
#showLeftContent{
position: fixed;top: 250px; left: 0px;padding-top: 10px;
width: 15px;height: 35px;z-index: 9999;cursor: pointer;
background-color: #ccc;border-radius: 0 5px 5px 0;display: none;
}
#showLeftContent:hover{color: #fff;}
/* S-JSON展示的样式 */
pre.json{margin-top:0px;margin-bottom:0px;}

View File

@@ -9,7 +9,7 @@
<body>
<div id="app">
这是一个关于页面
这是一个关于页面,更多内容敬请关注:<a href="https://gitee.com/zyplayer/zyplayer-doc" target="_blank"> zyplayer-doc-manage</a>
</div>
</body>
@@ -23,7 +23,7 @@
</script>
<style>
body{padding: 10px;}
</style>
</html>

View File

@@ -56,7 +56,7 @@
</script>
<style>
body{padding: 10px;}
</style>
</html>

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>文档管理系统 - zyplayer</title>
<title>文档管理系统</title>
<link rel="shortcut icon" href="../lib/mg/img/api.ico"/>
<link rel="stylesheet" href="../lib/zui/css/zui.min.css" />
<link rel="stylesheet" href="../lib/zui/lib/dashboard/zui.dashboard.min.css" />
@@ -11,6 +11,9 @@
<link rel="stylesheet" href="../lib/mg/css/mg-ui.css" />
</head>
<body>
<div id="showLeftContent">
<i class="icon icon-chevron-right"></i>
</div>
<div class="left-body" id="leftContent">
<div class="left-header">
<span class="logo" id="logoText">zyplayer-doc-manage</span>
@@ -18,12 +21,30 @@
</div>
<div class="scrollbar-hover left-container">
<!-- 样式类可选tree-menu tree-folders tree-chevrons tree-angles -->
<ul class="tree tree-lines tree-menu projects" data-ride="tree">
<li id="tabZpagesNavigationLi">
<ul class="tree tree-lines tree-menu projects" data-ride="tree" id="tabZpagesNavigationUl">
<li>
<a href="#"><i class="icon icon-group"></i> 系统管理</a>
<ul>
<li><a href="#" class="page-nav" data-id="userManage" data-href="./user/manage.html" data-icon="icon-user" data-reload="0"><i class="icon-user"></i> 人员管理</a></li>
<li><a href="#" class="page-nav" data-id="authManage" data-href="./auth/manage.html" data-icon="icon-lock" data-reload="1"><i class="icon-lock"></i> 权限列表</a></li>
<li><a href="#" class="page-nav" data-id="user-manage" data-href="./user/manage.html" data-icon="icon-user" data-reload="0"><i class="icon-user"></i> 人员管理</a></li>
<li><a href="#" class="page-nav" data-id="auth-manage" data-href="./auth/manage.html" data-icon="icon-lock" data-reload="1"><i class="icon-lock"></i> 权限列表</a></li>
</ul>
</li>
<li>
<a href="#"><i class="icon icon-window-alt"></i> 文档查看页面</a>
<ul>
<li><a href="#" class="page-nav" data-id="zyplayer-doc-db" data-href="../../doc-db.html" data-icon="icon-database" data-reload="1"><i class="icon-database"></i> 数据库文档</a></li>
<li><a href="#" class="page-nav" data-id="zyplayer-doc-swagger" data-href="../../document.html" data-icon="icon-file-code" data-reload="1"><i class="icon-file-code"></i> zyplayer-doc-swagger</a></li>
<li><a href="#" class="page-nav" data-id="swagger-bootstrap-ui" data-href="../../doc.html" data-icon="icon-file-code" data-reload="1"><i class="icon-file-code"></i> swagger-bootstrap-ui</a></li>
<li><a href="#" class="page-nav" data-id="springfox-swagger-ui" data-href="../../swagger-ui.html" data-icon="icon-file-code" data-reload="1"><i class="icon-file-code"></i> springfox-swagger-ui</a></li>
</ul>
</li>
<li>
<a href="#"><i class="icon icon-window-alt"></i> 独立文档页面</a>
<ul>
<li><a target="_blank" href="../../doc-db.html"><i class="icon-window"></i> 数据库文档</a></li>
<li><a target="_blank" href="../../document.html"><i class="icon-window"></i> zyplayer-doc-swagger</a></li>
<li><a target="_blank" href="../../doc.html"><i class="icon-window"></i> swagger-bootstrap-ui</a></li>
<li><a target="_blank" href="../../swagger-ui.html"><i class="icon-window"></i> springfox-swagger-ui</a></li>
</ul>
</li>
</ul>
@@ -78,11 +99,26 @@
$("#rightContentMask").hide();
}
});
/**
* 切换导航栏的隐藏或显示
*/
$("#changeContentWidth").click(function(){
$("#leftContent").hide();
$("#showLeftContent").show();
changeContentWidth(0);
});
/**
* 切换导航栏的隐藏或显示
*/
$("#showLeftContent").click(function(){
$("#leftContent").show();
$("#showLeftContent").hide();
changeContentWidth(360);
});
/**
* 页面导航切换
*/
$("#tabZpagesNavigationLi").on("click", ".page-nav", function(){
$("#tabZpagesNavigationUl").on("click", ".page-nav", function(){
var id = $(this).data("id");
var href = $(this).data("href");
var icon = $(this).data("icon");

View File

@@ -221,6 +221,7 @@
</script>
<style>
body{padding: 10px;}
.modal-table-box{height: 200px;overflow-y: auto;}
.modal-table-box ul{padding-left: 10px;list-style: none;}
.modal-table-box li{float: left; border: 1px solid #ccc;padding: 10px 15px; margin: 0 10px 10px 0; background-color: #ccc;cursor: pointer;}

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>接口文档管理系统 - zyplayer</title>
<title>接口文档管理系统</title>
<link rel="shortcut icon" href="webjars/mg-ui/img/api.ico"/>
<link rel="stylesheet" href="webjars/zui/css/zui.min.css" />
<link rel="stylesheet" href="webjars/zui/lib/dashboard/zui.dashboard.min.css" />
@@ -28,7 +28,7 @@
</div>
</li>
<li id="homePageLi"><a href="javascript:void(0)" path=""><i class="icon-home"></i> 控制台</a></li>
<li id="tabZpagesNavigationLi">
<li id="tabZpagesNavigationUl">
<a href="#"><i class="icon icon-cogs"></i> 文档管理</a>
<ul>
<li id="onlineDebugLi1" class="local-storage"><a href="javascript:void(0)" path=""><i class="icon-bug"></i> 在线调试管理</a></li>

View File

@@ -222,7 +222,7 @@ $(".choise").on("click", "li", function(){
/**
* 页面导航切换
*/
$("#tabZpagesNavigationLi").on("click", ".page-nav", function(){
$("#tabZpagesNavigationUl").on("click", ".page-nav", function(){
var id = $(this).data("id");
var href = $(this).data("href");
var icon = $(this).data("icon");