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

有興趣的可以關注下微信公共號。

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