MYSQL数据库文档生成器

一、概述

    平常会遇到编写文档类的工作,尤其是数据库的,要把每张表的详细字段列出来,手写实在费劲,从网上找了很多,都没有那种直接GUI输入参数,一键生成的,所以自己花时间做了一个,功能很简陋,但是基本需求可以实现。

二、代码

Swing

package com.scc.generate.word;

import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.PrintWriter;
import java.io.StringWriter;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
 * @ClassName: MainJFrame
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @author [email protected]
 * @date 2023年3月30日 下午5:23:40
 * 
 */
public class MainJFrame implements Runnable {

	/*
	 * (非 Javadoc) <p>Title: run</p> <p>Description: </p>
	 * 
	 * @see java.lang.Runnable#run()
	 */
	@Override
	public void run() {
		JFrame frame = new JFrame("数据库WORD生成器-scc");
		frame.setSize(500, 350);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JPanel panel = new JPanel();
		frame.add(panel);
		placeComponents(frame, panel);
		frame.setVisible(true);

	}

	private static void placeComponents(JFrame frame, JPanel panel) {
		panel.setLayout(null);
		// 驱动类
		JLabel driverJLabel = new JLabel("驱动类");
		driverJLabel.setBounds(10, 20, 80, 25);
		panel.add(driverJLabel);
		String[] driverSelectJLabel = { "com.mysql.cj.jdbc.Driver" };
		JComboBox comboBox = new JComboBox();
		comboBox.setModel(new DefaultComboBoxModel(driverSelectJLabel));
		comboBox.setBounds(100, 20, 350, 25);
		panel.add(comboBox);
		// URL
		JLabel urlLabel = new JLabel("URL:");
		urlLabel.setBounds(10, 50, 80, 25);
		panel.add(urlLabel);
		JTextField urlTextLabel = new JTextField(20);
		urlTextLabel.setBounds(100, 50, 350, 25);
		urlTextLabel
				.setText("jdbc:mysql://127.0.0.1:3306/[db_name]?useUnicode=true&characterEncoding=UTF-8&useSSL=false");
		panel.add(urlTextLabel);
		// 用户名
		JLabel uanmeLabel = new JLabel("用户名:");
		uanmeLabel.setBounds(10, 80, 80, 25);
		panel.add(uanmeLabel);
		JTextField uanmeTextLabel = new JTextField(20);
		uanmeTextLabel.setBounds(100, 80, 350, 25);
		uanmeTextLabel.setText("root");
		panel.add(uanmeTextLabel);
		// 密码
		JLabel passwordLabel = new JLabel("密码:");
		passwordLabel.setBounds(10, 110, 80, 25);
		panel.add(passwordLabel);
		JTextField passwordText = new JTextField(20);
		passwordText.setBounds(100, 110, 350, 25);
		passwordText.setText("123456");
		panel.add(passwordText);
		// 文件位置
		JLabel filePathLabel = new JLabel("文件位置:");
		filePathLabel.setBounds(10, 140, 80, 25);
		panel.add(filePathLabel);
		JTextField filePathText = new JTextField(20);
		filePathText.setBounds(100, 140, 350, 25);
		filePathText.setText("/Users/[user]/Desktop/words/");
		panel.add(filePathText);
		// 按钮
		JButton loginButton = new JButton("生成");
		loginButton.setBounds(100, 170, 100, 25);
		panel.add(loginButton);
		// 信息输出
		JTextArea infoJTextArea = new JTextArea();
		infoJTextArea.setLineWrap(true);
		JScrollPane jsp = new JScrollPane(infoJTextArea);
		jsp.setBounds(10, 210, 480, 100);
		jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		panel.add(jsp);
		loginButton.addActionListener(e -> {
			infoJTextArea.append("------------------开始生成------------------");
			infoJTextArea.append("\r\n");
			infoJTextArea.append("配置的驱动:");
			String driver = driverSelectJLabel[comboBox.getSelectedIndex()];
			infoJTextArea.append(driver);
			if (null == driver || "".equals(driver)) {
				infoJTextArea.append("ERROR:未配置驱动!");
			}
			infoJTextArea.append("\r\n");
			infoJTextArea.append("配置的URL:");
			String url = urlTextLabel.getText();
			infoJTextArea.append(url);
			if (null == url || "".equals(url)) {
				infoJTextArea.append("ERROR:未配置URL!");
			}
			infoJTextArea.append("\r\n");
			infoJTextArea.append("配置的用户名:");
			String uname = uanmeTextLabel.getText();
			infoJTextArea.append(uname);
			if (null == uname || "".equals(uname)) {
				infoJTextArea.append("ERROR:未配置用户名!");
			}
			infoJTextArea.append("\r\n");
			infoJTextArea.append("配置的密码:");
			String pwd = passwordText.getText();
			infoJTextArea.append(pwd);
			if (null == pwd || "".equals(pwd)) {
				infoJTextArea.append("ERROR:未配置密码!");
			}
			infoJTextArea.append("\r\n");
			infoJTextArea.append("配置的文件输出位置:");
			String filePath = filePathText.getText();
			infoJTextArea.append(filePath);
			if (null == filePath || "".equals(filePath)) {
				infoJTextArea.append("ERROR:未配置文件输出位置!");
			}
			infoJTextArea.append("\r\n");
			infoJTextArea.setCaretPosition(infoJTextArea.getText().length());
			try {
				new GenerateMysqlWord().generate(driver, url, uname, pwd, filePath);
			} catch (Exception ec) {
				infoJTextArea.append(getErrorInfoFromException(ec));
			}
			infoJTextArea.append("------------------生成完成------------------");
		});
		frame.addComponentListener(new ComponentAdapter() {// 拖动窗口监听
			@Override
			public void componentResized(ComponentEvent e) {
				int whidth = frame.getWidth();// 获取窗口宽度
				int height = frame.getHeight();// 获取窗口宽度
				// 将lable放在 窗口左边的1/3处
				comboBox.setBounds(100, 20, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h) 标签设置宽高不明显
				// 将lable放在 窗口左边的1/2处
				urlTextLabel.setBounds(100, 50, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
				// 宽度始终是窗口的1/2
				uanmeTextLabel.setBounds(100, 80, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
				passwordText.setBounds(100, 110, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
				filePathText.setBounds(100, 140, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
				jsp.setBounds(10, 210, whidth - 25, height - 250);// (起始点x,起始点y,宽地w,高h)
			}

		});
	}

	public static String getErrorInfoFromException(Exception e) {
		StringWriter sw = new StringWriter();
		try (PrintWriter pw = new PrintWriter(sw);) {
			e.printStackTrace(pw);
		}
		return sw.toString();

	}
}

文档生成

package com.scc.generate.word;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.sql.DataSource;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.engine.EngineFileType;
import cn.smallbun.screw.core.engine.EngineTemplateType;
import cn.smallbun.screw.core.execute.DocumentationExecute;
import cn.smallbun.screw.core.process.ProcessConfig;

/**
 * @ClassName: GenerateMysqlWord
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @author [email protected]
 * @date 2023年3月27日 下午3:49:19
 * 
 */
public class GenerateMysqlWord {
	public void generate(String driverClassName, String url, String uname, String pwd, String filePath)
			throws Exception {
		// 数据源:HikariCP 线程池, SpringBoot 2.0开始内置了HikariCP,2.0之前的版本需要引入依赖
		HikariConfig hikariConfig = new HikariConfig();
		// com.mysql.jdbc.Driver MySQL5驱动;com.mysql.cj.jdbc.Driver MySQL6之后的驱动
		hikariConfig.setDriverClassName(driverClassName);
		hikariConfig.setJdbcUrl(url);
		hikariConfig.setUsername(uname);
		hikariConfig.setPassword(pwd);
		// 设置可以获取tables remarks信息
		hikariConfig.addDataSourceProperty("useInformationSchema", "true");
		hikariConfig.setMinimumIdle(2);
		hikariConfig.setMaximumPoolSize(5);
		DataSource dataSource = new HikariDataSource(hikariConfig);

		// 1、生成文件配置
		EngineConfig engineConfig = EngineConfig.builder()
				// 生成文件路径(改成自己的生成路径)
				.fileOutputDir(filePath)
				// 生成后是否立即打开目录
				.openOutputDir(false)
				// 文件类型 有HTML、WORD、MD三种枚举选择
				.fileType(EngineFileType.WORD)
				// 生成模板实现
				.produceType(EngineTemplateType.freemarker).build();

		// 忽略表名(可选)
		List<String> ignoreTableName = Arrays.asList("aa", "test_group");
		// 忽略表前缀(可选)
		List<String> ignorePrefix = Collections.singletonList("czb_");
		// 忽略表后缀(可选)
		List<String> ignoreSuffix = Arrays.asList("_test", "_test1");

		// 2、配置想要忽略的表(可选)
		ProcessConfig processConfig = ProcessConfig.builder().ignoreTableName(ignoreTableName)
				.ignoreTablePrefix(ignorePrefix).ignoreTableSuffix(ignoreSuffix).build();

		// 3、生成文档配置(包含以下自定义版本号、标题、描述(数据库名 + 描述 = 文件名)等配置连接)
		Configuration config = Configuration.builder().version("1.0.0").title("数据库文档").description("数据库设计文档生成")
				.dataSource(dataSource).engineConfig(engineConfig).produceConfig(processConfig).build();

		// 4、执行生成
		new DocumentationExecute(config).execute();
	}
}

main

package com.scc.generate.word;

import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.PrintWriter;
import java.io.StringWriter;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
 * @ClassName: MainJFrame
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @author [email protected]
 * @date 2023年3月30日 下午5:23:40
 * 
 */
public class MainJFrame implements Runnable {

	/*
	 * (非 Javadoc) <p>Title: run</p> <p>Description: </p>
	 * 
	 * @see java.lang.Runnable#run()
	 */
	@Override
	public void run() {
		JFrame frame = new JFrame("数据库WORD生成器-scc");
		frame.setSize(500, 350);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JPanel panel = new JPanel();
		frame.add(panel);
		placeComponents(frame, panel);
		frame.setVisible(true);

	}

	private static void placeComponents(JFrame frame, JPanel panel) {
		panel.setLayout(null);
		// 驱动类
		JLabel driverJLabel = new JLabel("驱动类");
		driverJLabel.setBounds(10, 20, 80, 25);
		panel.add(driverJLabel);
		String[] driverSelectJLabel = { "com.mysql.cj.jdbc.Driver" };
		JComboBox comboBox = new JComboBox();
		comboBox.setModel(new DefaultComboBoxModel(driverSelectJLabel));
		comboBox.setBounds(100, 20, 350, 25);
		panel.add(comboBox);
		// URL
		JLabel urlLabel = new JLabel("URL:");
		urlLabel.setBounds(10, 50, 80, 25);
		panel.add(urlLabel);
		JTextField urlTextLabel = new JTextField(20);
		urlTextLabel.setBounds(100, 50, 350, 25);
		urlTextLabel
				.setText("jdbc:mysql://127.0.0.1:3306/[db_name]?useUnicode=true&characterEncoding=UTF-8&useSSL=false");
		panel.add(urlTextLabel);
		// 用户名
		JLabel uanmeLabel = new JLabel("用户名:");
		uanmeLabel.setBounds(10, 80, 80, 25);
		panel.add(uanmeLabel);
		JTextField uanmeTextLabel = new JTextField(20);
		uanmeTextLabel.setBounds(100, 80, 350, 25);
		uanmeTextLabel.setText("root");
		panel.add(uanmeTextLabel);
		// 密码
		JLabel passwordLabel = new JLabel("密码:");
		passwordLabel.setBounds(10, 110, 80, 25);
		panel.add(passwordLabel);
		JTextField passwordText = new JTextField(20);
		passwordText.setBounds(100, 110, 350, 25);
		passwordText.setText("123456");
		panel.add(passwordText);
		// 文件位置
		JLabel filePathLabel = new JLabel("文件位置:");
		filePathLabel.setBounds(10, 140, 80, 25);
		panel.add(filePathLabel);
		JTextField filePathText = new JTextField(20);
		filePathText.setBounds(100, 140, 350, 25);
		filePathText.setText("/Users/[user]/Desktop/words/");
		panel.add(filePathText);
		// 按钮
		JButton loginButton = new JButton("生成");
		loginButton.setBounds(100, 170, 100, 25);
		panel.add(loginButton);
		// 信息输出
		JTextArea infoJTextArea = new JTextArea();
		infoJTextArea.setLineWrap(true);
		JScrollPane jsp = new JScrollPane(infoJTextArea);
		jsp.setBounds(10, 210, 480, 100);
		jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		panel.add(jsp);
		loginButton.addActionListener(e -> {
			infoJTextArea.append("------------------开始生成------------------");
			infoJTextArea.append("\r\n");
			infoJTextArea.append("配置的驱动:");
			String driver = driverSelectJLabel[comboBox.getSelectedIndex()];
			infoJTextArea.append(driver);
			if (null == driver || "".equals(driver)) {
				infoJTextArea.append("ERROR:未配置驱动!");
			}
			infoJTextArea.append("\r\n");
			infoJTextArea.append("配置的URL:");
			String url = urlTextLabel.getText();
			infoJTextArea.append(url);
			if (null == url || "".equals(url)) {
				infoJTextArea.append("ERROR:未配置URL!");
			}
			infoJTextArea.append("\r\n");
			infoJTextArea.append("配置的用户名:");
			String uname = uanmeTextLabel.getText();
			infoJTextArea.append(uname);
			if (null == uname || "".equals(uname)) {
				infoJTextArea.append("ERROR:未配置用户名!");
			}
			infoJTextArea.append("\r\n");
			infoJTextArea.append("配置的密码:");
			String pwd = passwordText.getText();
			infoJTextArea.append(pwd);
			if (null == pwd || "".equals(pwd)) {
				infoJTextArea.append("ERROR:未配置密码!");
			}
			infoJTextArea.append("\r\n");
			infoJTextArea.append("配置的文件输出位置:");
			String filePath = filePathText.getText();
			infoJTextArea.append(filePath);
			if (null == filePath || "".equals(filePath)) {
				infoJTextArea.append("ERROR:未配置文件输出位置!");
			}
			infoJTextArea.append("\r\n");
			infoJTextArea.setCaretPosition(infoJTextArea.getText().length());
			try {
				new GenerateMysqlWord().generate(driver, url, uname, pwd, filePath);
			} catch (Exception ec) {
				infoJTextArea.append(getErrorInfoFromException(ec));
			}
			infoJTextArea.append("------------------生成完成------------------");
		});
		frame.addComponentListener(new ComponentAdapter() {// 拖动窗口监听
			@Override
			public void componentResized(ComponentEvent e) {
				int whidth = frame.getWidth();// 获取窗口宽度
				int height = frame.getHeight();// 获取窗口宽度
				// 将lable放在 窗口左边的1/3处
				comboBox.setBounds(100, 20, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h) 标签设置宽高不明显
				// 将lable放在 窗口左边的1/2处
				urlTextLabel.setBounds(100, 50, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
				// 宽度始终是窗口的1/2
				uanmeTextLabel.setBounds(100, 80, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
				passwordText.setBounds(100, 110, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
				filePathText.setBounds(100, 140, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
				jsp.setBounds(10, 210, whidth - 25, height - 250);// (起始点x,起始点y,宽地w,高h)
			}

		});
	}

	public static String getErrorInfoFromException(Exception e) {
		StringWriter sw = new StringWriter();
		try (PrintWriter pw = new PrintWriter(sw);) {
			e.printStackTrace(pw);
		}
		return sw.toString();

	}
}

三、使用

    打包成generateMysqlWord.jar,双击执行(需要JDK环境),界面如下:

    输入相应参数即可。

四、说明

    目前实现的功能很简单,其实还可以增加如忽略表的功能,但现在用不到。代码我已经上传到码云,项目地址:https://gitee.com/loveliyiyi/generate-mysql-word

有兴趣的可以关注下微信公共号。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章