initial version

This commit is contained in:
2023-04-06 14:46:15 +08:00
commit 4a967dc361
219 changed files with 142211 additions and 0 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
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
+166
View File
@@ -0,0 +1,166 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<groupId>cn.smallbun.screw</groupId>
<artifactId>screw</artifactId>
<version>1.0.6-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<packaging>jar</packaging>
<modelVersion>4.0.0</modelVersion>
<artifactId>screw-core</artifactId>
<dependencies>
<!--commons-lang-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!--logging-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
<!--HikariCP-->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<scope>provided</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<!-- velocity -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<scope>provided</scope>
</dependency>
<!--junit-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<!-- mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>provided</scope>
</dependency>
<!--sqlserver-->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>provided</scope>
</dependency>
<!-- mariadb-java-client -->
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<scope>provided</scope>
</dependency>
<!-- ojdbc8 -->
<dependency>
<groupId>com.oracle.ojdbc</groupId>
<artifactId>ojdbc8</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.easyproject</groupId>
<artifactId>orai18n</artifactId>
<scope>provided</scope>
</dependency>
<!-- postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>provided</scope>
</dependency>
<!--h2-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>provided</scope>
</dependency>
<!--db2-->
<dependency>
<groupId>com.ibm.db2</groupId>
<artifactId>jcc</artifactId>
<scope>provided</scope>
</dependency>
<!--hsqldb-->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>provided</scope>
</dependency>
<!--sqlite-->
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<scope>provided</scope>
</dependency>
<!-- slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<!-- logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
<profiles>
<profile>
<id>phoenix</id>
<dependencies>
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<version>5.0.0-HBase-2.0</version>
</dependency>
<!--与mysql中的 protobuf-java 冲突-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<exclusions>
<exclusion>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</profile>
</profiles>
<!--build-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,173 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.process.ProcessConfig;
import cn.smallbun.screw.core.util.Assert;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import javax.sql.DataSource;
import java.io.Serializable;
/**
* Screw 配置入口
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/19
*/
@Data
@NoArgsConstructor
public class Configuration implements Serializable {
/**
* 组织
*/
private String organization;
/**
* url
*/
private String organizationUrl;
/**
* 标题
*/
private String title;
/**
* 版本号
*/
private String version;
/**
* 描述
*/
private String description;
/**
* 数据源,这里直接使用@see{@link DataSource}接口,好处就,可以使用任何数据源
*/
private DataSource dataSource;
/**
* 生成配置
*/
private ProcessConfig produceConfig;
/**
* 引擎配置,关于数据库文档生成相关配置
*/
private EngineConfig engineConfig;
/**
* 构造函数
*
* @param title {@link String} 标题
* @param organization {@link String} 机构
* @param version {@link String} 版本
* @param description {@link String} 描述
* @param dataSource {@link DataSource} 数据源
* @param produceConfig {@link ProcessConfig} 生成配置
* @param engineConfig {@link EngineConfig} 生成配置
*/
private Configuration(String organization, String organizationUrl, String title, String version,
String description, DataSource dataSource, ProcessConfig produceConfig,
EngineConfig engineConfig) {
Assert.notNull(dataSource, "DataSource can not be empty!");
Assert.notNull(engineConfig, "EngineConfig can not be empty!");
this.title = title;
this.organizationUrl = organizationUrl;
this.organization = organization;
this.version = version;
this.description = description;
this.dataSource = dataSource;
this.engineConfig = engineConfig;
this.produceConfig = produceConfig;
}
/**
* builder
*
* @return {@link Configuration.ConfigurationBuilder}
*/
public static Configuration.ConfigurationBuilder builder() {
return new Configuration.ConfigurationBuilder();
}
@ToString
public static class ConfigurationBuilder {
private String organization;
private String organizationUrl;
private String title;
private String version;
private String description;
private DataSource dataSource;
private ProcessConfig produceConfig;
private EngineConfig engineConfig;
ConfigurationBuilder() {
}
public Configuration.ConfigurationBuilder organization(String org) {
this.organization = org;
return this;
}
public Configuration.ConfigurationBuilder organizationUrl(String orgUrl) {
this.organizationUrl = orgUrl;
return this;
}
public Configuration.ConfigurationBuilder title(String title) {
this.title = title;
return this;
}
public Configuration.ConfigurationBuilder version(String version) {
this.version = version;
return this;
}
public Configuration.ConfigurationBuilder description(String description) {
this.description = description;
return this;
}
public Configuration.ConfigurationBuilder dataSource(DataSource dataSource) {
this.dataSource = dataSource;
return this;
}
public Configuration.ConfigurationBuilder produceConfig(ProcessConfig processConfig) {
this.produceConfig = processConfig;
return this;
}
public Configuration.ConfigurationBuilder engineConfig(EngineConfig engineConfig) {
this.engineConfig = engineConfig;
return this;
}
/**
* build
*
* @return {@link Configuration}
*/
public Configuration build() {
return new Configuration(this.organization, this.organizationUrl, this.title,
this.version, this.description, this.dataSource, this.produceConfig,
this.engineConfig);
}
}
}
@@ -0,0 +1,41 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core;
import java.io.Serializable;
/**
* Screw Version
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/28 15:02
*/
public class Version implements Serializable {
private Version() {
}
/**
* 获取版本号
*
* @return {@link String} 版本号
*/
public static String getVersion() {
Package pkg = Version.class.getPackage();
return (pkg != null ? pkg.getImplementationVersion() : null);
}
}
@@ -0,0 +1,106 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.constant;
import java.io.Serializable;
/**
* 默认常量
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/20 18:33
*/
public class DefaultConstants implements Serializable {
/**
* 名称
*/
public static final String NAME = "screw";
/**
* 百分号
*/
public static final String PERCENT_SIGN = "%";
/**
* 暂未支持
*/
public static final String NOT_SUPPORTED = "Not supported yet!";
/**
* 默认字符集
*/
public static final String DEFAULT_ENCODING = "UTF-8";
/**
* 默认国际化
*/
public static final String DEFAULT_LOCALE = "zh_CN";
/**
* Mac
*/
public static final String MAC = "Mac";
/**
* Windows
*/
public static final String WINDOWS = "Windows";
/**
* 小数点0
*/
public static final String ZERO_DECIMAL_DIGITS = "0";
/**
* 默认描述
*/
public static final String DESCRIPTION = "Database design documents";
/**
* mysql useInformationSchema
*/
public static final String USE_INFORMATION_SCHEMA = "useInformationSchema";
/**
* oracle 连接参数备注
*/
public static final String ORACLE_REMARKS = "remarks";
/**
* 日志开始
*/
public static final String LOGGER_BEGINS = "Database design document generation begins 🚀";
/**
* 日志结束
*/
public static final String LOGGER_COMPLETE = "Database design document generation is complete , time cost:%s second 🎇";
/**
* 零
*/
public static final String ZERO = "0";
/**
* N
*/
public static final String N = "N";
/**
* Y
*/
public static final String Y = "Y";
/**
* phoenix 命名空间
*/
public static final String PHOENIX_NAMESPACE_MAPPING = "phoenix.schema.isNamespaceMappingEnabled";
/**
* phoenix 系统命名空间
*/
public static final String PHOENIX_SYS_NAMESPACE_MAPPING = "phoenix.schema.mapSystemTablesToNamespace";
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Constants
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 15:30
*/
package cn.smallbun.screw.core.constant;
@@ -0,0 +1,110 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.engine;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.ExceptionUtils;
import cn.smallbun.screw.core.util.StringUtils;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import static cn.smallbun.screw.core.constant.DefaultConstants.MAC;
import static cn.smallbun.screw.core.constant.DefaultConstants.WINDOWS;
/**
* AbstractProduce
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 21:47
*/
@Data
public abstract class AbstractTemplateEngine implements TemplateEngine {
/**
* 日志
*/
final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 模板配置
*/
private EngineConfig engineConfig;
private AbstractTemplateEngine() {
}
public AbstractTemplateEngine(EngineConfig engineConfig) {
Assert.notNull(engineConfig, "EngineConfig can not be empty!");
this.engineConfig = engineConfig;
}
/**
* 获取文件,文件名格式为,数据库名_版本号.文件类型
*
* @param docName 文档名称
* @return {@link String}
*/
protected File getFile(String docName) {
File file;
//如果没有填写输出路径,默认当前项目路径下的doc目录
if (StringUtils.isBlank(getEngineConfig().getFileOutputDir())) {
String dir = System.getProperty("user.dir");
file = new File(dir + "/doc");
} else {
file = new File(getEngineConfig().getFileOutputDir());
}
//不存在创建
if (!file.exists()) {
//创建文件夹
boolean mkdir = file.mkdirs();
}
//文件后缀
String suffix = getEngineConfig().getFileType().getFileSuffix();
file = new File(file, docName + suffix);
//设置文件产生位置
getEngineConfig().setFileOutputDir(file.getParent());
return file;
}
/**
* 打开文档生成的输出目录
*/
protected void openOutputDir() {
//是否打开,如果是就打开输出路径
if (getEngineConfig().isOpenOutputDir()
&& StringUtils.isNotBlank(getEngineConfig().getFileOutputDir())) {
try {
//获取系统信息
String osName = System.getProperty("os.name");
if (osName != null) {
if (osName.contains(MAC)) {
Runtime.getRuntime().exec("open " + getEngineConfig().getFileOutputDir());
} else if (osName.contains(WINDOWS)) {
Runtime.getRuntime()
.exec("cmd /c start " + getEngineConfig().getFileOutputDir());
}
}
} catch (IOException e) {
throw ExceptionUtils.mpe(e);
}
}
}
}
@@ -0,0 +1,58 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.engine;
import lombok.Builder;
import lombok.Data;
import java.io.Serializable;
/**
* 文件生成配置
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 18:19
*/
@Data
@Builder
public class EngineConfig implements Serializable {
/**
* 是否打开输出目录
*/
private boolean openOutputDir;
/**
* 文件产生位置
*/
private String fileOutputDir;
/**
* 生成文件类型
*/
private EngineFileType fileType;
/**
* 生成实现
*/
private EngineTemplateType produceType;
/**
* 自定义模板,模板需要和文件类型和使用模板的语法进行编写和处理,否则将会生成错误
*/
private String customTemplate;
/**
* 文件名称
*/
private String fileName;
}
@@ -0,0 +1,69 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.engine;
import cn.smallbun.screw.core.exception.ProduceException;
import cn.smallbun.screw.core.util.Assert;
import lombok.Getter;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* 生成构造工厂
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/21 21:20
*/
public class EngineFactory implements Serializable {
/**
* EngineConfig
*/
@Getter
private EngineConfig engineConfig;
public EngineFactory(EngineConfig configuration) {
Assert.notNull(configuration, "EngineConfig can not be empty!");
this.engineConfig = configuration;
}
private EngineFactory() {
}
/**
* 获取配置的数据库类型实例
*
* @return {@link TemplateEngine} 数据库查询对象
*/
public TemplateEngine newInstance() {
try {
//获取实现类
Class<? extends TemplateEngine> query = this.engineConfig.getProduceType()
.getImplClass();
//获取有参构造
Constructor<? extends TemplateEngine> constructor = query
.getConstructor(EngineConfig.class);
//实例化
return (TemplateEngine) constructor.newInstance(engineConfig);
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException
| InvocationTargetException e) {
throw new ProduceException(e);
}
}
}
@@ -0,0 +1,70 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.engine;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* 文件类型
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/21 21:08
*/
public enum EngineFileType implements Serializable {
/**
* HTML
*/
HTML(".html", "documentation_html", "HTML文件"),
/**
* WORD
*/
WORD(".doc", "documentation_word", "WORD文件"),
/**
* MD
*/
MD(".md", "documentation_md", "Markdown文件");
/**
* 文件后缀
*/
@Getter
@Setter
private String fileSuffix;
/**
* 模板文件
*/
@Getter
@Setter
private String templateNamePrefix;
/**
* 描述
*/
@Getter
@Setter
private String desc;
EngineFileType(String type, String templateFile, String desc) {
this.fileSuffix = type;
this.templateNamePrefix = templateFile;
this.desc = desc;
}
}
@@ -0,0 +1,77 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.engine;
import cn.smallbun.screw.core.engine.freemark.FreemarkerTemplateEngine;
import cn.smallbun.screw.core.engine.velocity.VelocityTemplateEngine;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* 模板类型
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/21 20:07
*/
public enum EngineTemplateType implements Serializable {
/**
* velocity 模板
*/
velocity("/template/velocity/",
VelocityTemplateEngine.class,
".vm"),
/**
* freeMarker 模板
*/
freemarker("/template/freemarker/",
FreemarkerTemplateEngine.class,
".ftl");
/**
* 模板目录
*/
@Getter
@Setter
private String templateDir;
/**
* 模板驱动实现类类型
*/
@Getter
@Setter
private Class<? extends TemplateEngine> implClass;
/**
* 后缀
*/
@Getter
@Setter
private String suffix;
/**
* 构造
*
* @param freemarker {@link String}
* @param template {@link Class}
*/
EngineTemplateType(String freemarker, Class<? extends TemplateEngine> template, String suffix) {
this.templateDir = freemarker;
this.implClass = template;
this.suffix = suffix;
}
}
@@ -0,0 +1,41 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.engine;
import cn.smallbun.screw.core.exception.ProduceException;
import cn.smallbun.screw.core.metadata.model.DataModel;
import java.io.Serializable;
/**
* 文件产生接口
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 21:47
*/
public interface TemplateEngine extends Serializable {
/**
* 生成文档
*
* @param info {@link DataModel}
* @param docName {@link String}
* @throws ProduceException ProduceException
*/
void produce(DataModel info, String docName) throws ProduceException;
}
@@ -0,0 +1,124 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.engine.freemark;
import cn.smallbun.screw.core.engine.AbstractTemplateEngine;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.exception.ProduceException;
import cn.smallbun.screw.core.metadata.model.DataModel;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.ExceptionUtils;
import cn.smallbun.screw.core.util.FileUtils;
import cn.smallbun.screw.core.util.StringUtils;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.*;
import java.util.Locale;
import java.util.Objects;
import static cn.smallbun.screw.core.constant.DefaultConstants.DEFAULT_ENCODING;
import static cn.smallbun.screw.core.constant.DefaultConstants.DEFAULT_LOCALE;
import static cn.smallbun.screw.core.engine.EngineTemplateType.freemarker;
import static cn.smallbun.screw.core.util.FileUtils.getFileByPath;
import static cn.smallbun.screw.core.util.FileUtils.isFileExists;
/**
* freemarker template produce
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 21:40
*/
public class FreemarkerTemplateEngine extends AbstractTemplateEngine {
/**
* freemarker 配置实例化
*/
private final Configuration configuration = new Configuration(
Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
{
try {
String path = getEngineConfig().getCustomTemplate();
//自定义模板
if (StringUtils.isNotBlank(path) && FileUtils.isFileExists(path)) {
//获取父目录
String parent = Objects.requireNonNull(getFileByPath(path)).getParent();
//设置模板加载路径
configuration.setDirectoryForTemplateLoading(new File(parent));
}
//加载自带模板
else {
//模板存放路径
configuration.setTemplateLoader(
new ClassTemplateLoader(this.getClass(), freemarker.getTemplateDir()));
}
//编码
configuration.setDefaultEncoding(DEFAULT_ENCODING);
//国际化
configuration.setLocale(new Locale(DEFAULT_LOCALE));
} catch (Exception e) {
throw ExceptionUtils.mpe(e);
}
}
public FreemarkerTemplateEngine(EngineConfig templateConfig) {
super(templateConfig);
}
/**
* 生成文档
*
* @param info {@link DataModel}
* @throws ProduceException ProduceException
*/
@Override
public void produce(DataModel info, String docName) throws ProduceException {
Assert.notNull(info, "DataModel can not be empty!");
String path = getEngineConfig().getCustomTemplate();
try {
Template template;
// freemarker template
// 如果自定义路径不为空文件也存在
if (StringUtils.isNotBlank(path) && isFileExists(path)) {
// 文件名称
String fileName = new File(path).getName();
template = configuration.getTemplate(fileName);
}
//获取系统默认的模板
else {
template = configuration
.getTemplate(getEngineConfig().getFileType().getTemplateNamePrefix()
+ freemarker.getSuffix());
}
// create file
File file = getFile(docName);
// writer freemarker
try (Writer out = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(file), DEFAULT_ENCODING))) {
// process
template.process(info, out);
// open the output directory
openOutputDir();
}
} catch (IOException | TemplateException e) {
throw ExceptionUtils.mpe(e);
}
}
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Document generation engine freemark implement
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 15:58
*/
package cn.smallbun.screw.core.engine.freemark;
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Document generation engine
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 15:29
*/
package cn.smallbun.screw.core.engine;
@@ -0,0 +1,126 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.engine.velocity;
import cn.smallbun.screw.core.engine.AbstractTemplateEngine;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.exception.ProduceException;
import cn.smallbun.screw.core.metadata.model.DataModel;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.ExceptionUtils;
import cn.smallbun.screw.core.util.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.log.NullLogChute;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import static cn.smallbun.screw.core.constant.DefaultConstants.DEFAULT_ENCODING;
import static cn.smallbun.screw.core.engine.EngineTemplateType.velocity;
/**
* velocity template
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 21:40
*/
public class VelocityTemplateEngine extends AbstractTemplateEngine {
/**
* DATA
*/
private static final String DATA = "_data";
/**
* 构造函数
*
* @param templateConfig {@link EngineConfig }
*/
public VelocityTemplateEngine(EngineConfig templateConfig) {
super(templateConfig);
}
/**
* VelocityEngine
*/
private static VelocityEngine velocityEngine;
{
// 初始化模板引擎
velocityEngine = new VelocityEngine();
// 如果存在自定义模板
if (StringUtils.isNotBlank(getEngineConfig().getCustomTemplate())) {
velocityEngine.setProperty("string.resource.loader.class",
"org.apache.velocity.runtime.resource.loader.StringResourceLoader");
} else {
velocityEngine.setProperty("file.resource.loader.class",
"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
}
velocityEngine.setProperty("runtime.log.logsystem.class", NullLogChute.class.getName());
velocityEngine.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "");
velocityEngine.setProperty(Velocity.ENCODING_DEFAULT, DEFAULT_ENCODING);
velocityEngine.setProperty(Velocity.INPUT_ENCODING, DEFAULT_ENCODING);
velocityEngine.setProperty("file.resource.loader.unicode", "true");
}
/**
* 生成文档
*
* @param info {@link DataModel}
* @throws ProduceException ProduceException
*/
@Override
public void produce(DataModel info, String docName) throws ProduceException {
Assert.notNull(info, "DataModel can not be empty!");
Template template;
try {
// get template path
String path = getEngineConfig().getCustomTemplate();
//如果自定义了模板
if (StringUtils.isNotBlank(path)) {
template = velocityEngine.getTemplate(path, DEFAULT_ENCODING);
}
//没有自定义模板,使用核心包自带
else {
template = velocityEngine
.getTemplate(velocity.getTemplateDir()
+ getEngineConfig().getFileType().getTemplateNamePrefix()
+ velocity.getSuffix(),
DEFAULT_ENCODING);
}
// output
try (FileOutputStream outStream = new FileOutputStream(getFile(docName));
OutputStreamWriter writer = new OutputStreamWriter(outStream, DEFAULT_ENCODING);
BufferedWriter sw = new BufferedWriter(writer)) {
//put data
VelocityContext context = new VelocityContext();
context.put(DATA, info);
//generate
template.merge(context, sw);
// open the output directory
openOutputDir();
}
} catch (IOException e) {
throw ExceptionUtils.mpe(e);
}
}
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Document generation engine velocity implement
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 15:59
*/
package cn.smallbun.screw.core.engine.velocity;
@@ -0,0 +1,100 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.exception;
/**
* 构建异常
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/21 23:21
*/
public class BuilderException extends ScrewException {
/**
* Constructs a new runtime exception with {@code null} as its
* detail message. The cause is not initialized, and may subsequently be
* initialized by a call to {@link #initCause}.
*/
public BuilderException() {
}
/**
* Constructs a new runtime exception with the specified detail message.
* The cause is not initialized, and may subsequently be initialized by a
* call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public BuilderException(String message) {
super(message);
}
/**
* Constructs a new runtime exception with the specified detail message and
* cause. <p>Note that the detail message associated with
* {@code cause} is <i>not</i> automatically incorporated in
* this runtime exception's detail message.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public BuilderException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new runtime exception with the specified cause and a
* detail message of <tt>(cause==null ? null : cause.toString())</tt>
* (which typically contains the class and detail message of
* <tt>cause</tt>). This constructor is useful for runtime exceptions
* that are little more than wrappers for other throwables.
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public BuilderException(Throwable cause) {
super(cause);
}
/**
* Constructs a new runtime exception with the specified detail
* message, cause, suppression enabled or disabled, and writable
* stack trace enabled or disabled.
*
* @param message the detail message.
* @param cause the cause. (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @param enableSuppression whether or not suppression is enabled
* or disabled
* @param writableStackTrace whether or not the stack trace should
* be writable
* @since 1.7
*/
public BuilderException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
@@ -0,0 +1,46 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.exception;
/**
* MappingException
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/25 21:59
*/
public class MappingException extends ScrewException {
public MappingException() {
}
public MappingException(String message) {
super(message);
}
public MappingException(String message, Throwable cause) {
super(message, cause);
}
public MappingException(Throwable cause) {
super(cause);
}
public MappingException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
@@ -0,0 +1,100 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.exception;
/**
* 文档生成异常
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/21 23:58
*/
public class ProduceException extends ScrewException {
/**
* Constructs a new runtime exception with {@code null} as its
* detail message. The cause is not initialized, and may subsequently be
* initialized by a call to {@link #initCause}.
*/
public ProduceException() {
}
/**
* Constructs a new runtime exception with the specified detail message.
* The cause is not initialized, and may subsequently be initialized by a
* call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public ProduceException(String message) {
super(message);
}
/**
* Constructs a new runtime exception with the specified detail message and
* cause. <p>Note that the detail message associated with
* {@code cause} is <i>not</i> automatically incorporated in
* this runtime exception's detail message.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public ProduceException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new runtime exception with the specified cause and a
* detail message of <tt>(cause==null ? null : cause.toString())</tt>
* (which typically contains the class and detail message of
* <tt>cause</tt>). This constructor is useful for runtime exceptions
* that are little more than wrappers for other throwables.
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public ProduceException(Throwable cause) {
super(cause);
}
/**
* Constructs a new runtime exception with the specified detail
* message, cause, suppression enabled or disabled, and writable
* stack trace enabled or disabled.
*
* @param message the detail message.
* @param cause the cause. (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @param enableSuppression whether or not suppression is enabled
* or disabled
* @param writableStackTrace whether or not the stack trace should
* be writable
* @since 1.7
*/
public ProduceException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
@@ -0,0 +1,100 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.exception;
/**
* 查询异常
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/21 23:21
*/
public class QueryException extends ScrewException {
/**
* Constructs a new runtime exception with {@code null} as its
* detail message. The cause is not initialized, and may subsequently be
* initialized by a call to {@link #initCause}.
*/
public QueryException() {
}
/**
* Constructs a new runtime exception with the specified detail message.
* The cause is not initialized, and may subsequently be initialized by a
* call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public QueryException(String message) {
super(message);
}
/**
* Constructs a new runtime exception with the specified detail message and
* cause. <p>Note that the detail message associated with
* {@code cause} is <i>not</i> automatically incorporated in
* this runtime exception's detail message.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public QueryException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new runtime exception with the specified cause and a
* detail message of <tt>(cause==null ? null : cause.toString())</tt>
* (which typically contains the class and detail message of
* <tt>cause</tt>). This constructor is useful for runtime exceptions
* that are little more than wrappers for other throwables.
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public QueryException(Throwable cause) {
super(cause);
}
/**
* Constructs a new runtime exception with the specified detail
* message, cause, suppression enabled or disabled, and writable
* stack trace enabled or disabled.
*
* @param message the detail message.
* @param cause the cause. (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @param enableSuppression whether or not suppression is enabled
* or disabled
* @param writableStackTrace whether or not the stack trace should
* be writable
* @since 1.7
*/
public QueryException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
@@ -0,0 +1,101 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.exception;
/**
* Screw exception
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 20:54
*/
public class ScrewException extends RuntimeException {
/**
* Constructs a new runtime exception with {@code null} as its
* detail message. The cause is not initialized, and may subsequently be
* initialized by a call to {@link #initCause}.
*/
public ScrewException() {
super();
}
/**
* Constructs a new runtime exception with the specified detail message.
* The cause is not initialized, and may subsequently be initialized by a
* call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public ScrewException(String message) {
super(message);
}
/**
* Constructs a new runtime exception with the specified detail message and
* cause. <p>Note that the detail message associated with
* {@code cause} is <i>not</i> automatically incorporated in
* this runtime exception's detail message.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public ScrewException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new runtime exception with the specified cause and a
* detail message of <tt>(cause==null ? null : cause.toString())</tt>
* (which typically contains the class and detail message of
* <tt>cause</tt>). This constructor is useful for runtime exceptions
* that are little more than wrappers for other throwables.
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A <tt>null</tt> value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.4
*/
public ScrewException(Throwable cause) {
super(cause);
}
/**
* Constructs a new runtime exception with the specified detail
* message, cause, suppression enabled or disabled, and writable
* stack trace enabled or disabled.
*
* @param message the detail message.
* @param cause the cause. (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @param enableSuppression whether or not suppression is enabled
* or disabled
* @param writableStackTrace whether or not the stack trace should
* be writable
* @since 1.7
*/
protected ScrewException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Exception Class
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 15:29
*/
package cn.smallbun.screw.core.exception;
@@ -0,0 +1,70 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.execute;
import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static cn.smallbun.screw.core.constant.DefaultConstants.DESCRIPTION;
/**
* 抽象执行
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/4/1 22:51
*/
public abstract class AbstractExecute implements Execute {
/**
* LOGGER
*/
final Logger logger = LoggerFactory.getLogger(this.getClass());
protected Configuration config;
public AbstractExecute(Configuration config) {
Assert.notNull(config, "Configuration can not be empty!");
this.config = config;
}
/**
* 获取文档名称
*
* @param database {@link String}
* @return {@link String} 名称
*/
String getDocName(String database) {
//自定义文件名称不为空
if (StringUtils.isNotBlank(config.getEngineConfig().getFileName())) {
return config.getEngineConfig().getFileName();
}
//描述
String description = config.getDescription();
if (StringUtils.isBlank(description)) {
description = DESCRIPTION;
}
//版本号
String version = config.getVersion();
if (StringUtils.isBlank(version)) {
return database + "_" + description;
}
return database + "_" + description + "_" + version;
}
}
@@ -0,0 +1,60 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.execute;
import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineFactory;
import cn.smallbun.screw.core.engine.TemplateEngine;
import cn.smallbun.screw.core.exception.BuilderException;
import cn.smallbun.screw.core.metadata.model.DataModel;
import cn.smallbun.screw.core.process.DataModelProcess;
import cn.smallbun.screw.core.util.ExceptionUtils;
/**
* 文档生成
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/4/1 22:51
*/
public class DocumentationExecute extends AbstractExecute {
public DocumentationExecute(Configuration config) {
super(config);
}
/**
* 执行
*
* @throws BuilderException BuilderException
*/
@Override
public void execute() throws BuilderException {
try {
long start = System.currentTimeMillis();
//处理数据
DataModel dataModel = new DataModelProcess(config).process();
//产生文档
TemplateEngine produce = new EngineFactory(config.getEngineConfig()).newInstance();
produce.produce(dataModel, getDocName(dataModel.getDatabase()));
logger.debug("database document generation complete time consuming:{}ms",
System.currentTimeMillis() - start);
} catch (Exception e) {
throw ExceptionUtils.mpe(e);
}
}
}
@@ -0,0 +1,31 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.execute;
/**
* 执行文档生成
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/4/1 22:38
*/
public interface Execute {
/**
* 执行生成
*/
void execute();
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Document generation and execution
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 15:29
*/
package cn.smallbun.screw.core.execute;
@@ -0,0 +1,77 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.mapping;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* FieldMethod
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/25
*/
public class FieldMethod {
/**
* 属性
*/
private Field field;
/**
* 方法
*/
private Method method;
/**
* Getter method for property <tt>field</tt>.
*
* @return property value of field
*/
public Field getField() {
return field;
}
/**
* Setter method for property <tt>field</tt>.
*
* @param field value to be assigned to property field
*/
public void setField(Field field) {
this.field = field;
}
/**
* Getter method for property <tt>method</tt>.
*
* @return property value of method
*/
public Method getMethod() {
return method;
}
/**
* Setter method for property <tt>method</tt>.
*
* @param method value to be assigned to property method
*/
public void setMethod(Method method) {
this.method = method;
}
}
@@ -0,0 +1,262 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.mapping;
import cn.smallbun.screw.core.exception.MappingException;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.*;
/**
* 映射器
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/25
*/
public class Mapping {
private Mapping() {
}
/**
* 将ResultSet 结果转为对象
*
* @param <T> 领域泛型
* @param resultSet {@link ResultSet} 对象
* @param clazz 领域类型
* @return 领域对象
* @throws MappingException MappingException
*/
public static <T> T convert(ResultSet resultSet, Class<T> clazz) throws MappingException {
//存放列名和结果
Map<String, Object> values = new HashMap<>(16);
try {
//处理 ResultSet
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
//迭代
while (resultSet.next()) {
//放入内存
for (int i = 1; i <= columnCount; i++) {
String columnName = metaData.getColumnName(i);
values.put(columnName, resultSet.getString(columnName));
}
}
//有结果
if (values.size() != 0) {
//获取类数据
List<FieldMethod> fieldMethods = getFieldMethods(clazz);
//设置属性值
return getObject(clazz, fieldMethods, values);
}
return clazz.newInstance();
} catch (Exception e) {
throw new MappingException(e);
}
}
/**
* @param resultSet {@link ResultSet} 对象
* @param clazz 领域类型
* @param <T> 领域泛型
* @return 领域对象
* @throws MappingException MappingException
*/
public static <T> List<T> convertList(ResultSet resultSet,
Class<T> clazz) throws MappingException {
//存放列名和结果
List<Map<String, Object>> values = new ArrayList<>(16);
//结果集合
List<T> list = new ArrayList<>();
try {
//处理 ResultSet
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
//迭代
while (resultSet.next()) {
//map object
HashMap<String, Object> value = new HashMap<>(16);
//循环所有的列,获取列名,根据列名获取值
for (int i = 1; i <= columnCount; i++) {
String columnName = metaData.getColumnName(i);
value.put(columnName, resultSet.getString(i));
}
//add object
values.add(value);
}
//获取类数据
List<FieldMethod> fieldMethods = getFieldMethods(clazz);
//循环集合,根据类型反射构建对象
for (Map<String, Object> map : values) {
T rsp = getObject(clazz, fieldMethods, map);
list.add(rsp);
}
} catch (Exception e) {
throw new MappingException(e);
}
return list;
}
/**
* 根据列标签获取列信息
*
* @param resultSet {@link ResultSet} 对象
* @param clazz 领域类型
* @param <T> 领域泛型
* @return 领域对象
* @throws MappingException MappingException
*/
public static <T> List<T> convertListByColumnLabel(ResultSet resultSet,
Class<T> clazz) throws MappingException {
//存放列名和结果
List<Map<String, Object>> values = new ArrayList<>(16);
//结果集合
List<T> list = new ArrayList<>();
try {
//处理 ResultSet
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
//迭代
while (resultSet.next()) {
//map object
HashMap<String, Object> value = new HashMap<>(16);
//循环所有的列,获取列名,根据列名获取值
for (int i = 1; i <= columnCount; i++) {
String columnName = metaData.getColumnLabel(i);
value.put(columnName, resultSet.getString(i));
}
//add object
values.add(value);
}
//获取类数据
List<FieldMethod> fieldMethods = getFieldMethods(clazz);
//循环集合,根据类型反射构建对象
for (Map<String, Object> map : values) {
T rsp = getObject(clazz, fieldMethods, map);
list.add(rsp);
}
} catch (Exception e) {
throw new MappingException(e);
}
return list;
}
/**
* 获取对象
*
* @param clazz class
* @param fieldMethods List<FieldMethod>
* @param map 数据集合
* @param <T> 领域泛型
* @return 领域对象
* @throws InstantiationException InstantiationException
* @throws IllegalAccessException IllegalAccessException
* @throws InvocationTargetException InvocationTargetException
*/
private static <T> T getObject(Class<T> clazz, List<FieldMethod> fieldMethods,
Map<String, Object> map) throws InstantiationException,
IllegalAccessException,
InvocationTargetException {
T rsp = clazz.newInstance();
//设置属性值
for (FieldMethod filed : fieldMethods) {
Field field = filed.getField();
Method method = filed.getMethod();
MappingField jsonField = field.getAnnotation(MappingField.class);
if (!Objects.isNull(jsonField)) {
method.invoke(rsp, map.get(jsonField.value()));
}
}
return rsp;
}
/**
* 根据类型获取 FieldMethod
*
* @param clazz {@link Class}
* @param <T> {@link T}
* @return {@link List<FieldMethod>}
* @throws IntrospectionException IntrospectionException
* @throws NoSuchFieldException NoSuchFieldException
*/
private static <T> List<FieldMethod> getFieldMethods(Class<T> clazz) throws IntrospectionException,
NoSuchFieldException {
//结果集合
List<FieldMethod> fieldMethods = new ArrayList<>();
//BeanInfo
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
//循环处理值
for (PropertyDescriptor pd : pds) {
Method writeMethod = pd.getWriteMethod();
if (writeMethod == null) {
continue;
}
//获取字段
Field field = clazz.getDeclaredField(pd.getName());
//获取只写方法
FieldMethod fieldMethod = new FieldMethod();
fieldMethod.setField(field);
fieldMethod.setMethod(writeMethod);
//放入集合
fieldMethods.add(fieldMethod);
}
return fieldMethods;
}
/**
* 尝试获取属性
* <p>
* 不会抛出异常,不存在则返回null
*
* @param clazz {@link Class}
* @param itemName {@link String}
* @return {@link Field}
*/
private static Field tryGetFieldWithoutExp(Class<?> clazz, String itemName) {
try {
return clazz.getDeclaredField(itemName);
} catch (Exception e) {
return null;
}
}
/**
* 获取属性设置属性
*
* @param clazz {@link Class}
* @param field {@link Field}
* @return {@link Method}
*/
private static <T> Method tryGetSetMethod(Class<T> clazz, Field field, String methodName) {
try {
return clazz.getDeclaredMethod(methodName, field.getType());
} catch (Exception e) {
return null;
}
}
}
@@ -0,0 +1,41 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.mapping;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 数据结构属性注解
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/25
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { ElementType.FIELD })
public @interface MappingField {
/**
* 属性映射名称
* @return {@link String}
**/
String value() default "";
}
@@ -0,0 +1,40 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.mapping;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 数据结构列表属性注解
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/16
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { ElementType.FIELD })
public @interface MappingListField {
/**
* JSON列表属性映射名称
* @return {@link String}
**/
String value() default "";
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Data mapping
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 15:29
*/
package cn.smallbun.screw.core.mapping;
@@ -0,0 +1,117 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.metadata;
import java.io.Serializable;
/**
* 表列接口
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/28 15:05
*/
public interface Column extends Serializable {
/**
* 获取表名
*
* @return {@link String}
*/
String getTableName();
/**
* 表中的列的索引(从 1 开始)
*
* @return {@link String}
*/
String getOrdinalPosition();
/**
* 名称
*
* @return {@link String}
*/
String getColumnName();
/**
* 列的数据类型名称
*
* @return {@link String}
*/
String getTypeName();
/**
* 列表示给定列的指定列大小。
* 对于数值数据,这是最大精度。
* 对于字符数据,这是字符长度。
* 对于日期时间数据类型,这是 String 表示形式的字符长度(假定允许的最大小数秒组件的精度)。
* 对于二进制数据,这是字节长度。
* 对于 ROWID 数据类型,这是字节长度。对于列大小不适用的数据类型,则返回 Null。
*
* @return {@link String}
*/
String getColumnSize();
/**
* 小数位
*
* @return {@link String}
*/
String getDecimalDigits();
/**
* 可为空
*
* @return {@link String}
*/
String getNullable();
/**
* 是否主键
*
* @return {@link Boolean}
*/
String getPrimaryKey();
/**
* 默认值
*
* @return {@link String}
*/
String getColumnDef();
/**
* 说明
*
* @return {@link String}
*/
String getRemarks();
/**
* 获取列类型
* @return {@link String}
*/
String getColumnType();
/**
* 获取列长度
*
* @return {@link String}
*/
String getColumnLength();
}
@@ -0,0 +1,49 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.metadata;
import java.io.Serializable;
/**
* 列长度
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/8/25 10:53
*/
public interface ColumnLength extends Serializable {
/**
* 表名
*
* @return {@link String}
*/
String getTableName();
/**
* 列名
*
* @return {@link String}
*/
String getColumnName();
/**
* 列长度
*
* @return {@link String}
*/
String getColumnLength();
}
@@ -0,0 +1,39 @@
package cn.smallbun.screw.core.metadata;
import java.io.Serializable;
/**
* 自定义类型
*/
public interface CustomType extends Serializable {
/**
* 获取类型名称
* @return
*/
String getTypeName();
/**
*
* @return
*/
String getAttrName();
/**
* 获取类型编码
* @return
*/
String getAttrTypeName();
/**
* 获取属性长度
* @return
*/
String getLength();
/**
* 获取属性编号
* @return
*/
String getAttrNo();
}
@@ -0,0 +1,41 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.metadata;
import cn.smallbun.screw.core.metadata.model.CustomTypeModel;
import cn.smallbun.screw.core.query.oracle.model.OracleTypesModel;
import java.io.Serializable;
import java.util.List;
/**
* 数据库接口
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/28 15:05
*/
public interface Database extends Serializable {
/**
* 获取数据库名称
*
* @return {@link String}
*/
String getDatabase();
List<OracleTypesModel> getTypes();
}
@@ -0,0 +1,40 @@
package cn.smallbun.screw.core.metadata;
import java.io.Serializable;
/**
* 外鍵以及外鍵信息 外鍵字段 外鍵約束字段以及外鍵關聯表
*/
public interface ForeignKey extends Serializable {
/**
* 表名
*
* @return {@link String}
*/
String getTableName();
/**
* 外键名称
*
* @return {@link String}
*/
String getConstraintName();
/**
* 列名
*
* @return {@link String}
*/
String getColumnName();
/**
* 约束键
* @return
*/
String getConstraintKey();
/**
* 字段外鍵關聯表
*/
String getReferencedTable();
}
@@ -0,0 +1,56 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.metadata;
import java.io.Serializable;
/**
* 主键
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/28 21:37
*/
public interface PrimaryKey extends Serializable {
/**
* 表名
*
* @return {@link String}
*/
String getTableName();
/**
* 主键名称
*
* @return {@link String}
*/
String getPkName();
/**
* 列名
*
* @return {@link String}
*/
String getColumnName();
/**
* 关键序列
*
* @return {@link String}
*/
String getKeySeq();
}
@@ -0,0 +1,48 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.metadata;
import cn.smallbun.screw.core.query.oracle.model.OracleForeignKeyModel;
import java.io.Serializable;
import java.util.List;
/**
* 表接口
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/28 15:05
*/
public interface Table extends Serializable {
/**
* 表名
*
* @return {@link String}
*/
String getTableName();
/**
* 获取说明
*
* @return {@link String}
*/
String getRemarks();
List<OracleForeignKeyModel> getForeignKeys();
}
@@ -0,0 +1,115 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.metadata.model;
import lombok.Data;
import java.io.Serializable;
/**
* 表列领域对象,目前包含如下内容
* <p>
* 名称
* <p>
* 数据类型
* <p>
* 长度
* <p>
* 小数位
* <p>
* 允许空值
* <p>
* 主键
* <p>
* 默认值
* <p>
* 说明
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 20:24
*/
@Data
public class ColumnModel implements Serializable {
/**
* serialVersionUID
*/
private static final long serialVersionUID = -5417752216907437665L;
/**
* 表中的列的索引(从 1 开始)
*/
private String ordinalPosition;
/**
* 名称
*/
private String columnName;
/**
* SQL 数据类型带长度
*/
private String columnType;
/**
* SQL 数据类型 名称
*/
private String typeName;
/**
* 列长度
*/
private String columnLength;
/**
* 列大小
*/
private String columnSize;
/**
* 小数位
*/
private String decimalDigits;
/**
* 可为空
*/
private String nullable;
/**
* 是否主键
*/
private String primaryKey;
/**
* 默认值
*/
private String columnDef;
/**
* 说明
*/
private String remarks;
/**
* 嵌套数据信息(用于文档数据库)
*/
private TableModel nestedTable;
/**
* 是否弃用
*/
private Boolean deprecated;
/**
* 外鍵和外鍵對應的表
*/
private String foreignKey;
private String rForeignKey;
private String foreignTable;
}
@@ -0,0 +1,22 @@
package cn.smallbun.screw.core.metadata.model;
public class CustomTypeModel {
/**
* 类型名称
*/
private String typeName;
private String typeOid;
/**
* 类型编码
*/
private String typeCode;
/**
* 属性
*/
private String attributes;
}
@@ -0,0 +1,51 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.metadata.model;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* DataModel
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/17 22:32
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class DataModel extends DatabaseModel {
/**
* 标题
*/
private String title;
/**
* 组织
*/
private String organization;
/**
* url
*/
private String organizationUrl;
/**
* 版本号
*/
private String version;
/**
* 描述
*/
private String description;
}
@@ -0,0 +1,49 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.metadata.model;
import cn.smallbun.screw.core.query.oracle.model.OracleTypesModel;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 数据库信息
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 20:26
*/
@Data
public class DatabaseModel implements Serializable {
private static final long serialVersionUID = -1975852052060128878L;
/**
* 数据库名称
*/
private String database;
/**
* 表
*/
private List<TableModel> tables;
/**
* 自定义类型
*/
private List<OracleTypesModel> types;
}
@@ -0,0 +1,55 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.metadata.model;
import cn.smallbun.screw.core.query.oracle.model.OracleForeignKeyModel;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 表信息领域对象
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 20:22
*/
@Data
public class TableModel implements Serializable {
private static final long serialVersionUID = 825666678767312142L;
/**
* 表名
*/
private String tableName;
/**
* 备注
*/
private String remarks;
/**
* 表列
*/
private List<ColumnModel> columns;
/**
* 是否弃用
*/
private Boolean deprecated;
private List<OracleForeignKeyModel> foreignKeys;
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Metadata model
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 15:59
*/
package cn.smallbun.screw.core.metadata.model;
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Metadata
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 15:28
*/
package cn.smallbun.screw.core.metadata;
@@ -0,0 +1,24 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Screw database table structure document generation core package
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 17:24
*/
package cn.smallbun.screw.core;
@@ -0,0 +1,238 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.process;
import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineFileType;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.metadata.Table;
import cn.smallbun.screw.core.metadata.model.ColumnModel;
import cn.smallbun.screw.core.metadata.model.DataModel;
import cn.smallbun.screw.core.metadata.model.TableModel;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.BeanUtils;
import cn.smallbun.screw.core.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import static cn.smallbun.screw.core.util.BeanUtils.*;
/**
* AbstractBuilder
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/22 21:09
*/
public abstract class AbstractProcess implements Process {
/**
* LOGGER
*/
final Logger logger = LoggerFactory
.getLogger(this.getClass());
/**
* 表信息缓存
*/
volatile Map<String, List<? extends Table>> tablesCaching = new ConcurrentHashMap<>();
/**
* 列信息缓存
*/
volatile Map<String, List<Column>> columnsCaching = new ConcurrentHashMap<>();
/**
* 主键信息缓存
*/
volatile Map<String, List<PrimaryKey>> primaryKeysCaching = new ConcurrentHashMap<>();
/**
* Configuration
*/
protected Configuration config;
private AbstractProcess() {
}
/**
* 构造方法
*
* @param configuration {@link Configuration}
*/
protected AbstractProcess(Configuration configuration) {
Assert.notNull(configuration, "Configuration can not be empty!");
this.config = configuration;
}
/**
* 过滤表
* 存在指定生成和指定不生成,优先级为:如果指定生成,只会生成指定的表,未指定的不会生成,也不会处理忽略表
*
* @param tables {@link List} 处理前数据
* @return {@link List} 处理过后的数据
* @see "1.0.3"
*/
protected List<TableModel> filterTables(List<TableModel> tables) {
ProcessConfig produceConfig = config.getProduceConfig();
if (!Objects.isNull(config) && !Objects.isNull(config.getProduceConfig())) {
//指定生成的表名、前缀、后缀任意不为空,按照指定表生成,其余不生成,不会在处理忽略表
if (CollectionUtils.isNotEmpty(produceConfig.getDesignatedTableName())
//前缀
|| CollectionUtils.isNotEmpty(produceConfig.getDesignatedTablePrefix())
//后缀
|| CollectionUtils.isNotEmpty(produceConfig.getDesignatedTableSuffix())) {
return handleDesignated(tables);
}
//处理忽略表
else {
return handleIgnore(tables);
}
}
return tables;
}
/**
* 处理指定表
*
* @param tables {@link List} 处理前数据
* @return {@link List} 处理过后的数据
* @see "1.0.3"
*/
private List<TableModel> handleDesignated(List<TableModel> tables) {
List<TableModel> tableModels = new ArrayList<>();
ProcessConfig produceConfig = this.config.getProduceConfig();
if (!Objects.isNull(config) && !Objects.isNull(produceConfig)) {
//指定表名
if (CollectionUtils.isNotEmpty(produceConfig.getDesignatedTableName())) {
List<String> list = produceConfig.getDesignatedTableName();
for (String name : list) {
tableModels.addAll(tables.stream().filter(j -> j.getTableName().equals(name))
.collect(Collectors.toList()));
}
}
//指定表名前缀
if (CollectionUtils.isNotEmpty(produceConfig.getDesignatedTablePrefix())) {
List<String> list = produceConfig.getDesignatedTablePrefix();
for (String prefix : list) {
tableModels
.addAll(tables.stream().filter(j -> j.getTableName().startsWith(prefix))
.collect(Collectors.toList()));
}
}
//指定表名后缀
if (CollectionUtils.isNotEmpty(produceConfig.getDesignatedTableSuffix())) {
List<String> list = produceConfig.getDesignatedTableSuffix();
for (String suffix : list) {
tableModels
.addAll(tables.stream().filter(j -> j.getTableName().endsWith(suffix))
.collect(Collectors.toList()));
}
}
return tableModels;
}
return tableModels;
}
/**
* 处理忽略
*
* @param tables {@link List} 处理前数据
* @return {@link List} 处理过后的数据
*/
private List<TableModel> handleIgnore(List<TableModel> tables) {
ProcessConfig produceConfig = this.config.getProduceConfig();
if (!Objects.isNull(this.config) && !Objects.isNull(produceConfig)) {
//处理忽略表名
if (CollectionUtils.isNotEmpty(produceConfig.getIgnoreTableName())) {
List<String> list = produceConfig.getIgnoreTableName();
for (String name : list) {
tables = tables.stream().filter(j -> !j.getTableName().equals(name))
.collect(Collectors.toList());
}
}
//忽略表名前缀
if (CollectionUtils.isNotEmpty(produceConfig.getIgnoreTablePrefix())) {
List<String> list = produceConfig.getIgnoreTablePrefix();
for (String prefix : list) {
tables = tables.stream().filter(j -> !j.getTableName().startsWith(prefix))
.collect(Collectors.toList());
}
}
//忽略表名后缀
if (CollectionUtils.isNotEmpty(produceConfig.getIgnoreTableSuffix())) {
List<String> list = produceConfig.getIgnoreTableSuffix();
for (String suffix : list) {
tables = tables.stream().filter(j -> !j.getTableName().endsWith(suffix))
.collect(Collectors.toList());
}
}
return tables;
}
return tables;
}
/**
* 优化数据
* @param dataModel {@link DataModel}
* @see "1.0.3"
*/
public void optimizeData(DataModel dataModel) {
//trim
beanAttributeValueTrim(dataModel);
//tables
List<TableModel> tables = dataModel.getTables();
//columns
tables.forEach(i -> {
//table escape xml
beanAttributeValueTrim(i);
List<ColumnModel> columns = i.getColumns();
//columns escape xml
columns.forEach(BeanUtils::beanAttributeValueTrim);
});
//if file type is word
if (config.getEngineConfig().getFileType().equals(EngineFileType.WORD)) {
//escape xml
beanAttributeValueEscapeXml(dataModel);
//tables
tables.forEach(i -> {
//table escape xml
beanAttributeValueEscapeXml(i);
List<ColumnModel> columns = i.getColumns();
//columns escape xml
columns.forEach(BeanUtils::beanAttributeValueEscapeXml);
});
}
//if file type is markdown
if (config.getEngineConfig().getFileType().equals(EngineFileType.MD)) {
//escape xml
beanAttributeValueReplaceBlank(dataModel);
//columns
tables.forEach(i -> {
//table escape xml
beanAttributeValueReplaceBlank(i);
List<ColumnModel> columns = i.getColumns();
//columns escape xml
columns.forEach(BeanUtils::beanAttributeValueReplaceBlank);
});
}
}
}
@@ -0,0 +1,181 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.process;
import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.metadata.Table;
import cn.smallbun.screw.core.metadata.model.ColumnModel;
import cn.smallbun.screw.core.metadata.model.DataModel;
import cn.smallbun.screw.core.metadata.model.TableModel;
import cn.smallbun.screw.core.query.DatabaseQuery;
import cn.smallbun.screw.core.query.DatabaseQueryFactory;
import cn.smallbun.screw.core.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static cn.smallbun.screw.core.constant.DefaultConstants.*;
/**
* 数据模型处理
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/22 21:12
*/
public class DataModelProcess extends AbstractProcess {
/**
* 构造方法
*
* @param configuration {@link Configuration}
*/
public DataModelProcess(Configuration configuration) {
super(configuration);
}
/**
* 处理
*
* @return {@link DataModel}
*/
@Override
public DataModel process() {
//获取query对象
DatabaseQuery query = new DatabaseQueryFactory(config.getDataSource()).newInstance();
DataModel model = new DataModel();
//Title
model.setTitle(config.getTitle());
//org
model.setOrganization(config.getOrganization());
//org url
model.setOrganizationUrl(config.getOrganizationUrl());
//version
model.setVersion(config.getVersion());
//description
model.setDescription(config.getDescription());
/*查询操作开始*/
long start = System.currentTimeMillis();
//获取数据库
Database database = query.getDataBase();
logger.debug("query the database time consuming:{}ms",
(System.currentTimeMillis() - start));
model.setDatabase(database.getDatabase());
model.setTypes(database.getTypes());
start = System.currentTimeMillis();
//获取全部表
List<? extends Table> tables = query.getTables();
logger.debug("query the table time consuming:{}ms", (System.currentTimeMillis() - start));
//获取全部列
start = System.currentTimeMillis();
List<? extends Column> columns = query.getTableColumns();
logger.debug("query the column time consuming:{}ms", (System.currentTimeMillis() - start));
//获取主键
start = System.currentTimeMillis();
List<? extends PrimaryKey> primaryKeys = query.getPrimaryKeys();
logger.debug("query the primary key time consuming:{}ms",
(System.currentTimeMillis() - start));
/*查询操作结束*/
/*处理数据开始*/
start = System.currentTimeMillis();
List<TableModel> tableModels = new ArrayList<>();
tablesCaching.put(database.getDatabase(), tables);
for (Table table : tables) {
//处理列,表名为key,列名为值
columnsCaching.put(table.getTableName(),
columns.stream().filter(i -> i.getTableName().equals(table.getTableName()))
.collect(Collectors.toList()));
//处理主键,表名为key,主键为值
primaryKeysCaching.put(table.getTableName(),
primaryKeys.stream().filter(i -> i.getTableName().equals(table.getTableName()))
.collect(Collectors.toList()));
}
for (Table table : tables) {
/*封装数据开始*/
TableModel tableModel = new TableModel();
//表名称
tableModel.setTableName(table.getTableName());
//说明
tableModel.setRemarks(table.getRemarks());
tableModel.setForeignKeys(table.getForeignKeys());
//添加表
tableModels.add(tableModel);
//处理列
List<ColumnModel> columnModels = new ArrayList<>();
//获取主键
List<String> key = primaryKeysCaching.get(table.getTableName()).stream()
.map(PrimaryKey::getColumnName).collect(Collectors.toList());
for (Column column : columnsCaching.get(table.getTableName())) {
packageColumn(columnModels, key, column);
}
//放入列
tableModel.setColumns(columnModels);
}
//设置表
model.setTables(filterTables(tableModels));
//优化数据
optimizeData(model);
/*封装数据结束*/
logger.debug("encapsulation processing data time consuming:{}ms",
(System.currentTimeMillis() - start));
return model;
}
/**
* packageColumn
* @param columnModels {@link List}
* @param keyList {@link List}
* @param column {@link Column}
*/
private void packageColumn(List<ColumnModel> columnModels, List<String> keyList,
Column column) {
ColumnModel columnModel = new ColumnModel();
//表中的列的索引(从 1 开始)
columnModel.setOrdinalPosition(column.getOrdinalPosition());
//列名称
columnModel.setColumnName(column.getColumnName());
//类型
columnModel.setColumnType(column.getColumnType());
//字段名称
columnModel.setTypeName(column.getTypeName());
//长度
columnModel.setColumnLength(column.getColumnLength());
columnModel.setColumnLength(column.getColumnLength());
//size
columnModel.setColumnSize(column.getColumnSize());
//小数位
columnModel.setDecimalDigits(
StringUtils.defaultString(column.getDecimalDigits(), ZERO_DECIMAL_DIGITS));
//可为空
columnModel.setNullable(ZERO.equals(column.getNullable()) ? N : Y);
//是否主键
columnModel.setPrimaryKey(keyList.contains(column.getColumnName()) ? Y : N);
//默认值
columnModel.setColumnDef(column.getColumnDef());
//说明
columnModel.setRemarks(column.getRemarks());
//放入集合
columnModels.add(columnModel);
}
}
@@ -0,0 +1,38 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.process;
import cn.smallbun.screw.core.metadata.model.DataModel;
import java.io.Serializable;
/**
* 构建
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/22 21:08
*/
public interface Process extends Serializable {
/**
* 处理
*
* @return {@link DataModel}
* @throws Exception Exception
*/
DataModel process() throws Exception;
}
@@ -0,0 +1,62 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.process;
import lombok.Builder;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 数据处理
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/4/1 22:22
*/
@Data
@Builder
public class ProcessConfig implements Serializable {
/**
* 忽略表名
*/
private List<String> ignoreTableName;
/**
* 忽略表前缀
*/
private List<String> ignoreTablePrefix;
/**
* 忽略表后缀
*/
private List<String> ignoreTableSuffix;
/**
* 指定生成表名
* @see "1.0.3"
*/
private List<String> designatedTableName;
/**
* 指定生成表前缀
* @see "1.0.3"
*/
private List<String> designatedTablePrefix;
/**
* 指定生成表后缀
* @see "1.0.3"
*/
private List<String> designatedTableSuffix;
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Data processing
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 15:28
*/
package cn.smallbun.screw.core.process;
@@ -0,0 +1,205 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query;
import cn.smallbun.screw.core.exception.QueryException;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.ExceptionUtils;
import cn.smallbun.screw.core.util.JdbcUtils;
import cn.smallbun.screw.core.util.StringUtils;
import com.zaxxer.hikari.HikariDataSource;
import lombok.Getter;
import javax.sql.DataSource;
import java.sql.*;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import static cn.smallbun.screw.core.constant.DefaultConstants.NOT_SUPPORTED;
/**
* AbstractDataBaseQuery
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/18 12:50
*/
public abstract class AbstractDatabaseQuery implements DatabaseQuery {
/**
* 缓存
*/
protected final Map<String, List<Column>> columnsCaching = new ConcurrentHashMap<>();
/**
* DataSource
*/
@Getter
private final DataSource dataSource;
/**
* Connection 双重锁,线程安全
*/
volatile protected Connection connection;
public AbstractDatabaseQuery(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* 获取连接对象,单例模式,采用双重锁检查
*
* @return {@link Connection}
* @throws QueryException QueryException
*/
private Connection getConnection() throws QueryException {
try {
//不为空
if (!Objects.isNull(connection) && !connection.isClosed()) {
System.out.println(connection);
return connection;
}
//同步代码块
synchronized (AbstractDatabaseQuery.class) {
//为空或者已经关闭
if (Objects.isNull(connection) || connection.isClosed()) {
this.connection = this.getDataSource().getConnection();
}
}
return this.connection;
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
}
}
/**
* 获取 getCatalog
*
* @return {@link String}
* @throws QueryException QueryException
*/
protected String getCatalog() throws QueryException {
try {
String catalog = this.getConnection().getCatalog();
if (StringUtils.isBlank(catalog)) {
return null;
}
return catalog;
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
}
}
/**
* 获取 getSchema
*
* @return {@link String}
* @throws QueryException QueryException
*/
protected String getSchema() throws QueryException {
try {
String schema;
//获取数据库URL 用于判断数据库类型
String url = this.getConnection().getMetaData().getURL();
//获取数据库名称
String name = JdbcUtils.getDbType(url).getName();
if (DatabaseType.CACHEDB.getName().equals(name)) {
schema = verifySchema(this.getDataSource());
} else {
schema = this.getConnection().getSchema();
}
if (StringUtils.isBlank(schema)) {
return null;
}
return schema;
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
}
}
/**
* 验证Schema
*
* @param dataSource {@link DataSource}
* @return Schema
*/
private String verifySchema(DataSource dataSource) throws SQLException {
String schema;
if (dataSource instanceof HikariDataSource) {
schema = ((HikariDataSource) dataSource).getSchema();
} else {
schema = dataSource.getConnection().getSchema();
}
//验证是否有此Schema
ResultSet resultSet = this.getConnection().getMetaData().getSchemas();
while (resultSet.next()) {
int columnCount = resultSet.getMetaData().getColumnCount();
for (int i = 1; i <= columnCount; i++) {
String columnValue = resultSet.getString(i);
if (StringUtils.isNotBlank(columnValue) && columnValue.contains(schema)) {
return schema;
}
}
}
return null;
}
/**
* 获取 DatabaseMetaData
*
* @return {@link DatabaseMetaData}
* @throws QueryException QueryException
*/
protected DatabaseMetaData getMetaData() throws QueryException {
try {
return this.getConnection().getMetaData();
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
}
}
/**
* 准备声明
*
* @param sql {@link String} SQL
* @return {@link PreparedStatement}
* @throws QueryException QueryException
*/
protected PreparedStatement prepareStatement(String sql) throws QueryException {
Assert.notEmpty(sql, "Sql can not be empty!");
try {
return this.getConnection().prepareStatement(sql);
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
}
}
/**
* 根据表名获取主键
*
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys() throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
}
@@ -0,0 +1,88 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query;
import cn.smallbun.screw.core.exception.QueryException;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.metadata.Table;
import com.ibm.db2.cmx.runtime.internal.repository.metadata.ForeignKeyInfo;
import java.io.Serializable;
import java.util.List;
/**
* 通用查询接口
* 查询数据库信息
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/18 11:58
*/
public interface DatabaseQuery extends Serializable {
/**
* 获取数据库
*
* @return {@link Database} 数据库信息
* @throws QueryException QueryException
*/
Database getDataBase() throws QueryException;
/**
* 获取表信息
*
* @return {@link List} 所有表信息
* @throws QueryException QueryException
*/
List<? extends Table> getTables() throws QueryException;
/**
* 获取列信息
*
* @param table {@link String} 表名
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
List<? extends Column> getTableColumns(String table) throws QueryException;
/**
* 获取所有列信息
*
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
List<? extends Column> getTableColumns() throws QueryException;
/**
* 根据表名获取主键
*
* @param table {@link String}
* @return {@link List}
* @throws QueryException QueryException
*/
List<? extends PrimaryKey> getPrimaryKeys(String table) throws QueryException;
/**
* 获取主键
*
* @return {@link List}
* @throws QueryException QueryException
*/
List<? extends PrimaryKey> getPrimaryKeys() throws QueryException;
}
@@ -0,0 +1,80 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query;
import cn.smallbun.screw.core.util.ExceptionUtils;
import cn.smallbun.screw.core.util.JdbcUtils;
import lombok.Getter;
import javax.sql.DataSource;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
/**
* 数据库查询工厂
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/18 14:15
*/
public class DatabaseQueryFactory implements Serializable {
/**
* DataSource
*/
@Getter
private DataSource dataSource;
/**
* 构造函数私有化
* 禁止通过new方式实例化对象
*/
private DatabaseQueryFactory() {
}
/**
* 构造函数
*
* @param source {@link DataSource}
*/
public DatabaseQueryFactory(DataSource source) {
dataSource = source;
}
/**
* 获取配置的数据库类型实例
*
* @return {@link DatabaseQuery} 数据库查询对象
*/
public DatabaseQuery newInstance() {
try {
//获取数据库URL 用于判断数据库类型
String url = this.getDataSource().getConnection().getMetaData().getURL();
//获取实现类
Class<? extends DatabaseQuery> query = JdbcUtils.getDbType(url).getImplClass();
//获取有参构造
Constructor<? extends DatabaseQuery> constructor = query
.getConstructor(DataSource.class);
//实例化
return constructor.newInstance(dataSource);
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException
| InvocationTargetException | SQLException e) {
throw ExceptionUtils.mpe(e);
}
}
}
@@ -0,0 +1,186 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query;
import cn.smallbun.screw.core.query.cachedb.CacheDbDataBaseQuery;
import cn.smallbun.screw.core.query.db2.Db2DataBaseQuery;
import cn.smallbun.screw.core.query.dm.DmDataBaseQuery;
import cn.smallbun.screw.core.query.h2.H2DataBaseQuery;
import cn.smallbun.screw.core.query.highgo.HigHgoDataBaseQuery;
import cn.smallbun.screw.core.query.hsql.HsqlDataBaseQuery;
import cn.smallbun.screw.core.query.mariadb.MariaDbDataBaseQuery;
import cn.smallbun.screw.core.query.mysql.MySqlDataBaseQuery;
import cn.smallbun.screw.core.query.oracle.OracleDataBaseQuery;
import cn.smallbun.screw.core.query.phoenix.PhoenixDataBaseQuery;
import cn.smallbun.screw.core.query.postgresql.PostgreSqlDataBaseQuery;
import cn.smallbun.screw.core.query.sqlite.SqliteDataBaseQuery;
import cn.smallbun.screw.core.query.sqlservice.SqlServerDataBaseQuery;
import lombok.Getter;
import java.io.Serializable;
/**
* 数据库类型
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/18 11:59
*/
public enum DatabaseType implements Serializable {
/**
* MYSQL
*/
MYSQL("mysql", "MySql数据库",
MySqlDataBaseQuery.class),
/**
* MARIA DB
*/
MARIADB("mariadb", "MariaDB数据库",
MariaDbDataBaseQuery.class),
/**
* ORACLE
*/
ORACLE("oracle", "Oracle数据库",
OracleDataBaseQuery.class),
/**
* DB2
*/
DB2("db2", "DB2数据库", Db2DataBaseQuery.class),
/**
* H2
*/
H2("h2", "H2数据库", H2DataBaseQuery.class),
/**
* HSQL
*/
HSQL("hsql", "HSQL数据库", HsqlDataBaseQuery.class),
/**
* SQLITE
*/
SQLITE("sqlite", "SQLite数据库",
SqliteDataBaseQuery.class),
/**
* POSTGRE
*/
POSTGRE_SQL("PostgreSql", "Postgre数据库",
PostgreSqlDataBaseQuery.class),
/**
* SQL SERVER 2005
*/
SQL_SERVER2005("sqlServer2005",
"SQLServer2005数据库",
SqlServerDataBaseQuery.class),
/**
* SQLSERVER
*/
SQL_SERVER("sqlserver", "SQLServer数据库",
SqlServerDataBaseQuery.class),
/**
* DM
*/
DM("dm", "达梦数据库", DmDataBaseQuery.class),
/**
* HIGHGO
*/
HIGHGO("highgo", "瀚高数据库",
HigHgoDataBaseQuery.class),
/**
* xugu
*/
XU_GU("xugu", "虚谷数据库", OtherDataBaseQuery.class),
/**
* Kingbase
*/
KINGBASE_ES("kingbasees", "人大金仓数据库",
OtherDataBaseQuery.class),
/**
* Phoenix
*/
PHOENIX("phoenix", "Phoenix HBase数据库",
PhoenixDataBaseQuery.class),
/**
* CacheDB
*/
CACHEDB("cachedb", "Cache 数据库",
CacheDbDataBaseQuery.class),
/**
* UNKONWN DB
*/
OTHER("other", "其他数据库", OtherDataBaseQuery.class);
/**
* 数据库名称
*/
@Getter
private final String name;
/**
* 描述
*/
@Getter
private final String desc;
/**
* 查询实现
*/
@Getter
private final Class<? extends DatabaseQuery> implClass;
/**
* 构造
*
* @param name {@link String} 名称
* @param desc {@link String} 描述
* @param query {@link Class}
*/
DatabaseType(String name, String desc, Class<? extends DatabaseQuery> query) {
this.name = name;
this.desc = desc;
this.implClass = query;
}
/**
* 获取数据库类型
*
* @param dbType {@link String} 数据库类型字符串
* @return {@link DatabaseType}
*/
public static DatabaseType getType(String dbType) {
DatabaseType[] dts = DatabaseType.values();
for (DatabaseType dt : dts) {
if (dt.getName().equalsIgnoreCase(dbType)) {
return dt;
}
}
return OTHER;
}
}
@@ -0,0 +1,105 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query;
import cn.smallbun.screw.core.exception.QueryException;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.metadata.Table;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.ExceptionUtils;
import javax.sql.DataSource;
import java.util.List;
import static cn.smallbun.screw.core.constant.DefaultConstants.NOT_SUPPORTED;
/**
* 其他数据库 暂未支持系列
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/20 17:41
*/
public class OtherDataBaseQuery extends AbstractDatabaseQuery {
/**
* 构造函数
*
* @param dataSource {@link DataSource}
*/
public OtherDataBaseQuery(DataSource dataSource) {
super(dataSource);
}
/**
* 获取数据库
*
* @return {@link Database} 数据库信息
*/
@Override
public Database getDataBase() {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 获取表信息
*
* @return {@link List} 所有表信息
*/
@Override
public List<Table> getTables() {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 获取列信息
*
* @param table {@link String} 表名
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<Column> getTableColumns(String table) throws QueryException {
Assert.notEmpty(table, "Table name can not be empty!");
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 获取所有列信息
*
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<? extends Column> getTableColumns() throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 根据表名获取主键
*
* @param table {@link String}
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys(String table) throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
}
@@ -0,0 +1,238 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.cachedb;
import cn.smallbun.screw.core.exception.QueryException;
import cn.smallbun.screw.core.mapping.Mapping;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.metadata.Table;
import cn.smallbun.screw.core.query.AbstractDatabaseQuery;
import cn.smallbun.screw.core.query.cachedb.model.CacheDbColumnModel;
import cn.smallbun.screw.core.query.cachedb.model.CacheDbDatabaseModel;
import cn.smallbun.screw.core.query.cachedb.model.CacheDbPrimaryKeyModel;
import cn.smallbun.screw.core.query.cachedb.model.CacheDbTableModel;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.CollectionUtils;
import cn.smallbun.screw.core.util.ExceptionUtils;
import cn.smallbun.screw.core.util.JdbcUtils;
import com.ibm.db2.cmx.runtime.internal.repository.metadata.ForeignKeyInfo;
import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.List;
import java.util.stream.Collectors;
import static cn.smallbun.screw.core.constant.DefaultConstants.PERCENT_SIGN;
/**
* CacheDB 数据库查询
*
* @author <a href ='jxh98@foxmail.com'>Josway</a> 2020/8/26
* @since JDK 1.8
*/
public class CacheDbDataBaseQuery extends AbstractDatabaseQuery {
/**
* 构造函数
*
* @param dataSource {@link DataSource}
*/
public CacheDbDataBaseQuery(DataSource dataSource) {
super(dataSource);
}
/**
* 获取数据库
*
* @return {@link Database} 数据库信息
* @throws QueryException QueryException
*/
@Override
public Database getDataBase() throws QueryException {
CacheDbDatabaseModel model = new CacheDbDatabaseModel();
//当前数据库名称
model.setDatabase(getSchema());
return model;
}
/**
* 获取表信息
*
* @return {@link List} 所有表信息
* @throws QueryException QueryException
*/
@Override
public List<? extends Table> getTables() throws QueryException {
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getTables(getCatalog(), getSchema(), null,
new String[] { "TABLE" });
//映射
return Mapping.convertList(resultSet, CacheDbTableModel.class);
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet);
}
}
/**
* 获取列信息
*
* @param table {@link String} 表名
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<? extends Column> getTableColumns(String table) throws QueryException {
Assert.notEmpty(table, "Table name can not be empty!");
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getColumns(getCatalog(), getSchema(), table, PERCENT_SIGN);
//映射
final List<CacheDbColumnModel> list = Mapping.convertList(resultSet,
CacheDbColumnModel.class);
//这里处理是为了如果是查询全部列呢?所以处理并获取唯一表名
List<String> tableNames = list.stream().map(CacheDbColumnModel::getTableName)
.collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(columnsCaching)) {
//查询全部
if (table.equals(PERCENT_SIGN)) {
//获取全部表列信息SQL
String sql = MessageFormat
.format("select TABLE_NAME as \"TABLE_NAME\",COLUMN_NAME as "
+ "\"COLUMN_NAME\",DESCRIPTION as \"REMARKS\","
+ "case when CHARACTER_MAXIMUM_LENGTH is null then DATA_TYPE || '''' "
+ "else DATA_TYPE || ''(''||CHARACTER_MAXIMUM_LENGTH ||'')'' end as \"COLUMN_TYPE\" "
+ "from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = ''{0}''",
getSchema());
PreparedStatement statement = prepareStatement(sql);
resultSet = statement.executeQuery();
int fetchSize = 4284;
if (resultSet.getFetchSize() < fetchSize) {
resultSet.setFetchSize(fetchSize);
}
}
//单表查询
else {
//获取表列信息SQL 查询表名、列名、说明、数据类型
String sql = MessageFormat
.format("select TABLE_NAME as \"TABLE_NAME\",COLUMN_NAME as "
+ "\"COLUMN_NAME\",DESCRIPTION as \"REMARKS\","
+ "case when CHARACTER_MAXIMUM_LENGTH is null then DATA_TYPE || ''''"
+ "else DATA_TYPE || ''(''||CHARACTER_MAXIMUM_LENGTH ||'')'' end as \"COLUMN_TYPE\" "
+ "from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = ''{0}'' and TABLE_NAME = "
+ "''{1}''",
getSchema(), table);
resultSet = prepareStatement(sql).executeQuery();
}
List<CacheDbColumnModel> inquires = Mapping.convertList(resultSet,
CacheDbColumnModel.class);
//处理列,表名为key,列名为值
tableNames.forEach(name -> columnsCaching.put(name, inquires.stream()
.filter(i -> i.getTableName().equals(name)).collect(Collectors.toList())));
}
//处理备注信息
list.forEach(i -> {
//从缓存中根据表名获取列信息
List<Column> columns = columnsCaching.get(i.getTableName());
columns.forEach(j -> {
//列名表名一致
if (i.getColumnName().equals(j.getColumnName())
&& i.getTableName().equals(j.getTableName())) {
//放入列类型
i.setColumnType(j.getColumnType());
i.setColumnLength(j.getColumnLength());
//放入注释
i.setRemarks(j.getRemarks());
}
});
});
return list;
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet);
}
}
/**
* 获取所有列信息
*
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<? extends Column> getTableColumns() throws QueryException {
//获取全部列
return getTableColumns(PERCENT_SIGN);
}
/**
* 根据表名获取主键
*
* @param table {@link String}
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys(String table) throws QueryException {
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getPrimaryKeys(getCatalog(), getSchema(), table);
//映射
return Mapping.convertList(resultSet, CacheDbPrimaryKeyModel.class);
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet, this.connection);
}
}
/**
* 根据表名获取主键信息
*
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys() throws QueryException {
ResultSet resultSet = null;
try {
// 由于单条循环查询存在性能问题,所以这里通过自定义SQL查询数据库主键信息
String sql = "select TABLE_CATALOG ,TABLE_NAME as \"TABLE_NAME\",TABLE_SCHEMA as \"TABLE_SCHEM\",COLUMN_NAME as \"COLUMN_NAME\",ORDINAL_POSITION as \"KEY_SEQ\" from INFORMATION_SCHEMA.COLUMNS where PRIMARY_KEY='YES' and TABLE_SCHEMA='%s'";
// 拼接参数
resultSet = prepareStatement(String.format(sql, getDataBase().getDatabase()))
.executeQuery();
return Mapping.convertList(resultSet, CacheDbPrimaryKeyModel.class);
} catch (SQLException e) {
throw new QueryException(e);
} finally {
JdbcUtils.close(resultSet);
}
}
}
@@ -0,0 +1,170 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.cachedb.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.Column;
import lombok.Data;
/**
* 表字段信息
*
* @author <a href ='jxh98@foxmail.com'>Josway</a> 2020/6/28
* @since JDK 1.8
*/
@Data
public class CacheDbColumnModel implements Column {
private static final long serialVersionUID = -7231934486902707912L;
/**
*
*/
@MappingField(value = "SCOPE_TABLE")
private String scopeTable;
/**
*
*/
@MappingField(value = "TABLE_CAT")
private String tableCat;
/**
* BUFFER_LENGTH
*/
@MappingField(value = "BUFFER_LENGTH")
private String bufferLength;
/**
* IS_NULLABLE
*/
@MappingField(value = "IS_NULLABLE")
private String isNullable;
/**
* TABLE_NAME
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
*
*/
@MappingField(value = "COLUMN_DEF")
private String columnDef;
/**
*
*/
@MappingField(value = "SCOPE_CATALOG")
private String scopeCatalog;
/**
* TABLE_SCHEM
*/
@MappingField(value = "TABLE_SCHEM")
private String tableSchem;
/**
* COLUMN_NAME
*/
@MappingField(value = "COLUMN_NAME")
private String columnName;
/**
* nullable
*/
@MappingField(value = "NULLABLE")
private String nullable;
/**
* REMARKS
*/
@MappingField(value = "REMARKS")
private String remarks;
/**
* DECIMAL_DIGITS
*/
@MappingField(value = "DECIMAL_DIGITS")
private String decimalDigits;
/**
*
*/
@MappingField(value = "NUM_PREC_RADIX")
private String numPrecRadix;
/**
*
*/
@MappingField(value = "SQL_DATETIME_SUB")
private String sqlDatetimeSub;
/**
* IS_GENERATEDCOLUMN
*/
@MappingField(value = "IS_GENERATEDCOLUMN")
private String isGeneratedcolumn;
/**
* IS_AUTOINCREMENT
*/
@MappingField(value = "IS_AUTOINCREMENT")
private String isAutoincrement;
/**
* SQL_DATA_TYPE
*/
@MappingField(value = "SQL_DATA_TYPE")
private String sqlDataType;
/**
* CHAR_OCTET_LENGTH
*/
@MappingField(value = "CHAR_OCTET_LENGTH")
private String charOctetLength;
/**
* ORDINAL_POSITION
*/
@MappingField(value = "ORDINAL_POSITION")
private String ordinalPosition;
/**
*
*/
@MappingField(value = "SCOPE_SCHEMA")
private String scopeSchema;
/**
*
*/
@MappingField(value = "SOURCE_DATA_TYPE")
private String sourceDataType;
/**
* DATA_TYPE
*/
@MappingField(value = "DATA_TYPE")
private String dataType;
/**
* TYPE_NAME
*/
@MappingField(value = "TYPE_NAME")
private String typeName;
/**
* COLUMN_SIZE
*/
@MappingField(value = "COLUMN_SIZE")
private String columnSize;
/**
* 是否主键
*/
private String primaryKey;
/**
* 列类型(带长度)
*/
@MappingField(value = "COLUMN_TYPE")
private String columnType;
/**
* 列长度
*/
@MappingField(value = "COLUMN_LENGTH")
private String columnLength;
}
@@ -0,0 +1,45 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.cachedb.model;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.query.oracle.model.OracleTypesModel;
import lombok.Data;
import java.util.List;
/**
* 数据库信息
*
* @author <a href ='jxh98@foxmail.com'>Josway</a> 2020/6/28
* @since JDK 1.8
*/
@Data
public class CacheDbDatabaseModel implements Database {
private static final long serialVersionUID = 931210775266917894L;
/**
* 数据库名称
*/
private String database;
@Override
public List<OracleTypesModel> getTypes() {
return null;
}
}
@@ -0,0 +1,60 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.cachedb.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import lombok.Data;
/**
* 表主键
*
* @author <a href ='jxh98@foxmail.com'>Josway</a> 2020/6/28
* @since JDK 1.8
*/
@Data
public class CacheDbPrimaryKeyModel implements PrimaryKey {
private static final long serialVersionUID = -4908250184995248600L;
/**
*
*/
@MappingField(value = "TABLE_CATALOG")
private String tableCat;
/**
* TABLE_NAME
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
* TABLE_SCHEM
*/
@MappingField(value = "TABLE_SCHEM")
private String tableSchem;
/**
* COLUMN_NAME
*/
@MappingField(value = "COLUMN_NAME")
private String columnName;
/**
* KEY_SEQ
*/
@MappingField(value = "KEY_SEQ")
private String keySeq;
private String pkName;
}
@@ -0,0 +1,92 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.cachedb.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.Table;
import cn.smallbun.screw.core.query.oracle.model.OracleForeignKeyModel;
import lombok.Data;
import java.util.List;
/**
* 表信息
*
* @author <a href ='jxh98@foxmail.com'>Josway</a> 2020/6/28
* @since JDK 1.8
*/
@Data
public class CacheDbTableModel implements Table {
private static final long serialVersionUID = -1917761911812533673L;
/**
*
*/
@MappingField(value = "TABLE_CAT")
private String tableCat;
/**
* TABLE_NAME
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
*
*/
@MappingField(value = "SELF_REFERENCING_COL_NAME")
private String selfReferencingColName;
/**
* TABLE_SCHEM
*/
@MappingField(value = "TABLE_SCHEM")
private String tableSchem;
/**
*
*/
@MappingField(value = "TYPE_SCHEM")
private String typeSchem;
/**
*
*/
@MappingField(value = "TYPE_CAT")
private Object typeCat;
/**
* TABLE_TYPE
*/
@MappingField(value = "TABLE_TYPE")
private String tableType;
/**
* REMARKS
*/
@MappingField(value = "REMARKS")
private String remarks;
/**
*
*/
@MappingField(value = "REF_GENERATION")
private String refGeneration;
/**
*
*/
@MappingField(value = "TYPE_NAME")
private String typeName;
@Override
public List<OracleForeignKeyModel> getForeignKeys() {
return null;
}
}
@@ -0,0 +1,24 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* CacheDB Database query model
*
* @author <a href ='jxh98@foxmail.com'>Josway</a> 2020/6/28
* @since JDK 1.8
*/
package cn.smallbun.screw.core.query.cachedb.model;
@@ -0,0 +1,24 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* CacheDB Database query implement
*
* @author <a href ='jxh98@foxmail.com'>Josway</a> 2020/6/28
* @since JDK 1.8
*/
package cn.smallbun.screw.core.query.cachedb;
@@ -0,0 +1,224 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.db2;
import cn.smallbun.screw.core.exception.QueryException;
import cn.smallbun.screw.core.mapping.Mapping;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.metadata.Table;
import cn.smallbun.screw.core.query.AbstractDatabaseQuery;
import cn.smallbun.screw.core.query.db2.model.Db2ColumnModel;
import cn.smallbun.screw.core.query.db2.model.Db2DatabaseModel;
import cn.smallbun.screw.core.query.db2.model.Db2PrimaryKeyModel;
import cn.smallbun.screw.core.query.db2.model.Db2TableModel;
import cn.smallbun.screw.core.query.mysql.model.MySqlTableModel;
import cn.smallbun.screw.core.query.oracle.model.OracleColumnModel;
import cn.smallbun.screw.core.query.oracle.model.OracleTableModel;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.CollectionUtils;
import cn.smallbun.screw.core.util.ExceptionUtils;
import cn.smallbun.screw.core.util.JdbcUtils;
import org.apache.commons.lang3.StringUtils;
import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static cn.smallbun.screw.core.constant.DefaultConstants.NOT_SUPPORTED;
import static cn.smallbun.screw.core.constant.DefaultConstants.PERCENT_SIGN;
/**
* db2 数据库查询
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/18 14:00
*/
public class Db2DataBaseQuery extends AbstractDatabaseQuery {
/**
* 构造函数
*
* @param dataSource {@link DataSource}
*/
public Db2DataBaseQuery(DataSource dataSource) {
super(dataSource);
}
/**
* 获取数据库
*
* @return {@link Database} 数据库信息
*/
@Override
public Database getDataBase() throws QueryException {
Db2DatabaseModel model = new Db2DatabaseModel();
model.setDatabase(StringUtils.trim(this.getSchema()));
return model;
}
/**
* 获取表信息
*
* @return {@link List} 所有表信息
*/
@Override
public List<Db2TableModel> getTables() {
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getTables(getCatalog(), getSchema(), PERCENT_SIGN,
new String[] { "TABLE" });
//映射
return Mapping.convertList(resultSet, Db2TableModel.class);
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet, connection);
}
}
/**
* 获取列信息
*
* @param table {@link String} 表名
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<Db2ColumnModel> getTableColumns(String table) throws QueryException {
Assert.notEmpty(table, "Table name can not be empty!");
ResultSet resultSet = null;
try {
//查询所有
List<Db2ColumnModel> list;
if (PERCENT_SIGN.equals(table)) {
List<String> tableNames = getTables().stream().map(Table::getTableName)
.collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
//db2 getMetaData().getColumns 中 无法获取表名,循环单张表获取
list = new ArrayList<>();
for (String tableName : tableNames) {
list.addAll(getTableColumns(tableName));
}
} else {
if (!this.columnsCaching.containsKey(table)) {
//查询
resultSet = getMetaData().getColumns(getCatalog(), getSchema(), table,
PERCENT_SIGN);
//映射
list = Mapping.convertList(resultSet, Db2ColumnModel.class);
//单表查询
String sql = "SELECT COLNAME as NAME,TABNAME as TABLE_NAME,REMARKS,LENGTH as COLUMN_LENGTH, TYPENAME ||'('|| LENGTH ||')' as COLUMN_TYPE,SCALE as DECIMAL_DIGITS FROM SYSCAT.COLUMNS WHERE TABSCHEMA='"
+ StringUtils.trim(getSchema())
+ "' and TABNAME = '%s' ORDER BY COLNO";
resultSet = prepareStatement(String.format(sql, table)).executeQuery();
//db2 ColumnName 获取的不是 as column 值,使用ColumnLabel获取
List<Db2ColumnModel> inquires = Mapping.convertListByColumnLabel(resultSet,
Db2ColumnModel.class);
for (Db2ColumnModel i : list) {
inquires.forEach(j -> {
//列名一致
if (i.getColumnName().equals(j.getColumnName())) {
//放入备注
i.setRemarks(j.getRemarks());
i.setColumnLength(j.getColumnLength());
i.setColumnType(j.getColumnType());
i.setTableName(j.getTableName());
i.setDecimalDigits(j.getDecimalDigits());
if ("NO".equals(i.getNullable())) {
i.setNullable("0");
}
}
});
}
this.columnsCaching.put(table,
list.stream().filter(i -> StringUtils.isNotBlank(i.getColumnName()))
.collect(Collectors.toList()));
} else {
list = this.columnsCaching.get(table).stream().map(c -> (Db2ColumnModel) c)
.collect(Collectors.toList());
}
}
return list;
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet, this.connection);
}
}
/**
* 获取所有列信息
*
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<? extends Column> getTableColumns() throws QueryException {
return getTableColumns(PERCENT_SIGN);
}
/**
* 根据表名获取主键
*
* @param table {@link String}
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys(String table) throws QueryException {
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getPrimaryKeys(getCatalog(), getSchema(), table);
//映射
return Mapping.convertList(resultSet, Db2PrimaryKeyModel.class);
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet, this.connection);
}
}
/**
* 根据表名获取主键
*
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys() throws QueryException {
ResultSet resultSet = null;
try {
// 由于单条循环查询存在性能问题,所以这里通过自定义SQL查询数据库主键信息
String sql = "SELECT TABSCHEMA as TABLE_SCHEM, TABNAME as TABLE_NAME ,COLNAME as COLUMN_NAME,KEYSEQ as KEY_SEQ FROM SYSCAT.COLUMNS WHERE TABSCHEMA = '%s' AND KEYSEQ IS NOT NULL ORDER BY KEYSEQ";
resultSet = prepareStatement(String.format(sql, getDataBase().getDatabase()))
.executeQuery();
return Mapping.convertListByColumnLabel(resultSet, Db2PrimaryKeyModel.class);
} catch (SQLException e) {
throw new QueryException(e);
} finally {
JdbcUtils.close(resultSet);
}
}
}
@@ -0,0 +1,175 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.db2.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.Column;
import lombok.Data;
/**
* db2 table column
*
* @author hexw
* Created by 964104818@qq.com on 2021/05/31 8:44
*/
@Data
public class Db2ColumnModel implements Column {
/**
* 表名称,它是引用属性的作用域(如果 DATA_TYPE 不是 REF,则为 null)
*/
@MappingField(value = "SCOPE_TABLE")
private Object scopeTable;
/**
* 表类别
*/
@MappingField(value = "TABLE_CAT")
private Object tableCat;
/**
* 未被使用
*/
@MappingField(value = "BUFFER_LENGTH")
private String bufferLength;
/**
* ISO 规则用于确定列是否包括 null。
*/
@MappingField(value = "IS_NULLABLE")
private String isNullable;
/**
* 数据源依赖的类型名称,对于 UDT,该类型名称是完全限定的
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
* 该列的默认值,当值在单引号内时应被解释为一个字符串(可为 null)
*/
@MappingField(value = "COLUMN_DEF")
private String columnDef;
/**
* 表的类别,它是引用属性的作用域(如果 DATA_TYPE 不是 REF,则为 null)
*/
@MappingField(value = "SCOPE_CATALOG")
private Object scopeCatalog;
/**
* 表模式
*/
@MappingField(value = "TABLE_SCHEM")
private String tableSchem;
/**
* 列名称
*/
@MappingField(value = "NAME")
private String columnName;
/**
* 是否允许使用 NULL。
*/
@MappingField(value = "NULLABLE")
private String nullable;
/**
* 描述列的注释(可为 null)
*/
@MappingField(value = "REMARKS")
private String remarks;
/**
* 小数部分的位数。对于 DECIMAL_DIGITS 不适用的数据类型,则返回 Null。
*/
@MappingField(value = "DECIMAL_DIGITS")
private String decimalDigits;
/**
* 基数(通常为 10 或 2)
*/
@MappingField(value = "NUM_PREC_RADIX")
private String numPrecRadix;
/**
*
*/
@MappingField(value = "SQL_DATETIME_SUB")
private String sqlDatetimeSub;
/**
*
*/
@MappingField(value = "IS_GENERATEDCOLUMN")
private String isGeneratedColumn;
/**
* 指示此列是否自动增加
* YES --- 如果该列自动增加
* NO --- 如果该列不自动增加
*/
@MappingField(value = "IS_AUTOINCREMENT")
private String isAutoIncrement;
/**
* SQL数据类型
*/
@MappingField(value = "SQL_DATA_TYPE")
private String sqlDataType;
/**
* 对于 char 类型,该长度是列中的最大字节数
*/
@MappingField(value = "CHAR_OCTET_LENGTH")
private String charOctetLength;
/**
* 表中的列的索引(从 1 开始)
*/
@MappingField(value = "ORDINAL_POSITION")
private String ordinalPosition;
/**
* 表的模式,它是引用属性的作用域(如果 DATA_TYPE 不是 REF,则为 null)
*/
@MappingField(value = "SCOPE_SCHEMA")
private String scopeSchema;
/**
* 不同类型或用户生成 Ref 类型、来自 java.sql.Types 的 SQL 类型的源类型(如果 DATA_TYPE 不是 DISTINCT 或用户生成的 REF,则为 null)
*/
@MappingField(value = "SOURCE_DATA_TYPE")
private String sourceDataType;
/**
* 来自 java.sql.Types 的 SQL 类型
*/
@MappingField(value = "DATA_TYPE")
private String dataType;
/**
* 数据源依赖的类型名称,对于 UDT,该类型名称是完全限定的
*/
@MappingField(value = "TYPE_NAME")
private String typeName;
/**
* 列表示给定列的指定列大小。
* 对于数值数据,这是最大精度。
* 对于字符数据,这是字符长度。
* 对于日期时间数据类型,这是 String 表示形式的字符长度(假定允许的最大小数秒组件的精度)。
* 对于二进制数据,这是字节长度。
* 对于 ROWID 数据类型,这是字节长度。对于列大小不适用的数据类型,则返回 Null。
*/
@MappingField(value = "COLUMN_SIZE")
private String columnSize;
/**
* 是否主键
*/
private String primaryKey;
/**
* 列类型(带长度)
*/
@MappingField(value = "COLUMN_TYPE")
private String columnType;
/**
* 列长度
*/
@MappingField(value = "COLUMN_LENGTH")
private String columnLength;
}
@@ -0,0 +1,47 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.db2.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.query.oracle.model.OracleTypesModel;
import lombok.Data;
import java.util.List;
/**
* db2数据库信息
*
* @author hexw
* Created by 964104818@qq.com on 2021/05/31 8:44
*/
@Data
public class Db2DatabaseModel implements Database {
private static final long serialVersionUID = 931210775266917894L;
/**
* 数据库名称
*/
@MappingField(value = "TABLE_CAT")
private String database;
@Override
public List<OracleTypesModel> getTypes() {
return null;
}
}
@@ -0,0 +1,58 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.db2.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import lombok.Data;
/**
* db2 table primary
*
* @author hexw
* Created by 964104818@qq.com on 2021/05/31 8:44
*/
@Data
public class Db2PrimaryKeyModel implements PrimaryKey {
/**
* 表名
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
* pk name
*/
@MappingField(value = "PK_NAME")
private String pkName;
/**
* 表模式
*/
@MappingField(value = "TABLE_SCHEM")
private String tableSchem;
/**
* 列名
*/
@MappingField(value = "COLUMN_NAME")
private String columnName;
/**
* 键序列
*/
@MappingField(value = "KEY_SEQ")
private String keySeq;
}
@@ -0,0 +1,65 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.db2.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.Table;
import cn.smallbun.screw.core.query.oracle.model.OracleForeignKeyModel;
import lombok.Data;
import java.util.List;
/**
* db2 table
*
* @author hexw
* Created by 964104818@qq.com on 2021/05/31 8:44
*/
@Data
public class Db2TableModel implements Table {
/**
* TABLE_CAT
*/
@MappingField(value = "TABLE_CAT")
private String tableCat;
/**
* 表名
*/
@MappingField(value = "NAME")
private String tableName;
/**
* 表模式
*/
@MappingField(value = "TABLE_SCHEM")
private String tableSchem;
/**
* 表类型
*/
@MappingField(value = "TABLE_TYPE")
private String tableType;
/**
* 备注
*/
@MappingField(value = "REMARKS")
private String remarks;
@Override
public List<OracleForeignKeyModel> getForeignKeys() {
return null;
}
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* DB2 Database query implement
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 16:00
*/
package cn.smallbun.screw.core.query.db2;
@@ -0,0 +1,302 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.dm;
import static cn.smallbun.screw.core.constant.DefaultConstants.PERCENT_SIGN;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import cn.smallbun.screw.core.exception.QueryException;
import cn.smallbun.screw.core.mapping.Mapping;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.query.AbstractDatabaseQuery;
import cn.smallbun.screw.core.query.dm.model.DmColumnModel;
import cn.smallbun.screw.core.query.dm.model.DmDatabaseModel;
import cn.smallbun.screw.core.query.dm.model.DmPrimaryKeyModel;
import cn.smallbun.screw.core.query.dm.model.DmTableModel;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.CollectionUtils;
import cn.smallbun.screw.core.util.ExceptionUtils;
import cn.smallbun.screw.core.util.JdbcUtils;
/**
* 达梦数据库查询
*
* @author SanLi
* Created by jincy@neusoft.com + qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/9/17 17:40
*/
@SuppressWarnings("serial")
public class DmDataBaseQuery extends AbstractDatabaseQuery {
private final ConcurrentMap<String, List<DmTableModel>> tablesMap = new ConcurrentHashMap<>();
private static final String DM_QUERY_TABLE_SQL = ""
+ "select "
+ " ut.table_name TABLE_NAME, "
+ " utc.comments COMMENTS "
+ "from "
+ " user_tables ut "
+ "left join USER_TAB_COMMENTS utc "
+ "on "
+ " ut.table_name=utc.table_name ";
private static final String DM_QUERY_COLUMNS_SQL = ""
+ "select "
+ " ut.table_name TABLE_NAME , "
+ " uc.column_name COLUMN_NAME , "
//+ " case uc.data_type when 'INT' then uc.data_type when 'CLOB' then uc.data_type when 'BLOB' then uc.data_type when 'INTEGER' then uc.data_type else concat(concat(concat(uc.data_type, '('), uc.data_length), ')') end case AS COLUMN_TYPE , "
+ " case uc.data_type when 'CLOB' then uc.data_type when 'BLOB' then uc.data_type else concat(concat(concat(uc.data_type, '('), uc.data_length), ')') end case AS COLUMN_TYPE , "
+ " uc.data_length COLUMN_LENGTH , "
+ " uc.DATA_PRECISION DATA_PRECISION, "
+ " uc.DATA_SCALE DECIMAL_DIGITS, "
+ " case uc.NULLABLE when 'Y' then '1' else '0' end case NULLABLE,"
+ " uc.DATA_DEFAULT COLUMN_DEF, "
+ " ucc.comments REMARKS "
+ "from "
+ " user_tables ut "
+ "left join USER_TAB_COMMENTS utc "
+ "on "
+ " ut.table_name=utc.table_name "
+ "left join user_tab_columns uc "
+ "on "
+ " ut.table_name=uc.table_name "
+ "left join user_col_comments ucc "
+ "on "
+ " uc.table_name =ucc.table_name "
+ " and uc.column_name=ucc.column_name "
+ "where 1=1 ";
private static final String DM_QUERY_PK_SQL = "" + "SELECT "
+ "C.OWNER AS TABLE_SCHEM, "
+ "C.TABLE_NAME , "
+ "C.COLUMN_NAME , "
+ "C.POSITION AS KEY_SEQ , "
+ "C.CONSTRAINT_NAME AS PK_NAME "
+ "FROM "
+ " ALL_CONS_COLUMNS C, "
+ " ALL_CONSTRAINTS K "
+ "WHERE "
+ " K.CONSTRAINT_TYPE = 'P' "
+ " AND K.OWNER = '%s' "
+ " AND K.CONSTRAINT_NAME = C.CONSTRAINT_NAME "
+ " AND K.TABLE_NAME = C.TABLE_NAME "
+ " AND K.OWNER = C.OWNER ";
/**
* 构造函数
*
* @param dataSource {@link DataSource}
*/
public DmDataBaseQuery(DataSource dataSource) {
super(dataSource);
}
/**
* 获取数据库
*
* @return {@link Database} 数据库信息
*/
@Override
public Database getDataBase() throws QueryException {
DmDatabaseModel model = new DmDatabaseModel();
//当前数据库名称
model.setDatabase(getSchema());
return model;
}
/**
* 获取达梦数据库的schema
*
* @return {@link String} 达梦数据库的schema信息
*/
@Override
public String getSchema() throws QueryException {
return null;
}
/**
* 获取达梦数据库的schema
*
* @return {@link String} 达梦数据库的schema信息
*/
public String getSchemaBak() throws QueryException {
try {
String schema = null;
ResultSet rs = getMetaData().getSchemas();
while (rs.next()) {
schema = rs.getString(1);
break;
}
return schema;
} catch (Exception e) {
throw ExceptionUtils.mpe(e);
}
}
/**
* 获取表信息
*
* @return {@link List} 所有表信息
*/
@Override
public List<DmTableModel> getTables() throws QueryException {
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getTables(getSchema(), getSchema(), PERCENT_SIGN,
new String[] { "TABLE" });
//映射
List<DmTableModel> list = Mapping.convertList(resultSet, DmTableModel.class);
resultSet = prepareStatement(DM_QUERY_TABLE_SQL).executeQuery();
List<DmTableModel> inquires = Mapping.convertList(resultSet, DmTableModel.class);
//处理备注信息
list.forEach((DmTableModel model) -> {
//备注
inquires.stream()
.filter(inquire -> model.getTableName().equals(inquire.getTableName()))
.forEachOrdered(inquire -> model.setRemarks(inquire.getRemarks()));
});
if (!list.isEmpty()) {
tablesMap.put("AllTable", list);
}
return list;
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet, this.connection);
}
}
/**
* 获取列信息
*
* @param table {@link String} 表名
* @return {@link List} 表字段信息
*/
@Override
public List<DmColumnModel> getTableColumns(String table) throws QueryException {
Assert.notEmpty(table, "Table name can not be empty!");
ResultSet resultSet = null;
List<DmColumnModel> resultList = new ArrayList<>();
List<String> tableNames = new ArrayList<>();
try {
//从缓存中获取表对象
List<DmTableModel> tables = tablesMap.get("AllTable");
if (tables.isEmpty()) {
tables = getTables();
} else {
for (DmTableModel dtm : tables) {
tableNames.add(dtm.getTableName());
}
}
/*如果表为空,则直接返回*/
if (tableNames.isEmpty()) {
return null;
}
if (CollectionUtils.isEmpty(columnsCaching)) {
//查询全部
if (table.equals(PERCENT_SIGN)) {
PreparedStatement statement = prepareStatement(DM_QUERY_COLUMNS_SQL);
resultSet = statement.executeQuery();
} else {
//查询单表的列信息
String singleTableSql = DM_QUERY_COLUMNS_SQL.concat(" and ut.table_name='%s'");
resultSet = prepareStatement(String.format(singleTableSql, table))
.executeQuery();
}
List<DmColumnModel> inquires = Mapping.convertList(resultSet, DmColumnModel.class);
//这里利用lambda表达式将多行列信息按table name 进行归类,并放入缓存
tableNames.forEach(name -> columnsCaching.put(name, inquires.stream()
.filter(i -> i.getTableName().equals(name)).collect(Collectors.toList())));
resultList = inquires;
}
return resultList;
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet, this.connection);
}
}
/**
* 获取所有列信息
*
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<? extends Column> getTableColumns() throws QueryException {
return getTableColumns(PERCENT_SIGN);
}
/**
* 根据表名获取主键
*
* @param table {@link String}
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys(String table) throws QueryException {
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getPrimaryKeys(getSchema(), getSchema(), table);
//映射
return Mapping.convertList(resultSet, DmPrimaryKeyModel.class);
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet, this.connection);
}
}
/**
* 根据表名获取主键
*
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys() throws QueryException {
ResultSet resultSet = null;
try {
// 由于单条循环查询存在性能问题,所以这里通过自定义SQL查询数据库主键信息
String sql = String.format(DM_QUERY_PK_SQL, getSchema());
resultSet = prepareStatement(sql).executeQuery();
return Mapping.convertList(resultSet, DmPrimaryKeyModel.class);
} catch (SQLException e) {
throw new QueryException(e);
} finally {
JdbcUtils.close(resultSet);
}
}
}
@@ -0,0 +1,177 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.dm.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.Column;
import lombok.Data;
/**
* oracle table column
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/27 8:44
*/
@Data
public class DmColumnModel implements Column {
/**
* 表名称,它是引用属性的作用域(如果 DATA_TYPE 不是 REF,则为 null)
*/
@MappingField(value = "SCOPE_TABLE")
private Object scopeTable;
/**
* 表类别
*/
@MappingField(value = "TABLE_CAT")
private Object tableCat;
/**
* 未被使用
*/
@MappingField(value = "BUFFER_LENGTH")
private String bufferLength;
/**
* ISO 规则用于确定列是否包括 null。
*/
@MappingField(value = "IS_NULLABLE")
private String isNullable;
/**
* 数据源依赖的类型名称,对于 UDT,该类型名称是完全限定的
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
* 该列的默认值,当值在单引号内时应被解释为一个字符串(可为 null)
*/
@MappingField(value = "COLUMN_DEF")
private String columnDef;
/**
* 表的类别,它是引用属性的作用域(如果 DATA_TYPE 不是 REF,则为 null)
*/
@MappingField(value = "SCOPE_CATALOG")
private Object scopeCatalog;
/**
* 表模式
*/
@MappingField(value = "TABLE_SCHEM")
private String tableSchem;
/**
* 列名称
*/
@MappingField(value = "COLUMN_NAME")
private String columnName;
/**
* 是否允许使用 NULL。
*/
@MappingField(value = "NULLABLE")
private String nullable;
/**
* 描述列的注释(可为 null)
*/
@MappingField(value = "REMARKS")
private String remarks;
/**
* 小数部分的位数。对于 DECIMAL_DIGITS 不适用的数据类型,则返回 Null。
*/
@MappingField(value = "DECIMAL_DIGITS")
private String decimalDigits;
/**
* 基数(通常为 10 或 2)
*/
@MappingField(value = "NUM_PREC_RADIX")
private String numPrecRadix;
/**
*
*/
@MappingField(value = "SQL_DATETIME_SUB")
private String sqlDatetimeSub;
/**
*
*/
@MappingField(value = "IS_GENERATEDCOLUMN")
private String isGeneratedColumn;
/**
* 指示此列是否自动增加
* YES --- 如果该列自动增加
* NO --- 如果该列不自动增加
*/
@MappingField(value = "IS_AUTOINCREMENT")
private String isAutoIncrement;
/**
* SQL数据类型
*/
@MappingField(value = "SQL_DATA_TYPE")
private String sqlDataType;
/**
* 对于 char 类型,该长度是列中的最大字节数
*/
@MappingField(value = "CHAR_OCTET_LENGTH")
private String charOctetLength;
/**
* 表中的列的索引(从 1 开始)
*/
@MappingField(value = "ORDINAL_POSITION")
private String ordinalPosition;
/**
* 表的模式,它是引用属性的作用域(如果 DATA_TYPE 不是 REF,则为 null)
*/
@MappingField(value = "SCOPE_SCHEMA")
private String scopeSchema;
/**
* 不同类型或用户生成 Ref 类型、来自 java.sql.Types 的 SQL 类型的源类型(如果 DATA_TYPE 不是 DISTINCT 或用户生成的 REF,则为 null)
*/
@MappingField(value = "SOURCE_DATA_TYPE")
private String sourceDataType;
/**
* 来自 java.sql.Types 的 SQL 类型
*/
@MappingField(value = "DATA_TYPE")
private String dataType;
/**
* 数据源依赖的类型名称,对于 UDT,该类型名称是完全限定的
*/
@MappingField(value = "TYPE_NAME")
private String typeName;
/**
* 列表示给定列的指定列大小。
* 对于数值数据,这是最大精度。
* 对于字符数据,这是字符长度。
* 对于日期时间数据类型,这是 String 表示形式的字符长度(假定允许的最大小数秒组件的精度)。
* 对于二进制数据,这是字节长度。
* 对于 ROWID 数据类型,这是字节长度。对于列大小不适用的数据类型,则返回 Null。
*/
@MappingField(value = "COLUMN_SIZE")
private String columnSize;
/**
* 是否主键
*/
private String primaryKey;
/**
* 列类型(带长度)
*/
@MappingField(value = "COLUMN_TYPE")
private String columnType;
/**
* 列长度
*/
@MappingField(value = "COLUMN_LENGTH")
private String columnLength;
}
@@ -0,0 +1,47 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.dm.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.query.oracle.model.OracleTypesModel;
import lombok.Data;
import java.util.List;
/**
* 数据库信息
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 20:26
*/
@Data
public class DmDatabaseModel implements Database {
private static final long serialVersionUID = 931210775266917894L;
/**
* 数据库名称
*/
@MappingField(value = "TABLE_CAT")
private String database;
@Override
public List<OracleTypesModel> getTypes() {
return null;
}
}
@@ -0,0 +1,58 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.dm.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import lombok.Data;
/**
* oracle table primary
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/27 11:11
*/
@Data
public class DmPrimaryKeyModel implements PrimaryKey {
/**
* 表名
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
* pk name
*/
@MappingField(value = "PK_NAME")
private String pkName;
/**
* 表模式
*/
@MappingField(value = "TABLE_SCHEM")
private String tableSchem;
/**
* 列名
*/
@MappingField(value = "COLUMN_NAME")
private String columnName;
/**
* 键序列
*/
@MappingField(value = "KEY_SEQ")
private String keySeq;
}
@@ -0,0 +1,65 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.dm.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.Table;
import cn.smallbun.screw.core.query.oracle.model.OracleForeignKeyModel;
import lombok.Data;
import java.util.List;
/**
* oracle table
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/27 8:44
*/
@Data
public class DmTableModel implements Table {
/**
* TABLE_CAT
*/
@MappingField(value = "TABLE_CAT")
private String tableCat;
/**
* 表名
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
* 表模式
*/
@MappingField(value = "TABLE_SCHEM")
private String tableSchem;
/**
* 表类型
*/
@MappingField(value = "TABLE_TYPE")
private String tableType;
/**
* 备注
*/
@MappingField(value = "REMARKS")
private String remarks;
@Override
public List<OracleForeignKeyModel> getForeignKeys() {
return null;
}
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* DM Database query implement
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 16:00
*/
package cn.smallbun.screw.core.query.dm.model;
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* DM Database query implement
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 16:00
*/
package cn.smallbun.screw.core.query.dm;
@@ -0,0 +1,107 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.h2;
import cn.smallbun.screw.core.exception.QueryException;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.metadata.Table;
import cn.smallbun.screw.core.query.AbstractDatabaseQuery;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.ExceptionUtils;
import javax.sql.DataSource;
import java.util.List;
import static cn.smallbun.screw.core.constant.DefaultConstants.NOT_SUPPORTED;
/**
* H2 数据库查询
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/18 13:58
*/
public class H2DataBaseQuery extends AbstractDatabaseQuery {
/**
* 构造函数
*
* @param dataSource {@link DataSource}
*/
public H2DataBaseQuery(DataSource dataSource) {
super(dataSource);
}
/**
* 获取数据库
*
* @return {@link Database} 数据库信息
*/
@Override
public Database getDataBase() throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 获取表信息
*
* @return {@link List} 所有表信息
*/
@Override
public List<Table> getTables() {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 获取列信息
*
* @param table {@link String} 表名
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<Column> getTableColumns(String table) throws QueryException {
Assert.notEmpty(table, "Table name can not be empty!");
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 获取所有列信息
*
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<? extends Column> getTableColumns() throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 根据表名获取主键
*
* @param table {@link String}
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys(String table) throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* H2 Database query implement
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 16:01
*/
package cn.smallbun.screw.core.query.h2;
@@ -0,0 +1,107 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.highgo;
import cn.smallbun.screw.core.exception.QueryException;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.metadata.Table;
import cn.smallbun.screw.core.query.AbstractDatabaseQuery;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.ExceptionUtils;
import javax.sql.DataSource;
import java.util.List;
import static cn.smallbun.screw.core.constant.DefaultConstants.NOT_SUPPORTED;
/**
* 瀚高数据库查询
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/20 17:40
*/
public class HigHgoDataBaseQuery extends AbstractDatabaseQuery {
/**
* 构造函数
*
* @param dataSource {@link DataSource}
*/
public HigHgoDataBaseQuery(DataSource dataSource) {
super(dataSource);
}
/**
* 获取数据库
*
* @return {@link Database} 数据库信息
*/
@Override
public Database getDataBase() throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 获取表信息
*
* @return {@link List} 所有表信息
*/
@Override
public List<Table> getTables() {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 获取列信息
*
* @param table {@link String} 表名
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<Column> getTableColumns(String table) throws QueryException {
Assert.notEmpty(table, "Table name can not be empty!");
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 获取所有列信息
*
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<? extends Column> getTableColumns() throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 根据表名获取主键
*
* @param table {@link String}
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys(String table) throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Highgo Database query model
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 16:01
*/
package cn.smallbun.screw.core.query.highgo;
@@ -0,0 +1,106 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.hsql;
import cn.smallbun.screw.core.exception.QueryException;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.metadata.Table;
import cn.smallbun.screw.core.query.AbstractDatabaseQuery;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.ExceptionUtils;
import javax.sql.DataSource;
import java.util.List;
import static cn.smallbun.screw.core.constant.DefaultConstants.NOT_SUPPORTED;
/**
* hsql 数据库查询
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/18 13:59
*/
public class HsqlDataBaseQuery extends AbstractDatabaseQuery {
/**
* 构造函数
*
* @param dataSource {@link DataSource}
*/
public HsqlDataBaseQuery(DataSource dataSource) {
super(dataSource);
}
/**
* 获取数据库
*
* @return {@link Database} 数据库信息
*/
@Override
public Database getDataBase() throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 获取表信息
*
* @return {@link List} 所有表信息
*/
@Override
public List<Table> getTables() {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 获取列信息
*
* @param table {@link String} 表名
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<Column> getTableColumns(String table) throws QueryException {
Assert.notEmpty(table, "Table name can not be empty!");
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 获取所有列信息
*
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<? extends Column> getTableColumns() throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
/**
* 根据表名获取主键
*
* @param table {@link String}
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys(String table) throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
}
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* HSQL Database query implement
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 16:01
*/
package cn.smallbun.screw.core.query.hsql;
@@ -0,0 +1,218 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.mariadb;
import cn.smallbun.screw.core.exception.QueryException;
import cn.smallbun.screw.core.mapping.Mapping;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.query.AbstractDatabaseQuery;
import cn.smallbun.screw.core.query.mariadb.model.MariadbColumnModel;
import cn.smallbun.screw.core.query.mariadb.model.MariadbDatabaseModel;
import cn.smallbun.screw.core.query.mariadb.model.MariadbPrimaryKeyModel;
import cn.smallbun.screw.core.query.mariadb.model.MariadbTableModel;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.CollectionUtils;
import cn.smallbun.screw.core.util.ExceptionUtils;
import cn.smallbun.screw.core.util.JdbcUtils;
import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;
import static cn.smallbun.screw.core.constant.DefaultConstants.PERCENT_SIGN;
/**
* mariadb 数据库查询
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/18 13:59
*/
public class MariaDbDataBaseQuery extends AbstractDatabaseQuery {
/**
* 构造函数
*
* @param dataSource {@link DataSource}
*/
public MariaDbDataBaseQuery(DataSource dataSource) {
super(dataSource);
}
/**
* 获取数据库
*
* @return {@link Database} 数据库信息
*/
@Override
public Database getDataBase() throws QueryException {
MariadbDatabaseModel model = new MariadbDatabaseModel();
model.setDatabase(getCatalog());
return model;
}
/**
* 获取表信息
*
* @return {@link List} 所有表信息
*/
@Override
public List<MariadbTableModel> getTables() throws QueryException {
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getTables(getCatalog(), getSchema(), PERCENT_SIGN,
new String[] { "TABLE" });
//映射
return Mapping.convertList(resultSet, MariadbTableModel.class);
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet);
}
}
/**
* 获取列信息
*
* @param table {@link String} 表名
* @return {@link List} 表字段信息
*/
@SuppressWarnings("DuplicatedCode")
@Override
public List<MariadbColumnModel> getTableColumns(String table) throws QueryException {
Assert.notEmpty(table, "Table name can not be empty!");
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getColumns(getCatalog(), getSchema(), table, PERCENT_SIGN);
//映射
List<MariadbColumnModel> list = Mapping.convertList(resultSet,
MariadbColumnModel.class);
//这里处理是为了如果是查询全部列呢?所以处理并获取唯一表名
List<String> tableNames = list.stream().map(MariadbColumnModel::getTableName)
.collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(columnsCaching)) {
//查询全部
if (table.equals(PERCENT_SIGN)) {
//获取全部表列信息SQL
String sql = "SELECT A.TABLE_NAME, A.COLUMN_NAME, A.COLUMN_TYPE, case when LOCATE('(', A.COLUMN_TYPE) > 0 then replace(substring(A.COLUMN_TYPE, LOCATE('(', A.COLUMN_TYPE) + 1), ')', '') else null end COLUMN_LENGTH FROM INFORMATION_SCHEMA.COLUMNS A WHERE A.TABLE_SCHEMA = '%s'";
PreparedStatement statement = prepareStatement(
String.format(sql, getDataBase().getDatabase()));
resultSet = statement.executeQuery();
int fetchSize = 4284;
if (resultSet.getFetchSize() < fetchSize) {
resultSet.setFetchSize(fetchSize);
}
}
//单表查询
else {
//获取表列信息SQL 查询表名、列名、说明、数据类型
String sql = "SELECT A.TABLE_NAME, A.COLUMN_NAME, A.COLUMN_TYPE, case when LOCATE('(', A.COLUMN_TYPE) > 0 then replace(substring(A.COLUMN_TYPE, LOCATE('(', A.COLUMN_TYPE) + 1), ')', '') else null end COLUMN_LENGTH FROM INFORMATION_SCHEMA.COLUMNS A WHERE A.TABLE_SCHEMA = '%s' and A.TABLE_NAME = '%s'";
resultSet = prepareStatement(
String.format(sql, getDataBase().getDatabase(), table)).executeQuery();
}
List<MariadbColumnModel> inquires = Mapping.convertList(resultSet,
MariadbColumnModel.class);
//处理列,表名为key,列名为值
tableNames.forEach(name -> columnsCaching.put(name, inquires.stream()
.filter(i -> i.getTableName().equals(name)).collect(Collectors.toList())));
}
//处理备注信息
list.forEach(i -> {
//从缓存中根据表名获取列信息
List<Column> columns = columnsCaching.get(i.getTableName());
columns.forEach(j -> {
//列名表名一致
if (i.getColumnName().equals(j.getColumnName())
&& i.getTableName().equals(j.getTableName())) {
//放入列类型
i.setColumnType(j.getColumnType());
i.setColumnLength(j.getColumnLength());
}
});
});
return list;
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet);
}
}
/**
* 获取所有列信息
*
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<? extends Column> getTableColumns() throws QueryException {
//获取全部列
return getTableColumns(PERCENT_SIGN);
}
/**
* 根据表名获取主键
*
* @param table {@link String}
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys(String table) throws QueryException {
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getPrimaryKeys(getCatalog(), getSchema(), table);
//映射
return Mapping.convertList(resultSet, MariadbPrimaryKeyModel.class);
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet, this.connection);
}
}
/**
* 根据表名获取主键
*
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys() throws QueryException {
ResultSet resultSet = null;
try {
// 由于单条循环查询存在性能问题,所以这里通过自定义SQL查询数据库主键信息
// MySQL 8 now use 'PRI' in place of 'pri'
String sql = "SELECT A.TABLE_SCHEMA TABLE_CAT, NULL TABLE_SCHEM, A.TABLE_NAME, A.COLUMN_NAME, B.SEQ_IN_INDEX KEY_SEQ, B.INDEX_NAME PK_NAME FROM INFORMATION_SCHEMA.COLUMNS A, INFORMATION_SCHEMA.STATISTICS B WHERE A.COLUMN_KEY in('PRI', 'pri') AND B.INDEX_NAME = 'PRIMARY' AND (A.TABLE_SCHEMA = '%s') AND (B.TABLE_SCHEMA = '%s') AND A.TABLE_SCHEMA = B.TABLE_SCHEMA AND A.TABLE_NAME = B.TABLE_NAME AND A.COLUMN_NAME = B.COLUMN_NAME ORDER BY A.COLUMN_NAME";
// 拼接参数
String database = getDataBase().getDatabase();
resultSet = prepareStatement(String.format(sql, database, database)).executeQuery();
return Mapping.convertList(resultSet, MariadbPrimaryKeyModel.class);
} catch (SQLException e) {
throw new QueryException(e);
} finally {
JdbcUtils.close(resultSet);
}
}
}
@@ -0,0 +1,176 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.mariadb.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.Column;
import lombok.Data;
/**
* 表字段信息
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 20:24
*/
@Data
public class MariadbColumnModel implements Column {
private static final long serialVersionUID = -7231934486902707912L;
/**
*
*/
@MappingField(value = "SCOPE_TABLE")
private Object scopeTable;
/**
*
*/
@MappingField(value = "TABLE_CAT")
private String tableCat;
/**
*
*/
@MappingField(value = "BUFFER_LENGTH")
private String bufferLength;
/**
*
*/
@MappingField(value = "IS_NULLABLE")
private String isNullable;
/**
*
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
*
*/
@MappingField(value = "COLUMN_DEF")
private String columnDef;
/**
*
*/
@MappingField(value = "SCOPE_CATALOG")
private Object scopeCatalog;
/**
*
*/
@MappingField(value = "TABLE_SCHEM")
private Object tableSchem;
/**
*
*/
@MappingField(value = "COLUMN_NAME")
private String columnName;
/**
*
*/
@MappingField(value = "NULLABLE")
private String nullable;
/**
*
*/
@MappingField(value = "REMARKS")
private String remarks;
/**
*
*/
@MappingField(value = "DECIMAL_DIGITS")
private String decimalDigits;
/**
*
*/
@MappingField(value = "NUM_PREC_RADIX")
private String numPrecRadix;
/**
*
*/
@MappingField(value = "SQL_DATETIME_SUB")
private String sqlDatetimeSub;
/**
*
*/
@MappingField(value = "IS_GENERATEDCOLUMN")
private String isGeneratedColumn;
/**
*
*/
@MappingField(value = "IS_AUTOINCREMENT")
private String isAutoIncrement;
/**
*
*/
@MappingField(value = "SQL_DATA_TYPE")
private String sqlDataType;
/**
*
*/
@MappingField(value = "CHAR_OCTET_LENGTH")
private String charOctetLength;
/**
*
*/
@MappingField(value = "ORDINAL_POSITION")
private String ordinalPosition;
/**
*
*/
@MappingField(value = "SCOPE_SCHEMA")
private Object scopeSchema;
/**
*
*/
@MappingField(value = "SOURCE_DATA_TYPE")
private Object sourceDataType;
/**
*
*/
@MappingField(value = "DATA_TYPE")
private String dataType;
/**
*
*/
@MappingField(value = "TYPE_NAME")
private String typeName;
/**
* 列表示给定列的指定列大小。
* 对于数值数据,这是最大精度。
* 对于字符数据,这是字符长度。
* 对于日期时间数据类型,这是 String 表示形式的字符长度(假定允许的最大小数秒组件的精度)。
* 对于二进制数据,这是字节长度。
* 对于 ROWID 数据类型,这是字节长度。对于列大小不适用的数据类型,则返回 Null。
*/
@MappingField(value = "COLUMN_SIZE")
private String columnSize;
/**
* 是否主键
*/
private String primaryKey;
/**
* 列类型(带长度)
*/
@MappingField(value = "COLUMN_TYPE")
private String columnType;
/**
* 列长度
*/
@MappingField(value = "COLUMN_LENGTH")
private String columnLength;
}
@@ -0,0 +1,47 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.mariadb.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.query.oracle.model.OracleTypesModel;
import lombok.Data;
import java.util.List;
/**
* 数据库信息
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 20:26
*/
@Data
public class MariadbDatabaseModel implements Database {
private static final long serialVersionUID = 931210775266917894L;
/**
* 数据库名称
*/
@MappingField(value = "TABLE_CAT")
private String database;
@Override
public List<OracleTypesModel> getTypes() {
return null;
}
}
@@ -0,0 +1,64 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.mariadb.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import lombok.Data;
/**
* 表主键
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/25 16:52
*/
@Data
public class MariadbPrimaryKeyModel implements PrimaryKey {
private static final long serialVersionUID = -4908250184995248600L;
/**
* tableCat
*/
@MappingField(value = "TABLE_CAT")
private String tableCat;
/**
* 表名
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
* 主键名称
*/
@MappingField(value = "PK_NAME")
private String pkName;
/**
*
*/
@MappingField(value = "TABLE_SCHEM")
private String tableSchem;
/**
* 列名
*/
@MappingField(value = "COLUMN_NAME")
private String columnName;
/**
* 关键序列
*/
@MappingField(value = "KEY_SEQ")
private String keySeq;
}
@@ -0,0 +1,93 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.mariadb.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.Table;
import cn.smallbun.screw.core.query.oracle.model.OracleForeignKeyModel;
import lombok.Data;
import java.util.List;
/**
* 表信息
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 20:22
*/
@Data
public class MariadbTableModel implements Table {
private static final long serialVersionUID = -1917761911812533673L;
/**
* tableCat
*/
@MappingField(value = "TABLE_CAT")
private String tableCat;
/**
* 表名
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
*
*/
@MappingField(value = "SELF_REFERENCING_COL_NAME")
private Object selfReferencingColName;
/**
*
*/
@MappingField(value = "TABLE_CAT")
private Object tableSchem;
/**
*
*/
@MappingField(value = "TYPE_SCHEM")
private Object typeSchem;
/**
*
*/
@MappingField(value = "TABLE_CAT")
private Object typeCat;
/**
* 表类型
*/
@MappingField(value = "TABLE_TYPE")
private String tableType;
/**
* 备注
*/
@MappingField(value = "REMARKS")
private String remarks;
/**
*
*/
@MappingField(value = "REF_GENERATION")
private Object refGeneration;
/**
* 类型名称
*/
@MappingField(value = "TYPE_NAME")
private Object typeName;
@Override
public List<OracleForeignKeyModel> getForeignKeys() {
return null;
}
}
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Mariadb Database query implement
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 16:02
*/
package cn.smallbun.screw.core.query.mariadb.model;
@@ -0,0 +1,23 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Mariadb Database query implement
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 16:02
*/
package cn.smallbun.screw.core.query.mariadb;
@@ -0,0 +1,222 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.mysql;
import cn.smallbun.screw.core.exception.QueryException;
import cn.smallbun.screw.core.mapping.Mapping;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.query.AbstractDatabaseQuery;
import cn.smallbun.screw.core.query.mysql.model.MySqlColumnModel;
import cn.smallbun.screw.core.query.mysql.model.MySqlDatabaseModel;
import cn.smallbun.screw.core.query.mysql.model.MySqlPrimaryKeyModel;
import cn.smallbun.screw.core.query.mysql.model.MySqlTableModel;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.CollectionUtils;
import cn.smallbun.screw.core.util.ExceptionUtils;
import cn.smallbun.screw.core.util.JdbcUtils;
import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;
import static cn.smallbun.screw.core.constant.DefaultConstants.PERCENT_SIGN;
/**
* mysql 数据库查询
* <p>
* 这里需要注意一点,jdbc url 一定要带有 useInformationSchema=true
* 或者通过配置文件方式配置上,这样才会走 {@link com.mysql.cj.jdbc.DatabaseMetaDataUsingInfoSchema} 元数据查询,查询的数据库表为INFORMATION_SCHEMA
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/18 12:46
*/
public class MySqlDataBaseQuery extends AbstractDatabaseQuery {
/**
* 构造函数
*
* @param dataSource {@link DataSource}
*/
public MySqlDataBaseQuery(DataSource dataSource) {
super(dataSource);
}
/**
* 获取数据库
*
* @return {@link Database} 数据库信息
*/
@Override
public Database getDataBase() throws QueryException {
MySqlDatabaseModel model = new MySqlDatabaseModel();
//当前数据库名称
model.setDatabase(getCatalog());
return model;
}
/**
* 获取表信息
*
* @return {@link List} 所有表信息
*/
@Override
public List<MySqlTableModel> getTables() throws QueryException {
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getTables(getCatalog(), getSchema(), PERCENT_SIGN,
new String[] { "TABLE" });
//映射
return Mapping.convertList(resultSet, MySqlTableModel.class);
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet);
}
}
/**
* 获取列信息
*
* @param table {@link String} 表名
* @return {@link List} 表字段信息
*/
@SuppressWarnings("DuplicatedCode")
@Override
public List<MySqlColumnModel> getTableColumns(String table) throws QueryException {
Assert.notEmpty(table, "Table name can not be empty!");
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getColumns(getCatalog(), getSchema(), table, PERCENT_SIGN);
//映射
List<MySqlColumnModel> list = Mapping.convertList(resultSet, MySqlColumnModel.class);
//这里处理是为了如果是查询全部列呢?所以处理并获取唯一表名
List<String> tableNames = list.stream().map(MySqlColumnModel::getTableName)
.collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(columnsCaching)) {
//查询全部
if (table.equals(PERCENT_SIGN)) {
//获取全部表列信息SQL
String sql = "SELECT A.TABLE_NAME, A.COLUMN_NAME, A.COLUMN_TYPE, case when LOCATE('(', A.COLUMN_TYPE) > 0 then replace(substring(A.COLUMN_TYPE, LOCATE('(', A.COLUMN_TYPE) + 1), ')', '') else null end COLUMN_LENGTH FROM INFORMATION_SCHEMA.COLUMNS A WHERE A.TABLE_SCHEMA = '%s'";
PreparedStatement statement = prepareStatement(
String.format(sql, getDataBase().getDatabase()));
resultSet = statement.executeQuery();
int fetchSize = 4284;
if (resultSet.getFetchSize() < fetchSize) {
resultSet.setFetchSize(fetchSize);
}
}
//单表查询
else {
//获取表列信息SQL 查询表名、列名、说明、数据类型
String sql = "SELECT A.TABLE_NAME, A.COLUMN_NAME, A.COLUMN_TYPE, case when LOCATE('(', A.COLUMN_TYPE) > 0 then replace(substring(A.COLUMN_TYPE, LOCATE('(', A.COLUMN_TYPE) + 1), ')', '') else null end COLUMN_LENGTH FROM INFORMATION_SCHEMA.COLUMNS A WHERE A.TABLE_SCHEMA = '%s' and A.TABLE_NAME = '%s'";
resultSet = prepareStatement(
String.format(sql, getDataBase().getDatabase(), table)).executeQuery();
}
List<MySqlColumnModel> inquires = Mapping.convertList(resultSet,
MySqlColumnModel.class);
//处理列,表名为key,列名为值
tableNames.forEach(name -> columnsCaching.put(name, inquires.stream()
.filter(i -> i.getTableName().equals(name)).collect(Collectors.toList())));
}
//处理备注信息
list.forEach(i -> {
//从缓存中根据表名获取列信息
List<Column> columns = columnsCaching.get(i.getTableName());
columns.forEach(j -> {
//列名表名一致
if (i.getColumnName().equals(j.getColumnName())
&& i.getTableName().equals(j.getTableName())) {
//放入列类型
i.setColumnType(j.getColumnType());
i.setColumnLength(j.getColumnLength());
}
});
});
return list;
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet);
}
}
/**
* 获取所有列信息
*
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<? extends Column> getTableColumns() throws QueryException {
//获取全部列
return getTableColumns(PERCENT_SIGN);
}
/**
* 根据表名获取主键
*
* @param table {@link String}
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys(String table) throws QueryException {
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getPrimaryKeys(getCatalog(), getSchema(), table);
//映射
return Mapping.convertList(resultSet, MySqlPrimaryKeyModel.class);
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet, this.connection);
}
}
/**
* 根据表名获取主键信息
*
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys() throws QueryException {
ResultSet resultSet = null;
try {
// 由于单条循环查询存在性能问题,所以这里通过自定义SQL查询数据库主键信息
String sql = "SELECT TABLE_SCHEMA AS TABLE_CAT, NULL AS TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, SEQ_IN_INDEX AS KEY_SEQ, 'PRIMARY' AS PK_NAME FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = '%s' AND INDEX_NAME = 'PRIMARY' ORDER BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX";
// 拼接参数
resultSet = prepareStatement(String.format(sql, getDataBase().getDatabase()))
.executeQuery();
return Mapping.convertList(resultSet, MySqlPrimaryKeyModel.class);
} catch (SQLException e) {
throw new QueryException(e);
} finally {
JdbcUtils.close(resultSet);
}
}
}
@@ -0,0 +1,174 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.mysql.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.Column;
import lombok.Data;
/**
* 表字段信息
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 20:24
*/
@Data
public class MySqlColumnModel implements Column {
private static final long serialVersionUID = -7231934486902707912L;
/**
*
*/
@MappingField(value = "SCOPE_TABLE")
private Object scopeTable;
/**
*
*/
@MappingField(value = "TABLE_CAT")
private String tableCat;
/**
*
*/
@MappingField(value = "BUFFER_LENGTH")
private String bufferLength;
/**
*
*/
@MappingField(value = "IS_NULLABLE")
private String isNullable;
/**
* 表名
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
* 默认值
*/
@MappingField(value = "COLUMN_DEF")
private String columnDef;
/**
*
*/
@MappingField(value = "SCOPE_CATALOG")
private Object scopeCatalog;
/**
*
*/
@MappingField(value = "TABLE_SCHEM")
private Object tableSchem;
/**
*
*/
@MappingField(value = "COLUMN_NAME")
private String columnName;
/**
*
*/
@MappingField(value = "NULLABLE")
private String nullable;
/**
* 说明
*/
@MappingField(value = "REMARKS")
private String remarks;
/**
* 小数位
*/
@MappingField(value = "DECIMAL_DIGITS")
private String decimalDigits;
/**
*
*/
@MappingField(value = "NUM_PREC_RADIX")
private String numPrecRadix;
/**
*
*/
@MappingField(value = "SQL_DATETIME_SUB")
private String sqlDatetimeSub;
/**
*
*/
@MappingField(value = "IS_GENERATEDCOLUMN")
private String isGeneratedColumn;
/**
*
*/
@MappingField(value = "IS_AUTOINCREMENT")
private String isAutoIncrement;
/**
*
*/
@MappingField(value = "SQL_DATA_TYPE")
private String sqlDataType;
/**
*
*/
@MappingField(value = "CHAR_OCTET_LENGTH")
private String charOctetLength;
/**
*
*/
@MappingField(value = "ORDINAL_POSITION")
private String ordinalPosition;
/**
*
*/
@MappingField(value = "SCOPE_SCHEMA")
private Object scopeSchema;
/**
*
*/
@MappingField(value = "SOURCE_DATA_TYPE")
private Object sourceDataType;
/**
* 数据类型
*/
@MappingField(value = "DATA_TYPE")
private String dataType;
/**
*
*/
@MappingField(value = "TYPE_NAME")
private String typeName;
/**
* 列表示给定列的指定列大小。
* 对于数值数据,这是最大精度。
* 对于字符数据,这是字符长度。
* 对于日期时间数据类型,这是 String 表示形式的字符长度(假定允许的最大小数秒组件的精度)。
* 对于二进制数据,这是字节长度。
* 对于 ROWID 数据类型,这是字节长度。对于列大小不适用的数据类型,则返回 Null。
*/
@MappingField(value = "COLUMN_SIZE")
private String columnSize;
/**
* 是否主键
*/
private String primaryKey;
/**
* 列类型(带长度)
*/
@MappingField(value = "COLUMN_TYPE")
private String columnType;
/**
* 列长度
*/
@MappingField(value = "COLUMN_LENGTH")
private String columnLength;
}
@@ -0,0 +1,45 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.mysql.model;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.query.oracle.model.OracleTypesModel;
import lombok.Data;
import java.util.List;
/**
* 数据库信息
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/17 20:26
*/
@Data
public class MySqlDatabaseModel implements Database {
private static final long serialVersionUID = 931210775266917894L;
/**
* 数据库名称
*/
private String database;
@Override
public List<OracleTypesModel> getTypes() {
return null;
}
}
@@ -0,0 +1,64 @@
/*
* screw-core - 简洁好用的数据库表结构文档生成工具
* Copyright © 2020 SanLi (qinggang.zuo@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cn.smallbun.screw.core.query.mysql.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import lombok.Data;
/**
* 表主键
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/25 16:52
*/
@Data
public class MySqlPrimaryKeyModel implements PrimaryKey {
private static final long serialVersionUID = -4908250184995248600L;
/**
* tableCat
*/
@MappingField(value = "TABLE_CAT")
private String tableCat;
/**
* 表名
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
* 主键名称
*/
@MappingField(value = "PK_NAME")
private String pkName;
/**
*
*/
@MappingField(value = "TABLE_SCHEM")
private String tableSchem;
/**
* 列名
*/
@MappingField(value = "COLUMN_NAME")
private String columnName;
/**
*
*/
@MappingField(value = "KEY_SEQ")
private String keySeq;
}

Some files were not shown because too many files have changed in this diff Show More