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
@@ -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;
}
@@ -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.mysql.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 MySqlTableModel 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 String selfReferencingColName;
/**
*
*/
@MappingField(value = "TABLE_CAT")
private String tableSchem;
/**
*
*/
@MappingField(value = "TYPE_SCHEM")
private String 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 String refGeneration;
/**
* 类型名称
*/
@MappingField(value = "TYPE_NAME")
private String 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/>.
*/
/**
* MySql Database query model
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/6/19 16:02
*/
package cn.smallbun.screw.core.query.mysql.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/>.
*/
/**
* MySQL 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.mysql;
@@ -0,0 +1,349 @@
/*
* 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.oracle;
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.ForeignKey;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.query.AbstractDatabaseQuery;
import cn.smallbun.screw.core.query.oracle.model.*;
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.alibaba.fastjson.JSON;
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;
/**
* oracle 数据库查询
* <p>
* 还是采用从驱动中拿到数据的方式,这里注意一点,一定要加入配置参数remarks为true 否则表和列等说明不会查询出来
* hikari:
* config.addDataSourceProperty("remarks", "true");
* <p>
* 不过这种查询性能很慢 https://docs.oracle.com/en/database/oracle/oracle-database/20/jjdbc/performance-extensions.html#GUID-15865071-39F2-430F-9EDA-EB34D0B2D560
* 所以,只能够通过自定义SQL来了
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/18 13:58
*/
@SuppressWarnings("Duplicates")
public class OracleDataBaseQuery extends AbstractDatabaseQuery {
/**
* 构造函数
*
* @param dataSource {@link DataSource}
*/
public OracleDataBaseQuery(DataSource dataSource) {
super(dataSource);
}
/**
* 获取数据库
*
* @return {@link Database} 数据库信息
*/
@Override
public Database getDataBase() throws QueryException {
OracleDatabaseModel model = new OracleDatabaseModel();
//当前数据库名称
model.setDatabase(getSchema());
//查询当前数据库自定义类型
List<OracleTypesModel> typeList = getCustomTypes();
model.setTypes(typeList);
return model;
}
/**
* TODO 该出再加入该表外键以及外键约束和外键关联表
* 获取表信息
*
* @return {@link List} 所有表信息
*/
@Override
public List<OracleTableModel> getTables() throws QueryException {
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getTables(getCatalog(), getSchema(), PERCENT_SIGN,
new String[] { "TABLE" });
//映射
List<OracleTableModel> list = Mapping.convertList(resultSet, OracleTableModel.class);
//由于ORACLE 查询 REMARKS 非常耗费性能,所以这里使用自定义SQL查询
//https://docs.oracle.com/en/database/oracle/oracle-database/20/jjdbc/performance-extensions.html#GUID-15865071-39F2-430F-9EDA-EB34D0B2D560
//获取所有表 查询表名、说明
String sql = "SELECT TABLE_NAME,COMMENTS AS REMARKS FROM USER_TAB_COMMENTS WHERE TABLE_TYPE = 'TABLE'";
if (isDda()) {
//DBA 使用 DBA_TAB_COMMENTS 进行查询 Oracle连接用户和schema不同问题。dba连接用户可以生成不同schema下的表结构
sql = "SELECT TABLE_NAME,COMMENTS AS REMARKS FROM DBA_TAB_COMMENTS WHERE TABLE_TYPE = 'TABLE' AND OWNER = '"
+ getSchema() + "'";
}
resultSet = prepareStatement(String.format(sql, getSchema())).executeQuery();
List<OracleTableModel> inquires = Mapping.convertList(resultSet,
OracleTableModel.class);
//处理备注信息
list.forEach((OracleTableModel model) -> {
//备注
inquires.stream()
.filter(inquire -> model.getTableName().equals(inquire.getTableName()))
.forEachOrdered(inquire -> model.setRemarks(inquire.getRemarks()));
});
//查询表外键信息
for (OracleTableModel table:list){
List<OracleForeignKeyModel> foreignKeys = getForeignKeys(table.getTableName());
if(foreignKeys.size()!=0){
table.setForeignKeys(foreignKeys);
}
}
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<OracleColumnModel> 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<OracleColumnModel> list = Mapping.convertList(resultSet, OracleColumnModel.class);
//由于ORACLE 查询 COLUMNS REMARKS 为NULL,所以这里使用自定义SQL查询
//https://docs.oracle.com/en/database/oracle/oracle-database/20/jjdbc/performance-extensions.html#GUID-15865071-39F2-430F-9EDA-EB34D0B2D560
List<String> tableNames = list.stream().map(OracleColumnModel::getTableName)
.collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(columnsCaching)) {
//查询全部
if (table.equals(PERCENT_SIGN)) {
String sql = "SELECT ut.TABLE_NAME, ut.COLUMN_NAME, uc.comments as REMARKS, concat(concat(concat(ut.DATA_TYPE, '('), ut.DATA_LENGTH), ')') AS COLUMN_TYPE, ut.DATA_LENGTH as COLUMN_LENGTH FROM user_tab_columns ut INNER JOIN user_col_comments uc ON ut.TABLE_NAME = uc.table_name AND ut.COLUMN_NAME = uc.column_name";
if (isDda()) {
sql = "SELECT ut.TABLE_NAME, ut.COLUMN_NAME, uc.comments as REMARKS, concat(concat(concat(ut.DATA_TYPE, '('), ut.DATA_LENGTH), ')') AS COLUMN_TYPE, ut.DATA_LENGTH as COLUMN_LENGTH FROM dba_tab_columns ut INNER JOIN dba_col_comments uc ON ut.TABLE_NAME = uc.table_name AND ut.COLUMN_NAME = uc.column_name and ut.OWNER = uc.OWNER WHERE ut.OWNER = '"
+ getDataBase() + "'";
}
PreparedStatement statement = prepareStatement(sql);
resultSet = statement.executeQuery();
int fetchSize = 4284;
if (resultSet.getFetchSize() < fetchSize) {
resultSet.setFetchSize(fetchSize);
}
// List<? extends ForeignKey> foreignKeys = getForeignKey(table);
// System.out.println("joieju-uewchoehwo========"+JSON.parse(foreignKeys.toString()));
}
//单表查询
else {
String sql = "SELECT ut.TABLE_NAME, ut.COLUMN_NAME, uc.comments as REMARKS, concat(concat(concat(ut.DATA_TYPE, '('), ut.DATA_LENGTH), ')') AS COLUMN_TYPE, ut.DATA_LENGTH as COLUMN_LENGTH FROM user_tab_columns ut INNER JOIN user_col_comments uc ON ut.TABLE_NAME = uc.table_name AND ut.COLUMN_NAME = uc.column_name WHERE ut.Table_Name = '%s'";
if (isDda()) {
sql = "SELECT ut.TABLE_NAME, ut.COLUMN_NAME, uc.comments as REMARKS, concat(concat(concat(ut.DATA_TYPE, '('), ut.DATA_LENGTH), ')') AS COLUMN_TYPE, ut.DATA_LENGTH as COLUMN_LENGTH FROM dba_tab_columns ut INNER JOIN dba_col_comments uc ON ut.TABLE_NAME = uc.table_name AND ut.COLUMN_NAME = uc.column_name and ut.OWNER = uc.OWNER WHERE ut.Table_Name = '%s' ut.OWNER = '"
+ getDataBase() + "'";
}
resultSet = prepareStatement(String.format(sql, table)).executeQuery();
}
List<OracleColumnModel> inquires = Mapping.convertList(resultSet,
OracleColumnModel.class);
//处理列,表名为key,列名为值
tableNames.forEach(name -> columnsCaching.put(name, inquires.stream()
.filter(i -> i.getTableName().equals(name)).collect(Collectors.toList())));
}
//处理备注信息
//从缓存中根据表名获取列信息
for (OracleColumnModel i : list) {
List<Column> columns = columnsCaching.get(i.getTableName());
columns.forEach(j -> {
//列名表名一致
if (i.getColumnName().equals(j.getColumnName())
&& i.getTableName().equals(j.getTableName())) {
//放入备注
i.setRemarks(j.getRemarks());
i.setColumnLength(j.getColumnLength());
i.setColumnType(j.getColumnType());
}
});
}
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, OraclePrimaryKeyModel.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 NULL AS TABLE_CAT, 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 LIKE '%s' ESCAPE '/' AND K.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND K.TABLE_NAME = C.TABLE_NAME AND K.OWNER = C.OWNER ORDER BY COLUMN_NAME ";
// 拼接参数
resultSet = prepareStatement(String.format(sql, getDataBase().getDatabase()))
.executeQuery();
return Mapping.convertList(resultSet, OraclePrimaryKeyModel.class);
} catch (SQLException e) {
throw new QueryException(e);
} finally {
JdbcUtils.close(resultSet);
}
}
/**
* 通过表名查询外键信息
* @param table
* @return
* @throws QueryException
*/
public List<? extends ForeignKey> getForeignKey(String table) throws QueryException{
ResultSet resultSet = null;
try {
resultSet = getMetaData().getExportedKeys(getCatalog(),getSchema(),table);
return Mapping.convertList(resultSet,OracleForeignKeyModel.class);
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
}finally {
JdbcUtils.close(resultSet);
}
}
/**
* 查询外键数据
* @return
* @throws QueryException
*/
public List<OracleForeignKeyModel> getForeignKeys(String table) throws QueryException{
ResultSet resultSet = null;
try {
String sql = "SELECT cons.constraint_name as constraintName, cols.column_name as columnName, cons.r_constraint_name as constraintKey, cons_owner.table_name AS referencedTable FROM " +
" all_constraints cons JOIN all_cons_columns cols ON cons.constraint_name = cols.constraint_name AND cons.owner = cols.owner " +
" JOIN all_constraints cons_owner ON cons.r_constraint_name = cons_owner.constraint_name AND cons.r_owner = cons_owner.owner " +
" WHERE cols.table_name = '%s' AND cons.constraint_type = 'R' ";
resultSet = prepareStatement(String.format(sql,table)).executeQuery();
List<OracleForeignKeyModel> list = Mapping.convertList(resultSet,OracleForeignKeyModel.class);
return list;
// return Mapping.convertList(resultSet, OracleForeignKeyModel.class);
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
JdbcUtils.close(resultSet);
}
}
/**
* 查询当前数据库的自定义类型
* @return
* @throws QueryException
*/
public List<OracleTypesModel> getCustomTypes() throws QueryException{
ResultSet resultSet = null;
try {
String sql = "SELECT * FROM ALL_TYPE_ATTRS where OWNER = '"+ getSchema() + "'";
resultSet = prepareStatement(sql).executeQuery();
List<OracleTypesModel> list = Mapping.convertList(resultSet,OracleTypesModel.class);
return list;
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
JdbcUtils.close(resultSet);
}
}
/**
*
* 当前用户是否为DBA
*
* @return {@link Boolean}
*/
private boolean isDda() {
ResultSet resultSet = null;
try {
//判断是否是DBA
resultSet = prepareStatement("SELECT USERENV('isdba') as IS_DBA FROM DUAL")
.executeQuery();
String dbaColumn = "IS_DBA";
resultSet.next();
return resultSet.getBoolean(dbaColumn);
} catch (SQLException e) {
throw new QueryException(e);
} finally {
JdbcUtils.close(resultSet);
}
}
}
@@ -0,0 +1,193 @@
/*
* 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.oracle.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 OracleColumnModel 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;
/**
* 字段外鍵名稱
*/
@MappingField(value = "CONSTRAINT_NAME")
private String foreignKey;
/**
* 字段外鍵約束 通過該字段查詢
*/
// @MappingField(value = "R_CONSTRAINT_NAME")
private String constraintKey;
/**
* 字段外鍵關聯表
*/
// @MappingField(value = "CONSTRAINT_TABLE")
private String foreignTable;
}
@@ -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.oracle.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.metadata.model.CustomTypeModel;
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 OracleDatabaseModel implements Database {
private static final long serialVersionUID = 931210775266917894L;
/**
* 数据库名称
*/
@MappingField(value = "TABLE_CAT")
private String database;
/**
* 自定义数据类型
*/
private List<OracleTypesModel> types;
}
@@ -0,0 +1,50 @@
package cn.smallbun.screw.core.query.oracle.model;
import cn.smallbun.screw.core.mapping.MappingField;
import cn.smallbun.screw.core.metadata.ForeignKey;
import lombok.Data;
/**
* oracle 外键相关数据
*/
@Data
public class OracleForeignKeyModel implements ForeignKey {
/**
* 表名
*/
@MappingField(value = "TABLE_NAME")
private String tableName;
/**
* fk name
*/
@MappingField(value = "CONSTRAINTNAME")
private String constraintName;
/**
* 表模式
*/
@MappingField(value = "TABLE_SCHEM")
private String tableSchem;
/**
* 约束键名
*/
@MappingField(value = "CONSTRAINTKEY")
private String constraintKey;
/**
* 外键表
*/
@MappingField(value = "REFERENCEDTABLE")
private String referencedTable;
/**
* 列名
*/
@MappingField(value = "COLUMNNAME")
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