├── lib
├── ojdbc14.jar
├── sqljdbc4-4.0.jar
├── sqlite-jdbc-3.19.3.jar
├── postgresql-9.4.1209.jar
├── javaparser-core-3.6.25.jar
├── gene-plugin-1.0-SNAPSHOT.jar
├── mariadb-java-client-2.3.0.jar
├── mybatis-generator-core-1.3.7.jar
├── mysql-connector-java-5.1.38.jar
└── mysql-connector-java-8.0.11.jar
├── .gitignore
├── screenshots
├── 20181206172726.png
├── 20181206172740.png
├── 20181206172825.png
└── 20181206172856.png
├── src
└── com
│ └── github
│ └── leecho
│ └── idea
│ └── plugin
│ └── mybatis
│ └── generator
│ ├── contants
│ └── PluginContants.java
│ ├── ui
│ ├── GenerateSettingTabUI.java
│ ├── ColumnSettingUI.form
│ ├── DatabaseCredentialUI.java
│ ├── ColumnSettingUI.java
│ ├── ColumnTablePanel.java
│ ├── GeneratorSettingUI.java
│ └── GenerateSettingUI.java
│ ├── model
│ ├── Credential.java
│ ├── DbType.java
│ ├── ColumnSetting.java
│ ├── ColumnSettingModel.java
│ ├── TableInfo.java
│ ├── AbstractTableModel.java
│ ├── GlobalConfig.java
│ └── TableConfig.java
│ ├── plugin
│ ├── RenameExampleClassPlugin.java
│ ├── SwaggerPlugin.java
│ └── LombokPlugin.java
│ ├── generate
│ ├── GenerateCallback.java
│ ├── MergeableShellCallback.java
│ ├── MyBatisCodeGenerator.java
│ └── MyBatisGenerateCommand.java
│ ├── util
│ ├── StringUtils.java
│ ├── JTextFieldHintListener.java
│ ├── DatabaseUtils.java
│ ├── JavaFileMerger.java
│ └── XmlFileMerger.java
│ ├── action
│ └── MainAction.java
│ └── setting
│ ├── SettingConfigurable.java
│ └── MyBatisGeneratorConfiguration.java
├── README.md
├── mybatis-generator-plus.iml
└── resources
└── META-INF
└── plugin.xml
/lib/ojdbc14.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/lib/ojdbc14.jar
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | .idea
3 | out
4 | *.iml
5 |
6 | *.idea
--------------------------------------------------------------------------------
/lib/sqljdbc4-4.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/lib/sqljdbc4-4.0.jar
--------------------------------------------------------------------------------
/lib/sqlite-jdbc-3.19.3.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/lib/sqlite-jdbc-3.19.3.jar
--------------------------------------------------------------------------------
/lib/postgresql-9.4.1209.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/lib/postgresql-9.4.1209.jar
--------------------------------------------------------------------------------
/lib/javaparser-core-3.6.25.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/lib/javaparser-core-3.6.25.jar
--------------------------------------------------------------------------------
/screenshots/20181206172726.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/screenshots/20181206172726.png
--------------------------------------------------------------------------------
/screenshots/20181206172740.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/screenshots/20181206172740.png
--------------------------------------------------------------------------------
/screenshots/20181206172825.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/screenshots/20181206172825.png
--------------------------------------------------------------------------------
/screenshots/20181206172856.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/screenshots/20181206172856.png
--------------------------------------------------------------------------------
/lib/gene-plugin-1.0-SNAPSHOT.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/lib/gene-plugin-1.0-SNAPSHOT.jar
--------------------------------------------------------------------------------
/lib/mariadb-java-client-2.3.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/lib/mariadb-java-client-2.3.0.jar
--------------------------------------------------------------------------------
/lib/mybatis-generator-core-1.3.7.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/lib/mybatis-generator-core-1.3.7.jar
--------------------------------------------------------------------------------
/lib/mysql-connector-java-5.1.38.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/lib/mysql-connector-java-5.1.38.jar
--------------------------------------------------------------------------------
/lib/mysql-connector-java-8.0.11.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leecho/mybatis-generator-plus/HEAD/lib/mysql-connector-java-8.0.11.jar
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/contants/PluginContants.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.contants;
2 |
3 | public class PluginContants {
4 | public static final String PLUGIN_NAME = "mybatis-generator";
5 | }
6 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/ui/GenerateSettingTabUI.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.ui;
2 |
3 | import com.intellij.ide.ui.laf.darcula.ui.DarculaTabbedPaneUI;
4 | import com.intellij.util.ui.JBUI;
5 |
6 | /**
7 | * @author LIQIU
8 | * created on 2019/6/20
9 | **/
10 | public class GenerateSettingTabUI extends DarculaTabbedPaneUI {
11 |
12 | @Override
13 | public void installDefaults(){
14 | super.installDefaults();
15 | this.tabInsets = JBUI.insets(5,30);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/model/Credential.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.model;
2 |
3 | /**
4 | * 保存数据库连接对应的用户名,密码存在keepass库中
5 | * Created by kangtian on 2018/8/3.
6 | */
7 | public class Credential {
8 |
9 | //用户名
10 | private String username;
11 |
12 |
13 | public Credential() {
14 | }
15 |
16 | public Credential(String username) {
17 | this.username = username;
18 |
19 | }
20 |
21 |
22 |
23 | public String getUsername() {
24 | return username;
25 | }
26 |
27 | public void setUsername(String username) {
28 | this.username = username;
29 | }
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MyBatis Generator Plus
2 | 一款与Idea无缝集成的好用的MyBatis生成器
3 | ## 特性:
4 | - 与Idea DataSource插件集成,操作方便
5 | - 提供UI界面对Java代码路径,XML文件路径进行配置
6 | - 提供增强选项,可以选择分页、Lombok等功能
7 | - 支持合并Mapper文件和Xml文件,可以放心修改原来的Mapper文件,无需担心被覆盖
8 |
9 | ## 操作手册
10 | - 在idea中建立数据库
11 | - 选中要生成的表右键点击弹出菜单,选择 "Generator Mybatis Code"
12 | 
13 |
14 | - 在弹出的界面中进行生成配置:
15 | 
16 |
17 | - 首次生成需要配置数据库密码:
18 | 
19 |
20 | - 配置好之后点击OK生成代码,生成后右下角弹出提示,可以点击文件快速预览
21 | 
22 |
23 | ## 如何安装
24 | [点击这里](https://github.com/leecho/mybatis-generator-plus/releases)下载安装包进行安装
25 |
26 | ## 感谢
27 | 本项目是在[better-mybatis-generator](https://github.com/kmaster/better-mybatis-generator)基础之上进行开发的
--------------------------------------------------------------------------------
/mybatis-generator-plus.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/plugin/RenameExampleClassPlugin.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.plugin;
2 |
3 | import org.mybatis.generator.api.IntrospectedTable;
4 | import org.mybatis.generator.api.PluginAdapter;
5 |
6 | import java.util.List;
7 | import java.util.regex.Matcher;
8 | import java.util.regex.Pattern;
9 |
10 | import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
11 | import static org.mybatis.generator.internal.util.messages.Messages.getString;
12 |
13 | public class RenameExampleClassPlugin extends PluginAdapter {
14 | private String target;
15 |
16 | /**
17 | *
18 | */
19 | public RenameExampleClassPlugin() {
20 | }
21 |
22 | @Override
23 | public boolean validate(List warnings) {
24 |
25 | target = this.getProperties().getProperty("target");
26 | boolean valid = stringHasValue(target);
27 |
28 | if (!valid) {
29 | if (!stringHasValue(target)) {
30 | warnings.add(getString("ValidationError.18",
31 | "RenameExampleClassPlugin",
32 | "searchString"));
33 | }
34 | }
35 |
36 | return valid;
37 | }
38 |
39 | @Override
40 | public void initialized(IntrospectedTable introspectedTable) {
41 | introspectedTable.setExampleType(target);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/generate/GenerateCallback.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.generate;
2 |
3 | import com.intellij.openapi.progress.ProgressIndicator;
4 | import com.intellij.openapi.ui.popup.Balloon;
5 | import org.mybatis.generator.api.ProgressCallback;
6 |
7 | public class GenerateCallback implements ProgressCallback {
8 |
9 | private ProgressIndicator indicator;
10 |
11 | private Balloon balloon;
12 |
13 | public GenerateCallback(ProgressIndicator indicator, Balloon balloon) {
14 | this.indicator = indicator;
15 | this.balloon = balloon;
16 | }
17 |
18 | @Override
19 | public void introspectionStarted(int i) {
20 | }
21 |
22 | @Override
23 | public void generationStarted(int i) {
24 | }
25 |
26 | @Override
27 | public void saveStarted(int i) {
28 | }
29 |
30 | @Override
31 | public void startTask(String s) {
32 | System.out.println("Start Task: " + s);
33 | indicator.setText(s);
34 | indicator.setFraction(indicator.getFraction() + 0.1);
35 | }
36 |
37 | @Override
38 | public void done() {
39 | indicator.setText("Generate Finished");
40 | indicator.setFraction(1);
41 | this.balloon.hide();
42 | }
43 |
44 | @Override
45 | public void checkCancel() throws InterruptedException {
46 |
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/util/StringUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.util;
2 |
3 | /**
4 | * Created by Owen on 6/18/16.
5 | */
6 | public class StringUtils {
7 |
8 | /**
9 | *
10 | * convert string from slash style to camel style, such as my_course will convert to MyCourse
11 | *
12 | * @param str
13 | * @return
14 | */
15 | public static String dbStringToCamelStyle(String str) {
16 | if (str != null) {
17 | str = str.toLowerCase();
18 | StringBuilder sb = new StringBuilder();
19 | sb.append(String.valueOf(str.charAt(0)).toUpperCase());
20 | for (int i = 1; i < str.length(); i++) {
21 | char c = str.charAt(i);
22 | if (c != '_') {
23 | sb.append(c);
24 | } else {
25 | if (i + 1 < str.length()) {
26 | sb.append(String.valueOf(str.charAt(i + 1)).toUpperCase());
27 | i++;
28 | }
29 | }
30 | }
31 | return sb.toString();
32 | }
33 | return null;
34 | }
35 | public static boolean isEmpty(Object str) {
36 | return str == null || "".equals(str);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/generate/MergeableShellCallback.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.generate;
2 |
3 | import com.github.leecho.idea.plugin.mybatis.generator.util.JavaFileMerger;
4 | import org.mybatis.generator.exception.ShellException;
5 | import org.mybatis.generator.internal.DefaultShellCallback;
6 |
7 | import java.io.File;
8 | import java.io.FileNotFoundException;
9 |
10 | /**
11 | * @author LIQIU
12 | */
13 | public class MergeableShellCallback extends DefaultShellCallback {
14 |
15 | public MergeableShellCallback(boolean overwrite) {
16 | super(overwrite);
17 | }
18 |
19 | @Override
20 | public boolean isMergeSupported() {
21 | return true;
22 | }
23 |
24 | @Override
25 | public String mergeJavaFile(String newFileSource, File existingFile, String[] javadocTags, String fileEncoding) throws ShellException {
26 | String filePath = existingFile.getAbsolutePath().replace(".java", "");
27 | if (filePath.endsWith("Mapper")) {
28 | try {
29 | return new JavaFileMerger().getNewJavaFile(newFileSource, existingFile.getAbsolutePath());
30 | } catch (FileNotFoundException e) {
31 | throw new ShellException(e);
32 | }
33 | } else {
34 | return newFileSource;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/util/JTextFieldHintListener.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.util;
2 | import javax.swing.*;
3 | import java.awt.*;
4 | import java.awt.event.FocusEvent;
5 | import java.awt.event.FocusListener;
6 | /**
7 | * 输入框提示
8 | * Created by kangtian on 2018/8/3.
9 | */
10 | public class JTextFieldHintListener implements FocusListener {
11 | private String hintText;
12 | private JTextField textField;
13 | public JTextFieldHintListener(JTextField jTextField,String hintText) {
14 | this.textField = jTextField;
15 | this.hintText = hintText;
16 | //默认直接显示
17 | jTextField.setText(hintText);
18 | jTextField.setForeground(Color.GRAY);
19 | }
20 |
21 | @Override
22 | public void focusGained(FocusEvent e) {
23 | //获取焦点时,清空提示内容
24 | String temp = textField.getText();
25 | if(temp.equals(hintText)) {
26 | textField.setText("");
27 | textField.setForeground(Color.BLACK);
28 | }
29 |
30 | }
31 |
32 | @Override
33 | public void focusLost(FocusEvent e) {
34 | //失去焦点时,没有输入内容,显示提示内容
35 | String temp = textField.getText();
36 | if(temp.equals("")) {
37 | textField.setForeground(Color.GRAY);
38 | textField.setText(hintText);
39 | }
40 |
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/util/DatabaseUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.util;
2 |
3 | import com.github.leecho.idea.plugin.mybatis.generator.model.DbType;
4 |
5 | import java.sql.Connection;
6 | import java.sql.DriverManager;
7 | import java.sql.SQLException;
8 |
9 | public class DatabaseUtils {
10 |
11 | public static void testConnection(String driverClass, String url, String username, String password, boolean isMySQL8) throws ClassNotFoundException, SQLException {
12 | boolean connected = false;
13 | Connection conn = null;
14 | if (driverClass.contains("oracle")) {
15 | Class.forName(DbType.Oracle.getDriverClass());
16 | } else if (driverClass.contains("mysql")) {
17 | if (!isMySQL8) {
18 | Class.forName(DbType.MySQL.getDriverClass());
19 | } else {
20 | Class.forName(DbType.MySQL_8.getDriverClass());
21 | url += "?serverTimezone=UTC";
22 | }
23 | } else if (driverClass.contains("postgresql")) {
24 | Class.forName(DbType.PostgreSQL.getDriverClass());
25 | } else if (driverClass.contains("sqlserver")) {
26 | Class.forName(DbType.SqlServer.getDriverClass());
27 | } else if (driverClass.contains("sqlite")) {
28 | Class.forName(DbType.Sqlite.getDriverClass());
29 | } else if (driverClass.contains("mariadb")) {
30 | Class.forName(DbType.MariaDB.getDriverClass());
31 | }
32 |
33 | try {
34 | conn = DriverManager.getConnection(url, username, password);
35 | } finally {
36 | if (conn != null) {
37 | try {
38 | conn.close();
39 | } catch (SQLException e) {
40 | e.printStackTrace();
41 | }
42 | }
43 | }
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/model/DbType.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.model;
2 |
3 | public enum DbType {
4 |
5 | MySQL("com.mysql.jdbc.Driver", "jdbc:mysql://%s:%s/%s?useUnicode=true&useSSL=false&characterEncoding=%s", "mysql-connector-java-5.1.38.jar"),
6 | MySQL_8("com.mysql.cj.jdbc.Driver", "jdbc:mysql://%s:%s/%s?serverTimezone=UTC&useUnicode=true&useSSL=false&characterEncoding=%s", "mysql-connector-java-8.0.11.jar"),
7 | Oracle("oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@%s:%s:%s", "ojdbc14.jar"),
8 | PostgreSQL("org.postgresql.Driver", "jdbc:postgresql://%s:%s/%s", "postgresql-9.4.1209.jar"),
9 | SqlServer("com.microsoft.sqlserver.jdbc.SQLServerDriver", "jdbc:sqlserver://%s:%s;databaseName=%s", "sqljdbc4-4.0.jar"),
10 | Sqlite("org.sqlite.JDBC", "jdbc:sqlite:%s", "sqlite-jdbc-3.19.3.jar"),
11 | MariaDB("org.mariadb.jdbc.Driver", "", "mariadb-java-client-2.3.0.jar");
12 |
13 | private final String driverClass;
14 | private final String connectionUrlPattern;
15 | private final String connectorJarFile;
16 |
17 | DbType(String driverClass, String connectionUrlPattern, String connectorJarFile) {
18 | this.driverClass = driverClass;
19 | this.connectionUrlPattern = connectionUrlPattern;
20 | this.connectorJarFile = connectorJarFile;
21 | }
22 |
23 | public String getDriverClass() {
24 | return driverClass;
25 | }
26 |
27 | public String getConnectionUrlPattern() {
28 | return connectionUrlPattern;
29 | }
30 |
31 | public String getConnectorJarFile() {
32 | return connectorJarFile;
33 | }
34 | }
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/action/MainAction.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.action;
2 |
3 | import com.github.leecho.idea.plugin.mybatis.generator.ui.GenerateSettingUI;
4 | import com.intellij.database.psi.DbTable;
5 | import com.intellij.openapi.actionSystem.AnAction;
6 | import com.intellij.openapi.actionSystem.AnActionEvent;
7 | import com.intellij.openapi.actionSystem.LangDataKeys;
8 | import com.intellij.openapi.ui.Messages;
9 | import com.intellij.psi.PsiElement;
10 |
11 | /**
12 | * Mybatis Generator Plus工具生成类
13 | * Created by kangtian on 2018/7/17.
14 | */
15 | public class MainAction extends AnAction {
16 |
17 |
18 | /**
19 | * 点击后打开插件主页面
20 | *
21 | * @param e
22 | */
23 | @Override
24 | public void actionPerformed(AnActionEvent e) {
25 | PsiElement[] psiElements = e.getData(LangDataKeys.PSI_ELEMENT_ARRAY);
26 | if (psiElements == null || psiElements.length == 0) {
27 | Messages.showMessageDialog("Please select one or more tables", "Mybatis Generator Plus", Messages.getWarningIcon());
28 | return;
29 | }
30 | if (psiElements.length > 1) {
31 | Messages.showMessageDialog("Please select only one table", "Mybatis Generator Plus", Messages.getWarningIcon());
32 | return;
33 | }
34 | for (PsiElement psiElement : psiElements) {
35 | if (!(psiElement instanceof DbTable)) {
36 | Messages.showMessageDialog("Please select one or more tables", "Mybatis Generator Plus", Messages.getWarningIcon());
37 | return;
38 | }
39 | }
40 | GenerateSettingUI ui = new GenerateSettingUI(e);
41 | ui.show();
42 | /*if (ui.showAndGet()) {
43 | ui.generate();
44 | }*/
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/ui/ColumnSettingUI.form:
--------------------------------------------------------------------------------
1 |
2 |
38 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/model/ColumnSetting.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.model;
2 |
3 | /**
4 | * 类型隐射信息
5 | *
6 | * @author makejava
7 | * @version 1.0.0
8 | * @since 2018/07/17 13:10
9 | */
10 | public class ColumnSetting {
11 | /**
12 | * 列类型
13 | */
14 | private String column;
15 | /**
16 | * java类型
17 | */
18 | private String javaType;
19 |
20 | private String jdbcType;
21 |
22 | private String javaProperty;
23 |
24 | private Boolean ignore;
25 |
26 | private Boolean changed;
27 |
28 | private String comment;
29 |
30 | public ColumnSetting(){
31 |
32 | }
33 |
34 | public String getColumn() {
35 | return column;
36 | }
37 |
38 | public void setColumn(String column) {
39 | this.column = column;
40 | }
41 |
42 | public String getJavaType() {
43 | return javaType;
44 | }
45 |
46 | public void setJavaType(String javaType) {
47 | this.javaType = javaType;
48 | }
49 |
50 | public String getJdbcType() {
51 | return jdbcType;
52 | }
53 |
54 | public void setJdbcType(String jdbcType) {
55 | this.jdbcType = jdbcType;
56 | }
57 |
58 | public String getJavaProperty() {
59 | return javaProperty;
60 | }
61 |
62 | public void setJavaProperty(String javaProperty) {
63 | this.javaProperty = javaProperty;
64 | }
65 |
66 | public Boolean getChanged() {
67 | return changed;
68 | }
69 |
70 | public void setChanged(Boolean changed) {
71 | this.changed = changed;
72 | }
73 |
74 | public Boolean getIgnore() {
75 | return ignore;
76 | }
77 |
78 | public void setIgnore(Boolean ignore) {
79 | this.ignore = ignore;
80 | }
81 |
82 | public String getComment() {
83 | return comment;
84 | }
85 |
86 | public void setComment(String comment) {
87 | this.comment = comment;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/model/ColumnSettingModel.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.model;
2 |
3 |
4 | import com.intellij.openapi.ui.Messages;
5 |
6 | /**
7 | * 类型隐射模型
8 | *
9 | * @author makejava
10 | * @version 1.0.0
11 | * @since 2018/07/17 13:10
12 | */
13 | public class ColumnSettingModel extends AbstractTableModel {
14 | @Override
15 | protected String[] initColumnName() {
16 | return new String[]{"Column", "Jdbc Type", "Java Property", "Java Type", "Ignore", "Comment"};
17 | }
18 |
19 | @Override
20 | protected Object[] toObj(ColumnSetting entity) {
21 | return new Object[]{entity.getColumn(), entity.getJdbcType(), entity.getJavaProperty(), entity.getJavaType(), entity.getIgnore(), entity.getComment()};
22 | }
23 |
24 | @Override
25 | protected boolean setVal(ColumnSetting setting, int columnIndex, Object val) {
26 | if (val == null || String.valueOf(val).length() == 0 || String.valueOf(val).equals("")) {
27 | Messages.showMessageDialog("The value must not be null", "Mybatis Generator Plus", Messages.getWarningIcon());
28 | return false;
29 | }
30 | if (columnIndex == 0) {
31 | setting.setColumn((String) val);
32 | } else if (columnIndex == 1) {
33 | if (setting.getJdbcType().equals(val)) {
34 | return false;
35 | }
36 | setting.setJdbcType((String) val);
37 | } else if (columnIndex == 2) {
38 | if (setting.getJavaProperty().equals(val)) {
39 | return false;
40 | }
41 | setting.setJavaProperty((String) val);
42 | } else if (columnIndex == 3) {
43 | if (setting.getJavaType().equals(val)) {
44 | return false;
45 | }
46 | setting.setJavaType((String) val);
47 | } else if (columnIndex == 4) {
48 | setting.setIgnore((Boolean) val);
49 | }
50 | setting.setChanged(true);
51 | return true;
52 | }
53 |
54 | @Override
55 | public boolean isCellEditable(int row, int column) {
56 | return column != 0 && column != 5;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/setting/SettingConfigurable.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.setting;
2 |
3 | import com.github.leecho.idea.plugin.mybatis.generator.ui.GeneratorSettingUI;
4 | import com.intellij.openapi.options.ConfigurationException;
5 | import com.intellij.openapi.options.SearchableConfigurable;
6 | import com.intellij.openapi.project.Project;
7 | import com.sun.istack.internal.NotNull;
8 | import org.jetbrains.annotations.Nls;
9 | import org.jetbrains.annotations.Nullable;
10 |
11 | import javax.swing.*;
12 |
13 | /**
14 | *配置设置界面
15 | * Created by kangtian on 2018/7/18.
16 | */
17 | public class SettingConfigurable implements SearchableConfigurable {
18 | private GeneratorSettingUI mainPanel;
19 |
20 | @SuppressWarnings("FieldCanBeLocal")
21 | private final Project project;
22 |
23 |
24 | public SettingConfigurable(@NotNull Project project) {
25 | this.project = project;
26 | }
27 |
28 | @Nls
29 | @Override
30 | public String getDisplayName() {
31 | return "Mybatis Generator Plus Plus";
32 | }
33 |
34 | @Nullable
35 | @Override
36 | public String getHelpTopic() {
37 | return "gene.helpTopic";
38 | }
39 |
40 | @NotNull
41 | @Override
42 | public String getId() {
43 | return "Mybatis.Generator.Plugin";
44 | }
45 |
46 | @Nullable
47 | @Override
48 | public Runnable enableSearch(String s) {
49 | return null;
50 | }
51 |
52 | @Nullable
53 | @Override
54 | public JComponent createComponent() {
55 | mainPanel = new GeneratorSettingUI();
56 | mainPanel.createUI(project);
57 | return mainPanel.getContentPane();
58 | }
59 |
60 | @Override
61 | public boolean isModified() {
62 | return mainPanel.isModified();
63 | }
64 |
65 | @Override
66 | public void apply() {
67 | mainPanel.apply();
68 | }
69 |
70 | @Override
71 | public void reset() {
72 | mainPanel.reset();
73 | }
74 |
75 | @Override
76 | public void disposeUIResources() {
77 | mainPanel = null;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/model/TableInfo.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.model;
2 |
3 | import com.intellij.database.model.DasColumn;
4 | import com.intellij.database.psi.DbTable;
5 | import com.intellij.database.util.DasUtil;
6 | import com.intellij.util.containers.JBIterable;
7 |
8 | import java.util.*;
9 |
10 | public class TableInfo {
11 |
12 | public final DbTable tableElement;
13 |
14 | private List columns;
15 |
16 | private List primaryKeys = new ArrayList();
17 |
18 |
19 | public TableInfo(DbTable tableElement) {
20 | this.tableElement = tableElement;
21 | List columns = new ArrayList();
22 |
23 | JBIterable extends DasColumn> columnsIter = DasUtil.getColumns(tableElement);
24 | List extends DasColumn> dasColumns = columnsIter.toList();
25 | for (DasColumn dasColumn : dasColumns) {
26 | columns.add(dasColumn);
27 |
28 | if (DasUtil.isPrimary(dasColumn)) {
29 | primaryKeys.add(dasColumn.getName());
30 | }
31 |
32 | }
33 |
34 | this.columns = columns;
35 | }
36 |
37 | public String getTableName() {
38 | return tableElement.getName();
39 | }
40 |
41 | public List getColumns() {
42 | return columns;
43 | }
44 |
45 | public List getColumnsName() {
46 | List columnsName = new ArrayList<>();
47 | for (DasColumn column : columns) {
48 | columnsName.add(column.getName());
49 | }
50 | return columnsName;
51 | }
52 |
53 | public List getPrimaryKeys() {
54 | return this.primaryKeys;
55 | }
56 |
57 | public List getNonPrimaryColumns() {
58 | Set pKNameSet = new HashSet();
59 | for (String pkName : getPrimaryKeys()) {
60 | pKNameSet.add(pkName);
61 | }
62 |
63 | List ret = new ArrayList();
64 | for (DasColumn column : columns) {
65 | if (!pKNameSet.contains(column.getName())) {
66 | ret.add(column);
67 | }
68 | }
69 |
70 | return ret;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/setting/MyBatisGeneratorConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.setting;
2 |
3 | import com.github.leecho.idea.plugin.mybatis.generator.model.TableConfig;
4 | import com.github.leecho.idea.plugin.mybatis.generator.model.Credential;
5 | import com.intellij.openapi.components.PersistentStateComponent;
6 | import com.intellij.openapi.components.ServiceManager;
7 | import com.intellij.openapi.components.State;
8 | import com.intellij.openapi.components.Storage;
9 | import com.intellij.openapi.project.Project;
10 | import com.intellij.util.xmlb.XmlSerializerUtil;
11 | import com.github.leecho.idea.plugin.mybatis.generator.model.GlobalConfig;
12 | import org.jetbrains.annotations.Nullable;
13 |
14 | import java.util.Map;
15 |
16 |
17 | /**
18 | * 配置持久化
19 | */
20 | @State(name = "MyBatisGeneratorConfiguration", storages = {@Storage("mybatis-generator-config.xml")})
21 | public class MyBatisGeneratorConfiguration implements PersistentStateComponent {
22 |
23 | private GlobalConfig globalConfig;
24 | private Map credentials;
25 | private Map tableConfigs;
26 |
27 | @Nullable
28 | public static MyBatisGeneratorConfiguration getInstance(Project project) {
29 | return ServiceManager.getService(project, MyBatisGeneratorConfiguration.class);
30 | }
31 |
32 | @Override
33 | @Nullable
34 | public MyBatisGeneratorConfiguration getState() {
35 | return this;
36 | }
37 |
38 | @Override
39 | public void loadState(MyBatisGeneratorConfiguration myBatisGeneratorConfiguration) {
40 | XmlSerializerUtil.copyBean(myBatisGeneratorConfiguration, this);
41 | }
42 |
43 | public Map getCredentials() {
44 | return credentials;
45 | }
46 |
47 | public void setCredentials(Map credentials) {
48 | this.credentials = credentials;
49 | }
50 |
51 | public Map getTableConfigs() {
52 | return tableConfigs;
53 | }
54 |
55 | public void setTableConfigs(Map tableConfigs) {
56 | this.tableConfigs = tableConfigs;
57 | }
58 |
59 | public GlobalConfig getGlobalConfig() {
60 | if (this.globalConfig == null) {
61 | return GlobalConfig.getDefault();
62 | } else {
63 | return globalConfig;
64 | }
65 | }
66 |
67 | public void setGlobalConfig(GlobalConfig globalConfig) {
68 | this.globalConfig = globalConfig;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/util/JavaFileMerger.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.util;
2 |
3 | import com.github.javaparser.JavaParser;
4 | import com.github.javaparser.ast.CompilationUnit;
5 | import com.github.javaparser.ast.ImportDeclaration;
6 | import com.github.javaparser.ast.Node;
7 | import com.github.javaparser.ast.NodeList;
8 | import com.github.javaparser.ast.body.MethodDeclaration;
9 |
10 | import java.io.File;
11 | import java.io.FileNotFoundException;
12 | import java.util.Arrays;
13 | import java.util.HashSet;
14 | import java.util.List;
15 | import java.util.stream.Collectors;
16 |
17 | /**
18 | * @author LIQIU
19 | */
20 | public class JavaFileMerger {
21 |
22 | public String getNewJavaFile(String newFileSource, String existingFileFullPath) throws FileNotFoundException {
23 | CompilationUnit newCompilationUnit = JavaParser.parse(newFileSource);
24 | CompilationUnit existingCompilationUnit = JavaParser.parse(new File(existingFileFullPath));
25 | return mergerFile(newCompilationUnit, existingCompilationUnit, newFileSource);
26 | }
27 |
28 | public String mergerFile(CompilationUnit newCompilationUnit, CompilationUnit existingCompilationUnit, String newFileSource) {
29 |
30 | NodeList newsImports = newCompilationUnit.getImports();
31 | NodeList existsImports = existingCompilationUnit.getImports();
32 | HashSet allImports = new HashSet<>();
33 | allImports.addAll(newsImports);
34 | allImports.addAll(existsImports);
35 | allImports.removeAll(newsImports);
36 |
37 | List sources = Arrays.stream(newFileSource.split("\n")).collect(Collectors.toList());
38 |
39 | sources.addAll(newsImports.size() + 2, allImports.stream().map(importDeclaration -> importDeclaration.toString().replace("\r\n","")).collect(Collectors.toList()));
40 |
41 |
42 | List newMethods = newCompilationUnit.getTypes().get(0).getMethods();
43 | List oldMethods = existingCompilationUnit.getTypes().get(0).getMethods();
44 | HashSet allMethods = new HashSet<>();
45 | allMethods.addAll(newMethods);
46 | allMethods.addAll(oldMethods);
47 | allMethods.removeAll(newMethods);
48 |
49 | sources.addAll(sources.size() - 1, allMethods.stream().map(methodDeclaration -> "\n" + " " + methodDeclaration.toString()).collect(Collectors.toList()));
50 | return String.join("\n", sources);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/model/AbstractTableModel.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.model;
2 |
3 | import javax.swing.table.DefaultTableModel;
4 | import java.util.List;
5 |
6 | /**
7 | * 抽象的表模型
8 | *
9 | * @author makejava
10 | * @version 1.0.0
11 | * @since 2018/07/17 13:10
12 | */
13 | public abstract class AbstractTableModel extends DefaultTableModel {
14 | /**
15 | * 数据
16 | */
17 | private List data;
18 |
19 | /**
20 | * 构造方法
21 | */
22 | public AbstractTableModel() {
23 | for (String columnName : initColumnName()) {
24 | super.addColumn(columnName);
25 | }
26 | }
27 |
28 | /**
29 | * 初始化方法
30 | *
31 | * @param data 数据
32 | */
33 | public void init(List data) {
34 | if (data.isEmpty()) {
35 | return;
36 | }
37 | // 先移除后赋值,修复复制分组后无数据展示问题
38 | removeAllRow();
39 | this.data = data;
40 | data.forEach(item -> super.addRow(toObj(item)));
41 | }
42 |
43 | public List getData() {
44 | return this.data;
45 | }
46 |
47 |
48 | /**
49 | * 移除所有行
50 | */
51 | private void removeAllRow() {
52 | int rowCount = getRowCount();
53 | if (rowCount > 0) {
54 | for (int i = 0; i < rowCount; i++) {
55 | // 只移除行数据,不移除储存数据,修复切换分组数据自动清空BUG
56 | super.removeRow(0);
57 | }
58 | }
59 | }
60 |
61 | /**
62 | * 移除指定行数据
63 | *
64 | * @param row 行号
65 | */
66 | @Override
67 | public void removeRow(int row) {
68 | super.removeRow(row);
69 | this.data.remove(row);
70 | }
71 |
72 | /**
73 | * 设置值到指定行指定列
74 | *
75 | * @param aValue 值
76 | * @param row 行号
77 | * @param column 列号
78 | */
79 | @Override
80 | public void setValueAt(Object aValue, int row, int column) {
81 | T obj = data.get(row);
82 | if (setVal(obj, column, aValue)) {
83 | super.setValueAt(aValue, row, column);
84 | }
85 | }
86 |
87 | /**
88 | * 添加一行数据
89 | *
90 | * @param entity 实体数据
91 | */
92 | public void addRow(T entity) {
93 | super.addRow(toObj(entity));
94 | this.data.add(entity);
95 | }
96 |
97 | /**
98 | * 抽象初始化列名
99 | *
100 | * @return 列名
101 | */
102 | protected abstract String[] initColumnName();
103 |
104 | /**
105 | * 实体类转数据数组
106 | *
107 | * @param entity 实体类
108 | * @return 数据数组
109 | */
110 | protected abstract Object[] toObj(T entity);
111 |
112 | /**
113 | * 设置实体类的值
114 | *
115 | * @param obj 实体类
116 | * @param columnIndex 列索引
117 | * @param val 值
118 | */
119 | protected abstract boolean setVal(T obj, int columnIndex, Object val);
120 | }
121 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/ui/DatabaseCredentialUI.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.ui;
2 |
3 | import com.github.leecho.idea.plugin.mybatis.generator.contants.PluginContants;
4 | import com.github.leecho.idea.plugin.mybatis.generator.model.Credential;
5 | import com.github.leecho.idea.plugin.mybatis.generator.setting.MyBatisGeneratorConfiguration;
6 | import com.github.leecho.idea.plugin.mybatis.generator.util.StringUtils;
7 | import com.intellij.openapi.ui.DialogWrapper;
8 | import com.intellij.openapi.ui.VerticalFlowLayout;
9 | import com.intellij.ui.JBColor;
10 | import com.intellij.ui.components.JBPasswordField;
11 | import com.intellij.util.ui.JBUI;
12 | import com.intellij.credentialStore.CredentialAttributes;
13 | import com.intellij.credentialStore.Credentials;
14 | import com.intellij.ide.passwordSafe.PasswordSafe;
15 | import com.intellij.openapi.project.Project;
16 | import com.intellij.openapi.vfs.VirtualFile;
17 | import com.intellij.ui.components.JBPanel;
18 | import com.intellij.ui.components.JBTextField;
19 | import org.jetbrains.annotations.Nullable;
20 |
21 | import javax.swing.*;
22 | import java.awt.*;
23 | import java.util.HashMap;
24 | import java.util.Map;
25 |
26 | /**
27 | * 账号密码输入界面
28 | * Created by kangtian on 2018/8/3.
29 | */
30 | public class DatabaseCredentialUI extends DialogWrapper {
31 |
32 | private MyBatisGeneratorConfiguration myBatisGeneratorConfiguration;
33 | private String url;
34 | private Project project;
35 | private JPanel contentPanel = new JBPanel<>();
36 |
37 | private JTextField usernameField = new JBTextField(30);
38 | private JTextField passwordField = new JBPasswordField();
39 | private JLabel errorMessage = new JLabel("");
40 |
41 |
42 | public DatabaseCredentialUI(Project project, String url) throws HeadlessException {
43 | super(project);
44 | this.url = url;
45 | this.project = project;
46 | this.myBatisGeneratorConfiguration = MyBatisGeneratorConfiguration.getInstance(project);
47 | setTitle("Connect to Database");
48 | pack();
49 |
50 | contentPanel.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP));
51 | Map credentials = myBatisGeneratorConfiguration.getCredentials();
52 |
53 | JPanel usernamePanel = new JBPanel<>();
54 | usernamePanel.setLayout(new BoxLayout(usernamePanel, BoxLayout.X_AXIS));
55 | usernamePanel.setBorder(JBUI.Borders.empty(1));
56 | JLabel usernameLabel = new JLabel("Username:");
57 | usernameLabel.setPreferredSize(new Dimension(80, 20));
58 | usernamePanel.add(usernameLabel);
59 | usernamePanel.add(usernameField);
60 | if(credentials != null && credentials.containsKey(url)){
61 | usernameField.setText(credentials.get(url).getUsername());
62 | }
63 |
64 | JPanel passwordPanel = new JBPanel<>();
65 | passwordPanel.setLayout(new BoxLayout(passwordPanel, BoxLayout.X_AXIS));
66 | passwordPanel.setBorder(JBUI.Borders.empty(1));
67 | JLabel passwordLabel = new JLabel("Password:");
68 | passwordLabel.setPreferredSize(new Dimension(80, 20));
69 | passwordPanel.add(passwordLabel);
70 | passwordPanel.add(passwordField);
71 | contentPanel.add(usernamePanel);
72 | contentPanel.add(passwordPanel);
73 | contentPanel.add(errorMessage);
74 | errorMessage.setForeground(JBColor.RED);
75 | this.init();
76 | }
77 |
78 | @Override
79 | protected void doOKAction() {
80 |
81 | if (StringUtils.isEmpty(usernameField.getText())) {
82 | errorMessage.setText("Username must not be null");
83 | return;
84 | }
85 |
86 | if (StringUtils.isEmpty(passwordField.getText())) {
87 | errorMessage.setText("Password must not be null");
88 | return;
89 | }
90 |
91 | Map credentials = myBatisGeneratorConfiguration.getCredentials();
92 | if (credentials == null) {
93 | credentials = new HashMap<>();
94 | }
95 | credentials.put(url, new Credential(usernameField.getText()));
96 | CredentialAttributes attributes = new CredentialAttributes(PluginContants.PLUGIN_NAME + "-" + url, usernameField.getText(), this.getClass(), false);
97 | Credentials saveCredentials = new Credentials(attributes.getUserName(), passwordField.getText());
98 | PasswordSafe.getInstance().set(attributes, saveCredentials);
99 | myBatisGeneratorConfiguration.setCredentials(credentials);
100 | VirtualFile baseDir = project.getBaseDir();
101 | baseDir.refresh(false, true);
102 |
103 | super.doOKAction();
104 | }
105 |
106 | @Nullable
107 | @Override
108 | protected JComponent createCenterPanel() {
109 | return this.contentPanel;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/ui/ColumnSettingUI.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.ui;
2 |
3 | import com.github.leecho.idea.plugin.mybatis.generator.model.TableConfig;
4 | import com.github.leecho.idea.plugin.mybatis.generator.model.TableInfo;
5 | import com.github.leecho.idea.plugin.mybatis.generator.model.ColumnSetting;
6 | import com.github.leecho.idea.plugin.mybatis.generator.model.ColumnSettingModel;
7 | import com.github.leecho.idea.plugin.mybatis.generator.util.StringUtils;
8 | import com.intellij.openapi.project.Project;
9 | import com.intellij.openapi.ui.DialogWrapper;
10 | import org.jdesktop.swingx.JXTable;
11 | import org.jetbrains.annotations.Nullable;
12 | import org.mybatis.generator.api.IntrospectedColumn;
13 | import org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl;
14 | import org.mybatis.generator.internal.types.JdbcTypeNameTranslator;
15 |
16 | import javax.swing.*;
17 | import java.awt.*;
18 | import java.sql.Types;
19 | import java.util.ArrayList;
20 |
21 | /**
22 | * 类型映射设置
23 | *
24 | * @author makejava
25 | * @version 1.0.0
26 | * @since 2018/07/17 13:10
27 | */
28 | public class ColumnSettingUI extends DialogWrapper {
29 | /**
30 | * 主面板
31 | */
32 | private JPanel mainPanel;
33 | /**
34 | * 类型映射表
35 | */
36 | private JTable columnSettingTable;
37 |
38 | /**
39 | * 类型映射表模型
40 | */
41 | private ColumnSettingModel columnSettingModel;
42 |
43 | private TableConfig tableConfig;
44 |
45 | public ColumnSettingUI(Project project, TableConfig tableConfig, TableInfo tableInfo) {
46 | super(project);
47 | //添加类型
48 | // 初始化操作
49 | this.tableConfig = tableConfig;
50 | load(tableConfig, tableInfo);
51 | columnSettingTable.getColumnModel().setColumnMargin(3);
52 | columnSettingTable.getColumnModel().getColumn(4).setCellEditor(new JXTable.BooleanEditor());
53 | columnSettingTable.getColumnModel().getColumn(3).setWidth(50);
54 | this.setTitle("Column Setting");
55 | mainPanel.setPreferredSize(new Dimension(800,300));
56 | this.init();
57 | }
58 |
59 | @Nullable
60 | @Override
61 | protected JComponent createCenterPanel() {
62 | return mainPanel;
63 | }
64 |
65 | @Override
66 | protected void doOKAction() {
67 | java.util.List columnSettingList = this.columnSettingModel.getData();
68 | columnSettingList.forEach(columnSetting -> {
69 | if (columnSetting.getChanged()) {
70 | columnSetting.setChanged(false);
71 | tableConfig.getColumnSettings().put(columnSetting.getColumn(), columnSetting);
72 | }
73 | });
74 | super.doOKAction();
75 | }
76 |
77 | /**
78 | * 初始化方法
79 | */
80 | protected void load(TableConfig tableConfig, TableInfo tableInfo) {
81 | //初始化表格
82 | this.columnSettingModel = new ColumnSettingModel();
83 | JavaTypeResolverDefaultImpl resolver = new JavaTypeResolverDefaultImpl();
84 | java.util.List columnSettingList = new ArrayList<>();
85 | tableInfo.getColumns().forEach(dasColumn -> {
86 |
87 | ColumnSetting columnSetting = tableConfig.getColumnSettings().get(dasColumn.getName());
88 | IntrospectedColumn introspectedColumn = new IntrospectedColumn();
89 | String typeName = dasColumn.getDataType().typeName.toUpperCase();
90 | if ("DATETIME".equals(typeName)) {
91 | introspectedColumn.setJdbcType(Types.TIMESTAMP);
92 | } else if ("INT".equals(typeName)) {
93 | introspectedColumn.setJdbcType(Types.INTEGER);
94 | } else {
95 | introspectedColumn.setJdbcType(JdbcTypeNameTranslator.getJdbcType(typeName));
96 | }
97 | introspectedColumn.setLength(dasColumn.getDataType().getLength());
98 | introspectedColumn.setScale(dasColumn.getDataType().getScale());
99 |
100 | if (columnSetting == null) {
101 | columnSetting = new ColumnSetting();
102 | columnSetting.setColumn(dasColumn.getName());
103 | String property = StringUtils.dbStringToCamelStyle(dasColumn.getName());
104 | property = property.substring(0, 1).toLowerCase() + property.substring(1);
105 | columnSetting.setJavaProperty(property);
106 | columnSetting.setJdbcType(resolver.calculateJdbcTypeName(introspectedColumn));
107 | columnSetting.setJavaType(resolver.calculateJavaType(introspectedColumn).getShortName());
108 | columnSetting.setIgnore(false);
109 | }else{
110 | if(!columnSetting.getJdbcType().equals(resolver.calculateJdbcTypeName(introspectedColumn))){
111 | columnSetting.setJdbcType(resolver.calculateJdbcTypeName(introspectedColumn));
112 | columnSetting.setJavaType(resolver.calculateJavaType(introspectedColumn).getShortName());
113 | }
114 | }
115 | columnSetting.setComment(dasColumn.getComment());
116 | columnSetting.setChanged(false);
117 | columnSettingList.add(columnSetting);
118 | });
119 | columnSettingModel.init(columnSettingList);
120 | this.columnSettingTable.setModel(columnSettingModel);
121 | }
122 |
123 | }
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/plugin/SwaggerPlugin.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.plugin;
2 |
3 | import com.github.leecho.idea.plugin.mybatis.generator.util.StringUtils;
4 | import org.mybatis.generator.api.IntrospectedColumn;
5 | import org.mybatis.generator.api.IntrospectedTable;
6 | import org.mybatis.generator.api.PluginAdapter;
7 | import org.mybatis.generator.api.dom.java.Field;
8 | import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
9 | import org.mybatis.generator.api.dom.java.Interface;
10 | import org.mybatis.generator.api.dom.java.TopLevelClass;
11 |
12 | import java.util.List;
13 |
14 |
15 | /**
16 | * A MyBatis Generator plugin to use Lombok's annotations.
17 | * For example, use @Data annotation instead of getter ands setter.
18 | *
19 | * @author Paolo Predonzani (http://softwareloop.com/)
20 | */
21 | public class SwaggerPlugin extends PluginAdapter {
22 |
23 | /**
24 | * @param warnings list of warnings
25 | * @return always true
26 | */
27 | @Override
28 | public boolean validate(List warnings) {
29 | return true;
30 | }
31 |
32 | /**
33 | * Intercepts base record class generation
34 | *
35 | * @param topLevelClass the generated base record class
36 | * @param introspectedTable The class containing information about the table as
37 | * introspected from the database
38 | * @return always true
39 | */
40 | @Override
41 | public boolean modelBaseRecordClassGenerated(
42 | TopLevelClass topLevelClass,
43 | IntrospectedTable introspectedTable
44 | ) {
45 | addAnnotations(topLevelClass, introspectedTable.getRemarks());
46 | return true;
47 | }
48 |
49 | /**
50 | * Intercepts primary key class generation
51 | *
52 | * @param topLevelClass the generated primary key class
53 | * @param introspectedTable The class containing information about the table as
54 | * introspected from the database
55 | * @return always true
56 | */
57 | @Override
58 | public boolean modelPrimaryKeyClassGenerated(
59 | TopLevelClass topLevelClass,
60 | IntrospectedTable introspectedTable
61 | ) {
62 | addAnnotations(topLevelClass, introspectedTable.getRemarks());
63 | return true;
64 | }
65 |
66 | /**
67 | * Intercepts "record with blob" class generation
68 | *
69 | * @param topLevelClass the generated record with BLOBs class
70 | * @param introspectedTable The class containing information about the table as
71 | * introspected from the database
72 | * @return always true
73 | */
74 | @Override
75 | public boolean modelRecordWithBLOBsClassGenerated(
76 | TopLevelClass topLevelClass,
77 | IntrospectedTable introspectedTable
78 | ) {
79 | addAnnotations(topLevelClass, introspectedTable.getRemarks());
80 | return true;
81 | }
82 |
83 | @Override
84 | public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
85 | if (!StringUtils.isEmpty(introspectedColumn.getRemarks())) {
86 | addFieldAnnotations(topLevelClass, field, introspectedColumn.getRemarks());
87 | }
88 | return true;
89 | }
90 |
91 | /**
92 | * Adds the lombok annotations' imports and annotations to the class
93 | *
94 | * @param topLevelClass the partially implemented model class
95 | */
96 | private void addFieldAnnotations(TopLevelClass topLevelClass, Field field, String name) {
97 | topLevelClass.addImportedType(new FullyQualifiedJavaType("io.swagger.annotations.ApiModelProperty"));
98 | field.addAnnotation(String.format("@ApiModelProperty(\"%s\")", name));
99 | }
100 |
101 | /**
102 | * Adds the lombok annotations' imports and annotations to the class
103 | *
104 | * @param topLevelClass the partially implemented model class
105 | */
106 | private void addAnnotations(TopLevelClass topLevelClass, String name) {
107 | topLevelClass.addImportedType(new FullyQualifiedJavaType("io.swagger.annotations.ApiModel"));
108 | String[] parts = name.split("\\.");
109 | topLevelClass.addAnnotation(String.format("@ApiModel(\"%s\")", parts[parts.length - 1]));
110 | }
111 |
112 |
113 | @Override
114 | public boolean clientGenerated(
115 | Interface interfaze,
116 | TopLevelClass topLevelClass,
117 | IntrospectedTable introspectedTable
118 | ) {
119 | interfaze.addImportedType(new FullyQualifiedJavaType(
120 | "org.apache.ibatis.annotations.Mapper"));
121 | interfaze.addAnnotation("@Mapper");
122 | return true;
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/resources/META-INF/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 | com.github.leecho.idea.plugin.mybatis.generator
3 | MyBatis Generator Plus
4 | 1.5
5 | Leecho
6 |
7 |
8 |
10 |
11 | Integrate with the Idea Database tool
12 | Support mapper class file merge
13 | Support mapper xml file merge
14 | Support customize postfix for mapper class
15 | Support customize postfix for example class
16 | Support table prefix for domain class
17 | Support customize setting for column
18 | Support for IDEA the latest version.
19 | Optimize Mysql8 database connection.
20 | Add MariaDB support
21 |
22 |
23 | ]]>
24 |
26 |
27 | 集成Idea Database工具
28 | 支持Mapper类文件自动合并
29 | 支持Mapper XML文件自动合并
30 | 支持自动忽略表前缀
31 | 支持自定义Mapper类后缀
32 | 支持自定义Example类后缀
33 | 支持修改字段数据类型
34 | 支持忽略字段
35 |
36 |
37 | ]]>
38 |
40 | Use in idea database tool,right click table to generate mybatis files (include:mapper、example、domain、xml).Currently supported databases: Mysql, Oracle. To be verified: Mysql 8, Postgre SQL and SQL Server
41 | Step1: Connecting to Your Database: View > Tool Windows > Database.
42 | Step2: Select one tablesRight Click and select Generate MyBatis Code to open generator main UI.
43 | Step3: Check configuration in main ui,click ok.
44 | Step4: Provide account and password for the first time.
45 | Step5: Generate work finish,check files and it can be use.
46 | Setting: Tools > MyBatis Generator Plus set custom default configuration,If not, use the program default configuration.
47 | More tutorial please visit here
48 |
49 |
50 |
51 | - 在idea的database工具中使用,右击选择表生成mybatis相关的代码。目前已支持的数据库:Mysql、Mysql8(可能需要设置数据库时区time_zone = '+8:00')、Oracle、MariaDB。待验证:PostgreSQL与SQL Server
52 | - Step1: 连接Database: View > Tool Windows > Database。
53 | - Step2: 选择表,右击选择功能 Generate MyBatis Code 打开主页面。
54 | - Step3: 检查配置无误后点击 ok。
55 | - Step4: 首次使用时请提供账号密码。p
56 | - Step5: 生成完成,检查、使用代码。
57 | - Setting: Tools > MyBatis Generator Plus 此处设置默认配置,未设置则使用程序默认配置。
58 |
59 | ]]>
60 |
61 |
62 |
63 |
64 |
66 | v1.0
67 | Init Version
68 |
69 | v1.1
70 | Update description
71 |
72 | v1.2
73 | add comment column for column setting ui
74 | fix database column type change bug
75 |
76 | v1.3
77 | optimization some feature
78 |
79 | v1.4
80 | add swagger support options
81 | add table prefix support
82 | new ui for generate setting
83 | fixed some bugs
84 |
85 | v1.5
86 | fix cannot get table remark bug
87 | fix cannot support sql server bug
88 | add progressbar for display connect to database
89 |
90 |
91 |
92 | ]]>
93 |
94 |
95 |
96 |
97 | com.intellij.database
98 |
99 |
102 |
104 |
105 |
106 |
107 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/ui/ColumnTablePanel.java:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * @author LIQIU
4 | * created on 2019/6/20
5 | **/
6 | package com.github.leecho.idea.plugin.mybatis.generator.ui;
7 |
8 | import com.github.leecho.idea.plugin.mybatis.generator.model.ColumnSetting;
9 | import com.github.leecho.idea.plugin.mybatis.generator.model.ColumnSettingModel;
10 | import com.github.leecho.idea.plugin.mybatis.generator.model.TableConfig;
11 | import com.github.leecho.idea.plugin.mybatis.generator.model.TableInfo;
12 | import com.github.leecho.idea.plugin.mybatis.generator.util.StringUtils;
13 | import com.intellij.openapi.ui.VerticalFlowLayout;
14 | import com.intellij.ui.components.JBPanel;
15 | import com.intellij.ui.components.JBScrollPane;
16 | import com.intellij.ui.table.JBTable;
17 | import com.intellij.util.ui.JBUI;
18 | import org.jdesktop.swingx.JXTable;
19 | import org.mybatis.generator.api.IntrospectedColumn;
20 | import org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl;
21 | import org.mybatis.generator.internal.types.JdbcTypeNameTranslator;
22 |
23 | import javax.swing.*;
24 | import javax.swing.event.TableModelEvent;
25 | import javax.swing.event.TableModelListener;
26 | import java.awt.*;
27 | import java.sql.Types;
28 | import java.util.ArrayList;
29 |
30 | /**
31 | * @author LIQIU
32 | * created on 2019/6/20
33 | **/
34 | public class ColumnTablePanel extends JBPanel {
35 |
36 | /**
37 | * 类型映射表
38 | */
39 | private JTable columnSettingTable = new JBTable();
40 |
41 | /**
42 | * 类型映射表模型
43 | */
44 | private ColumnSettingModel columnSettingModel;
45 |
46 | private TableConfig tableConfig;
47 |
48 | public ColumnTablePanel(TableConfig tableConfig, TableInfo tableInfo) {
49 | //添加类型
50 | // 初始化操作
51 | this.tableConfig = tableConfig;
52 | load(tableConfig, tableInfo);
53 | this.setName("Columns");
54 | columnSettingTable.getColumnModel().setColumnMargin(3);
55 | columnSettingTable.getColumnModel().getColumn(4).setCellEditor(new JXTable.BooleanEditor());
56 | columnSettingTable.getColumnModel().getColumn(3).setWidth(50);
57 | VerticalFlowLayout layout= new VerticalFlowLayout(VerticalFlowLayout.TOP);
58 | layout.setVgap(0);
59 | layout.setHgap(0);
60 | layout.setHorizontalFill(true);
61 | layout.setVerticalFill(true);
62 | this.setLayout(layout);
63 | JBScrollPane jScrollPane = new JBScrollPane(columnSettingTable);
64 | jScrollPane.setPreferredSize(new Dimension(800,320));
65 | this.setBorder(JBUI.Borders.empty(-11));
66 | this.add(jScrollPane);
67 | this.setVisible(true);
68 | }
69 |
70 |
71 | /**
72 | * 初始化方法
73 | */
74 | protected void load(TableConfig tableConfig, TableInfo tableInfo) {
75 | //初始化表格
76 | this.columnSettingModel = new ColumnSettingModel();
77 | JavaTypeResolverDefaultImpl resolver = new JavaTypeResolverDefaultImpl();
78 | java.util.List columnSettingList = new ArrayList<>();
79 | tableInfo.getColumns().forEach(dasColumn -> {
80 |
81 | ColumnSetting columnSetting = tableConfig.getColumnSettings().get(dasColumn.getName());
82 | IntrospectedColumn introspectedColumn = new IntrospectedColumn();
83 | String typeName = dasColumn.getDataType().typeName.toUpperCase();
84 | if ("DATETIME".equals(typeName)) {
85 | introspectedColumn.setJdbcType(Types.TIMESTAMP);
86 | } else if ("INT".equals(typeName)) {
87 | introspectedColumn.setJdbcType(Types.INTEGER);
88 | } else {
89 | introspectedColumn.setJdbcType(JdbcTypeNameTranslator.getJdbcType(typeName));
90 | }
91 | introspectedColumn.setLength(dasColumn.getDataType().getLength());
92 | introspectedColumn.setScale(dasColumn.getDataType().getScale());
93 |
94 | if (columnSetting == null) {
95 | columnSetting = new ColumnSetting();
96 | columnSetting.setColumn(dasColumn.getName());
97 | String property = StringUtils.dbStringToCamelStyle(dasColumn.getName());
98 | property = property.substring(0, 1).toLowerCase() + property.substring(1);
99 | columnSetting.setJavaProperty(property);
100 | columnSetting.setJdbcType(resolver.calculateJdbcTypeName(introspectedColumn));
101 | columnSetting.setJavaType(resolver.calculateJavaType(introspectedColumn).getShortName());
102 | columnSetting.setIgnore(false);
103 | } else {
104 | if (!columnSetting.getJdbcType().equals(resolver.calculateJdbcTypeName(introspectedColumn))) {
105 | columnSetting.setJdbcType(resolver.calculateJdbcTypeName(introspectedColumn));
106 | columnSetting.setJavaType(resolver.calculateJavaType(introspectedColumn).getShortName());
107 | }
108 | }
109 | columnSetting.setComment(dasColumn.getComment());
110 | columnSetting.setChanged(false);
111 | columnSettingList.add(columnSetting);
112 | });
113 | columnSettingModel.init(columnSettingList);
114 | columnSettingModel.addTableModelListener(e -> {
115 | ColumnSetting columnSetting = columnSettingModel.getData().get(e.getFirstRow());
116 | columnSetting.setChanged(false);
117 | tableConfig.getColumnSettings().put(columnSetting.getColumn(),columnSetting);
118 | });
119 | this.columnSettingTable.setModel(columnSettingModel);
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/model/GlobalConfig.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.model;
2 |
3 | public class GlobalConfig {
4 |
5 | private String moduleRootPath;
6 | private String sourcePath;
7 | private String resourcePath;
8 | private String mapperPostfix;
9 | private String examplePostfix;
10 |
11 | private String domainPackage;
12 | private String mapperPackage;
13 | private String examplePackage;
14 | private String xmlPackage;
15 |
16 | private String tablePrefix;
17 |
18 | /**
19 | * 是否分页
20 | */
21 | private boolean offsetLimit;
22 |
23 | /**
24 | * 是否生成实体注释(来自表)
25 | */
26 | private boolean comment;
27 |
28 | /**
29 | * 是否覆盖原xml
30 | */
31 | private boolean override;
32 |
33 | /**
34 | * 是否生成toString/hashCode/equals方法
35 | */
36 | private boolean needToStringHashcodeEquals;
37 |
38 | /**
39 | * 是否使用Schema前缀
40 | */
41 | private boolean useSchemaPrefix;
42 |
43 | /**
44 | * 是否select 增加ForUpdate
45 | */
46 | private boolean needForUpdate;
47 |
48 | /**
49 | * 是否DAO使用 @Repository 注解
50 | */
51 | private boolean annotationDAO;
52 |
53 | /**
54 | * 是否DAO方法抽出到公共父接口
55 | */
56 | private boolean useDAOExtendStyle;
57 |
58 | /**
59 | * 是否JSR310: Date and Time API
60 | */
61 | private boolean jsr310Support;
62 |
63 | /**
64 | * 是否生成JPA注解
65 | */
66 | private boolean annotation;
67 |
68 | /**
69 | * 是否使用实际的列名
70 | */
71 | private boolean useActualColumnNames;
72 |
73 | /**
74 | * 是否启用as别名查询
75 | */
76 | private boolean useTableNameAlias;
77 |
78 | /**
79 | * 是否使用Example
80 | */
81 | private boolean useExample;
82 | /**
83 | * 是否是mysql8数据库
84 | */
85 | private boolean mysql8;
86 |
87 | private boolean lombokAnnotation;
88 |
89 | private boolean lombokBuilderAnnotation;
90 |
91 | private boolean swaggerAnnotation;
92 |
93 | public String getSourcePath() {
94 | return sourcePath;
95 | }
96 |
97 | public void setSourcePath(String sourcePath) {
98 | this.sourcePath = sourcePath;
99 | }
100 |
101 | public String getResourcePath() {
102 | return resourcePath;
103 | }
104 |
105 | public void setResourcePath(String resourcePath) {
106 | this.resourcePath = resourcePath;
107 | }
108 |
109 | public String getMapperPostfix() {
110 | return mapperPostfix;
111 | }
112 |
113 | public void setMapperPostfix(String mapperPostfix) {
114 | this.mapperPostfix = mapperPostfix;
115 | }
116 |
117 | public String getDomainPackage() {
118 | return domainPackage;
119 | }
120 |
121 | public void setDomainPackage(String domainPackage) {
122 | this.domainPackage = domainPackage;
123 | }
124 |
125 | public String getMapperPackage() {
126 | return mapperPackage;
127 | }
128 |
129 | public void setMapperPackage(String mapperPackage) {
130 | this.mapperPackage = mapperPackage;
131 | }
132 |
133 | public String getXmlPackage() {
134 | return xmlPackage;
135 | }
136 |
137 | public void setXmlPackage(String xmlPackage) {
138 | this.xmlPackage = xmlPackage;
139 | }
140 |
141 | public boolean isOffsetLimit() {
142 | return offsetLimit;
143 | }
144 |
145 | public void setOffsetLimit(boolean offsetLimit) {
146 | this.offsetLimit = offsetLimit;
147 | }
148 |
149 | public boolean isComment() {
150 | return comment;
151 | }
152 |
153 | public void setComment(boolean comment) {
154 | this.comment = comment;
155 | }
156 |
157 | public boolean isOverride() {
158 | return override;
159 | }
160 |
161 | public void setOverride(boolean override) {
162 | this.override = override;
163 | }
164 |
165 | public boolean isNeedToStringHashcodeEquals() {
166 | return needToStringHashcodeEquals;
167 | }
168 |
169 | public void setNeedToStringHashcodeEquals(boolean needToStringHashcodeEquals) {
170 | this.needToStringHashcodeEquals = needToStringHashcodeEquals;
171 | }
172 |
173 | public boolean isUseSchemaPrefix() {
174 | return useSchemaPrefix;
175 | }
176 |
177 | public void setUseSchemaPrefix(boolean useSchemaPrefix) {
178 | this.useSchemaPrefix = useSchemaPrefix;
179 | }
180 |
181 | public boolean isNeedForUpdate() {
182 | return needForUpdate;
183 | }
184 |
185 | public void setNeedForUpdate(boolean needForUpdate) {
186 | this.needForUpdate = needForUpdate;
187 | }
188 |
189 | public boolean isAnnotationDAO() {
190 | return annotationDAO;
191 | }
192 |
193 | public void setAnnotationDAO(boolean annotationDAO) {
194 | this.annotationDAO = annotationDAO;
195 | }
196 |
197 | public boolean isUseDAOExtendStyle() {
198 | return useDAOExtendStyle;
199 | }
200 |
201 | public void setUseDAOExtendStyle(boolean useDAOExtendStyle) {
202 | this.useDAOExtendStyle = useDAOExtendStyle;
203 | }
204 |
205 | public boolean isJsr310Support() {
206 | return jsr310Support;
207 | }
208 |
209 | public void setJsr310Support(boolean jsr310Support) {
210 | this.jsr310Support = jsr310Support;
211 | }
212 |
213 | public boolean isAnnotation() {
214 | return annotation;
215 | }
216 |
217 | public void setAnnotation(boolean annotation) {
218 | this.annotation = annotation;
219 | }
220 |
221 | public boolean isUseActualColumnNames() {
222 | return useActualColumnNames;
223 | }
224 |
225 | public void setUseActualColumnNames(boolean useActualColumnNames) {
226 | this.useActualColumnNames = useActualColumnNames;
227 | }
228 |
229 | public boolean isUseTableNameAlias() {
230 | return useTableNameAlias;
231 | }
232 |
233 | public void setUseTableNameAlias(boolean useTableNameAlias) {
234 | this.useTableNameAlias = useTableNameAlias;
235 | }
236 |
237 | public boolean isUseExample() {
238 | return useExample;
239 | }
240 |
241 | public void setUseExample(boolean useExample) {
242 | this.useExample = useExample;
243 | }
244 |
245 | public boolean isMysql8() {
246 | return mysql8;
247 | }
248 |
249 | public void setMysql8(boolean mysql8) {
250 | this.mysql8 = mysql8;
251 | }
252 |
253 | public boolean isLombokAnnotation() {
254 | return lombokAnnotation;
255 | }
256 |
257 | public void setLombokAnnotation(boolean lombokAnnotation) {
258 | this.lombokAnnotation = lombokAnnotation;
259 | }
260 |
261 | public boolean isLombokBuilderAnnotation() {
262 | return lombokBuilderAnnotation;
263 | }
264 |
265 | public void setLombokBuilderAnnotation(boolean lombokBuilderAnnotation) {
266 | this.lombokBuilderAnnotation = lombokBuilderAnnotation;
267 | }
268 |
269 | public String getModuleRootPath() {
270 | return moduleRootPath;
271 | }
272 |
273 | public void setModuleRootPath(String moduleRootPath) {
274 | this.moduleRootPath = moduleRootPath;
275 | }
276 |
277 | public String getExamplePostfix() {
278 | return examplePostfix;
279 | }
280 |
281 | public void setExamplePostfix(String examplePostfix) {
282 | this.examplePostfix = examplePostfix;
283 | }
284 |
285 | public String getExamplePackage() {
286 | return examplePackage;
287 | }
288 |
289 | public void setExamplePackage(String examplePackage) {
290 | this.examplePackage = examplePackage;
291 | }
292 |
293 | public boolean isSwaggerAnnotation() {
294 | return swaggerAnnotation;
295 | }
296 |
297 | public void setSwaggerAnnotation(boolean swaggerAnnotation) {
298 | this.swaggerAnnotation = swaggerAnnotation;
299 | }
300 |
301 | public String getTablePrefix() {
302 | return tablePrefix;
303 | }
304 |
305 | public void setTablePrefix(String tablePrefix) {
306 | this.tablePrefix = tablePrefix;
307 | }
308 |
309 | public static GlobalConfig getDefault() {
310 | GlobalConfig globalConfig = new GlobalConfig();
311 | globalConfig.setSourcePath("src/main/java");
312 | globalConfig.setResourcePath("src/main/resources");
313 | globalConfig.setMapperPostfix("Mapper");
314 | globalConfig.setXmlPackage("mapper");
315 | globalConfig.setExamplePostfix("Example");
316 | globalConfig.setUseExample(true);
317 | globalConfig.setComment(true);
318 | return globalConfig;
319 | }
320 | }
321 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/util/XmlFileMerger.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.util;
2 |
3 | import static org.mybatis.generator.internal.util.messages.Messages.getString;
4 |
5 | import java.io.File;
6 | import java.io.FileInputStream;
7 | import java.io.IOException;
8 | import java.io.InputStreamReader;
9 | import java.io.StringReader;
10 | import java.util.ArrayList;
11 | import java.util.List;
12 |
13 | import javax.xml.parsers.DocumentBuilder;
14 | import javax.xml.parsers.DocumentBuilderFactory;
15 | import javax.xml.parsers.ParserConfigurationException;
16 |
17 | import com.sun.org.apache.xerces.internal.dom.DeferredTextImpl;
18 | import org.mybatis.generator.api.GeneratedXmlFile;
19 | import org.mybatis.generator.config.MergeConstants;
20 | import org.mybatis.generator.exception.ShellException;
21 | import org.mybatis.generator.internal.DomWriter;
22 | import org.w3c.dom.Comment;
23 | import org.w3c.dom.Document;
24 | import org.w3c.dom.DocumentType;
25 | import org.w3c.dom.Element;
26 | import org.w3c.dom.NamedNodeMap;
27 | import org.w3c.dom.Node;
28 | import org.w3c.dom.NodeList;
29 | import org.w3c.dom.Text;
30 | import org.xml.sax.EntityResolver;
31 | import org.xml.sax.InputSource;
32 | import org.xml.sax.SAXException;
33 |
34 | /**
35 | * This class handles the task of merging changes into an existing XML file.
36 | *
37 | * @author Jeff Butler
38 | */
39 | public class XmlFileMerger {
40 | private static class NullEntityResolver implements EntityResolver {
41 | /**
42 | * returns an empty reader. This is done so that the parser doesn't
43 | * attempt to read a DTD. We don't need that support for the merge and
44 | * it can cause problems on systems that aren't Internet connected.
45 | */
46 | @Override
47 | public InputSource resolveEntity(String publicId, String systemId)
48 | throws SAXException, IOException {
49 |
50 | StringReader sr = new StringReader(""); //$NON-NLS-1$
51 |
52 | return new InputSource(sr);
53 | }
54 | }
55 |
56 | /**
57 | * Utility class - no instances allowed
58 | */
59 | private XmlFileMerger() {
60 | super();
61 | }
62 |
63 | public static String getMergedSource(GeneratedXmlFile generatedXmlFile,
64 | File existingFile) throws ShellException {
65 |
66 | try {
67 | return getMergedSource(new InputSource(new StringReader(generatedXmlFile.getFormattedContent())),
68 | new InputSource(new InputStreamReader(new FileInputStream(existingFile), "UTF-8")), //$NON-NLS-1$
69 | existingFile.getName());
70 | } catch (IOException e) {
71 | throw new ShellException(getString("Warning.13", //$NON-NLS-1$
72 | existingFile.getName()), e);
73 | } catch (SAXException e) {
74 | throw new ShellException(getString("Warning.13", //$NON-NLS-1$
75 | existingFile.getName()), e);
76 | } catch (ParserConfigurationException e) {
77 | throw new ShellException(getString("Warning.13", //$NON-NLS-1$
78 | existingFile.getName()), e);
79 | }
80 | }
81 |
82 | public static String getMergedSource(InputSource newFile,
83 | InputSource existingFile, String existingFileName) throws IOException, SAXException,
84 | ParserConfigurationException, ShellException {
85 |
86 | DocumentBuilderFactory factory = DocumentBuilderFactory
87 | .newInstance();
88 | factory.setExpandEntityReferences(false);
89 | DocumentBuilder builder = factory.newDocumentBuilder();
90 | builder.setEntityResolver(new NullEntityResolver());
91 |
92 | Document existingDocument = builder.parse(existingFile);
93 | Document newDocument = builder.parse(newFile);
94 |
95 | DocumentType newDocType = newDocument.getDoctype();
96 | DocumentType existingDocType = existingDocument.getDoctype();
97 |
98 | if (!newDocType.getName().equals(existingDocType.getName())) {
99 | throw new ShellException(getString("Warning.12", //$NON-NLS-1$
100 | existingFileName));
101 | }
102 |
103 | Element existingRootElement = existingDocument.getDocumentElement();
104 | Element newRootElement = newDocument.getDocumentElement();
105 |
106 | // reconcile the root element attributes -
107 | // take all attributes from the new element and add to the existing
108 | // element
109 |
110 | // remove all attributes from the existing root element
111 | NamedNodeMap attributes = existingRootElement.getAttributes();
112 | int attributeCount = attributes.getLength();
113 | for (int i = attributeCount - 1; i >= 0; i--) {
114 | Node node = attributes.item(i);
115 | existingRootElement.removeAttribute(node.getNodeName());
116 | }
117 |
118 | // add attributes from the new root node to the old root node
119 | attributes = newRootElement.getAttributes();
120 | attributeCount = attributes.getLength();
121 | for (int i = 0; i < attributeCount; i++) {
122 | Node node = attributes.item(i);
123 | existingRootElement.setAttribute(node.getNodeName(), node
124 | .getNodeValue());
125 | }
126 |
127 | NodeList newMethods = newRootElement.getChildNodes();
128 | List methods = new ArrayList();
129 | for (int i = 0; i < newMethods.getLength(); i++) {
130 | Node node = newMethods.item(i);
131 | try {
132 | if (node instanceof DeferredTextImpl) {
133 | continue;
134 | }
135 | Element ele = (Element) node;
136 | methods.add(ele.getAttribute("id"));
137 | } catch (Exception e) {
138 | //#text节点转换会异常
139 | continue;
140 | }
141 | if (i == newMethods.getLength() - 1) {
142 | if (isWhiteSpace(node)) {
143 | break;
144 | }
145 | }
146 | }
147 |
148 | // remove the old generated elements and any
149 | // white space before the old nodes
150 | List nodesToDelete = new ArrayList();
151 | NodeList children = existingRootElement.getChildNodes();
152 | int length = children.getLength();
153 | for (int i = 0; i < length; i++) {
154 | Node node = children.item(i);
155 | if (isGeneratedNode(node, methods)) {
156 | nodesToDelete.add(node);
157 | } else if (isWhiteSpace(node)
158 | && isGeneratedNode(children.item(i + 1), methods)) {
159 | nodesToDelete.add(node);
160 | }
161 | }
162 |
163 | for (Node node : nodesToDelete) {
164 | existingRootElement.removeChild(node);
165 | }
166 |
167 | // add the new generated elements
168 | children = newRootElement.getChildNodes();
169 | length = children.getLength();
170 | Node firstChild = existingRootElement.getFirstChild();
171 | for (int i = 0; i < length; i++) {
172 | Node node = children.item(i);
173 | // don't add the last node if it is only white space
174 | if (i == length - 1 && isWhiteSpace(node)) {
175 | break;
176 | }
177 |
178 | Node newNode = existingDocument.importNode(node, true);
179 | if (firstChild == null) {
180 | existingRootElement.appendChild(newNode);
181 | } else {
182 | existingRootElement.insertBefore(newNode, firstChild);
183 | }
184 | }
185 |
186 | // pretty print the result
187 | return prettyPrint(existingDocument);
188 | }
189 |
190 | private static String prettyPrint(Document document) throws ShellException {
191 | DomWriter dw = new DomWriter();
192 | String s = dw.toString(document);
193 | return s;
194 | }
195 |
196 | private static boolean isGeneratedNode(Node node, List methods) {
197 | boolean rc = false;
198 |
199 | if (node != null && node.getNodeType() == Node.ELEMENT_NODE) {
200 | Element element = (Element) node;
201 | String id = element.getAttribute("id"); //$NON-NLS-1$
202 | if (methods.contains(id)) {
203 | return true;
204 | }
205 | if (id != null) {
206 | for (String prefix : MergeConstants.OLD_XML_ELEMENT_PREFIXES) {
207 | if (id.startsWith(prefix)) {
208 | rc = true;
209 | break;
210 | }
211 | }
212 | }
213 |
214 | if (rc == false) {
215 | // check for new node format - if the first non-whitespace node
216 | // is an XML comment, and the comment includes
217 | // one of the old element tags,
218 | // then it is a generated node
219 | NodeList children = node.getChildNodes();
220 | int length = children.getLength();
221 | for (int i = 0; i < length; i++) {
222 | Node childNode = children.item(i);
223 | if (isWhiteSpace(childNode)) {
224 | continue;
225 | } else if (childNode.getNodeType() == Node.COMMENT_NODE) {
226 | Comment comment = (Comment) childNode;
227 | String commentData = comment.getData();
228 | for (String tag : MergeConstants.OLD_ELEMENT_TAGS) {
229 | if (commentData.contains(tag)) {
230 | rc = true;
231 | break;
232 | }
233 | }
234 | } else {
235 | break;
236 | }
237 | }
238 | }
239 | }
240 |
241 | return rc;
242 | }
243 |
244 | private static boolean isWhiteSpace(Node node) {
245 | boolean rc = false;
246 |
247 | if (node != null && node.getNodeType() == Node.TEXT_NODE) {
248 | Text tn = (Text) node;
249 | if (tn.getData().trim().length() == 0) {
250 | rc = true;
251 | }
252 | }
253 |
254 | return rc;
255 | }
256 | }
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/model/TableConfig.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.model;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * 界面配置
8 | */
9 | public class TableConfig {
10 |
11 | /**
12 | * 配置名称
13 | */
14 | private String name;
15 |
16 | /**
17 | * 表名
18 | */
19 | private String tableName;
20 |
21 | /**
22 | * 主键
23 | */
24 | private String primaryKey;
25 |
26 | /**
27 | * 实体名
28 | */
29 | private String domainName;
30 |
31 | /**
32 | * dao名称
33 | */
34 | private String mapperName;
35 |
36 | /**
37 | * dao名称
38 | */
39 | private String exampleName;
40 |
41 | /**
42 | * dao后缀
43 | */
44 | private String mapperPostfix;
45 |
46 | /**
47 | * dao后缀
48 | */
49 | private String examplePostfix;
50 |
51 | /**
52 | * 工程目录
53 | */
54 | private String moduleRootPath;
55 |
56 | private String sourcePath;
57 | private String resourcePath;
58 |
59 | private String basePackage;
60 | private String domainPackage;
61 |
62 | private String mapperPackage;
63 |
64 | private String examplePackage;
65 |
66 | private String xmlPackage;
67 |
68 | private Map columnSettings = new HashMap<>();
69 | /**
70 | * 是否分页
71 | */
72 | private boolean offsetLimit;
73 |
74 | /**
75 | * 是否生成实体注释(来自表)
76 | */
77 | private boolean comment;
78 |
79 | /**
80 | * 是否覆盖原xml
81 | */
82 | private boolean override;
83 |
84 | /**
85 | * 是否生成toString/hashCode/equals方法
86 | */
87 | private boolean needToStringHashcodeEquals;
88 |
89 | /**
90 | * 是否使用Schema前缀
91 | */
92 | private boolean useSchemaPrefix;
93 |
94 | /**
95 | * 是否select 增加ForUpdate
96 | */
97 | private boolean needForUpdate;
98 |
99 | /**
100 | * 是否DAO使用 @Repository 注解
101 | */
102 | private boolean annotationDAO;
103 |
104 | /**
105 | * 是否DAO方法抽出到公共父接口
106 | */
107 | private boolean useDAOExtendStyle;
108 |
109 | /**
110 | * 是否JSR310: Date and Time API
111 | */
112 | private boolean jsr310Support;
113 |
114 | /**
115 | * 是否生成JPA注解
116 | */
117 | private boolean annotation;
118 |
119 | /**
120 | * 是否使用实际的列名
121 | */
122 | private boolean useActualColumnNames;
123 |
124 | /**
125 | * 是否启用as别名查询
126 | */
127 | private boolean useTableNameAlias;
128 |
129 | /**
130 | * 是否使用Example
131 | */
132 | private boolean useExample;
133 | /**
134 | * 是否是mysql8数据库
135 | */
136 | private boolean mysql8;
137 |
138 | private boolean lombokAnnotation;
139 |
140 | private boolean lombokBuilderAnnotation;
141 |
142 | private boolean swaggerAnnotation;
143 |
144 | private String encoding;
145 | private String connectorJarPath;
146 |
147 | public boolean isJsr310Support() {
148 | return jsr310Support;
149 | }
150 |
151 | public void setJsr310Support(boolean jsr310Support) {
152 | this.jsr310Support = jsr310Support;
153 | }
154 |
155 | public boolean isUseSchemaPrefix() {
156 | return useSchemaPrefix;
157 | }
158 |
159 | public void setUseSchemaPrefix(boolean useSchemaPrefix) {
160 | this.useSchemaPrefix = useSchemaPrefix;
161 | }
162 |
163 | public boolean isUseExample() {
164 | return useExample;
165 | }
166 |
167 | public void setUseExample(boolean useExample) {
168 | this.useExample = useExample;
169 | }
170 |
171 | public String getName() {
172 | return name;
173 | }
174 |
175 | public void setName(String name) {
176 | this.name = name;
177 | }
178 |
179 | public String getTableName() {
180 | return tableName;
181 | }
182 |
183 | public void setTableName(String tableName) {
184 | this.tableName = tableName;
185 | }
186 |
187 | public String getDomainName() {
188 | return domainName;
189 | }
190 |
191 | public void setDomainName(String domainName) {
192 | this.domainName = domainName;
193 | }
194 |
195 | public String getConnectorJarPath() {
196 | return connectorJarPath;
197 | }
198 |
199 | public void setConnectorJarPath(String connectorJarPath) {
200 | this.connectorJarPath = connectorJarPath;
201 | }
202 |
203 | public String getModuleRootPath() {
204 | return moduleRootPath;
205 | }
206 |
207 | public void setModuleRootPath(String moduleRootPath) {
208 | this.moduleRootPath = moduleRootPath;
209 | }
210 |
211 | public String getDomainPackage() {
212 | return domainPackage;
213 | }
214 |
215 | public void setDomainPackage(String domainPackage) {
216 | this.domainPackage = domainPackage;
217 | }
218 |
219 |
220 | public String getMapperPackage() {
221 | return mapperPackage;
222 | }
223 |
224 | public void setMapperPackage(String mapperPackage) {
225 | this.mapperPackage = mapperPackage;
226 | }
227 |
228 |
229 | public String getXmlPackage() {
230 | return xmlPackage;
231 | }
232 |
233 | public void setXmlPackage(String xmlPackage) {
234 | this.xmlPackage = xmlPackage;
235 | }
236 |
237 | public boolean isOffsetLimit() {
238 | return offsetLimit;
239 | }
240 |
241 | public void setOffsetLimit(boolean offsetLimit) {
242 | this.offsetLimit = offsetLimit;
243 | }
244 |
245 | public boolean isComment() {
246 | return comment;
247 | }
248 |
249 | public void setComment(boolean comment) {
250 | this.comment = comment;
251 | }
252 |
253 | public boolean isNeedToStringHashcodeEquals() {
254 | return needToStringHashcodeEquals;
255 | }
256 |
257 | public void setNeedToStringHashcodeEquals(boolean needToStringHashcodeEquals) {
258 | this.needToStringHashcodeEquals = needToStringHashcodeEquals;
259 | }
260 |
261 | public boolean isNeedForUpdate() {
262 | return needForUpdate;
263 | }
264 |
265 | public void setNeedForUpdate(boolean needForUpdate) {
266 | this.needForUpdate = needForUpdate;
267 | }
268 |
269 | public boolean isAnnotationDAO() {
270 | return annotationDAO;
271 | }
272 |
273 | public void setAnnotationDAO(boolean annotationDAO) {
274 | this.annotationDAO = annotationDAO;
275 | }
276 |
277 | public boolean isAnnotation() {
278 | return annotation;
279 | }
280 |
281 | public void setAnnotation(boolean annotation) {
282 | this.annotation = annotation;
283 | }
284 |
285 | public boolean isUseActualColumnNames() {
286 | return useActualColumnNames;
287 | }
288 |
289 | public void setUseActualColumnNames(boolean useActualColumnNames) {
290 | this.useActualColumnNames = useActualColumnNames;
291 | }
292 |
293 | public String getMapperName() {
294 | return mapperName;
295 | }
296 |
297 | public void setMapperName(String mapperName) {
298 | this.mapperName = mapperName;
299 | }
300 |
301 | public String getPrimaryKey() {
302 | return primaryKey;
303 | }
304 |
305 | public void setPrimaryKey(String primaryKey) {
306 | this.primaryKey = primaryKey;
307 | }
308 |
309 | public String getEncoding() {
310 | return encoding;
311 | }
312 |
313 | public void setEncoding(String encoding) {
314 | this.encoding = encoding;
315 | }
316 |
317 | public boolean getUseTableNameAlias() {
318 | return useTableNameAlias;
319 | }
320 |
321 | public void setUseTableNameAlias(boolean useTableNameAlias) {
322 | this.useTableNameAlias = useTableNameAlias;
323 | }
324 |
325 | public boolean isUseTableNameAlias() {
326 | return useTableNameAlias;
327 | }
328 |
329 | public boolean isOverride() {
330 | return override;
331 | }
332 |
333 | public void setOverride(boolean override) {
334 | this.override = override;
335 | }
336 |
337 | public void setUseDAOExtendStyle(boolean useDAOExtendStyle) {
338 | this.useDAOExtendStyle = useDAOExtendStyle;
339 | }
340 |
341 | public boolean isUseDAOExtendStyle() {
342 | return useDAOExtendStyle;
343 | }
344 |
345 | public String getSourcePath() {
346 | return sourcePath;
347 | }
348 |
349 | public void setSourcePath(String sourcePath) {
350 | this.sourcePath = sourcePath;
351 | }
352 |
353 | public String getResourcePath() {
354 | return resourcePath;
355 | }
356 |
357 | public void setResourcePath(String resourcePath) {
358 | this.resourcePath = resourcePath;
359 | }
360 |
361 | public String getMapperPostfix() {
362 | return mapperPostfix;
363 | }
364 |
365 | public void setMapperPostfix(String mapperPostfix) {
366 | this.mapperPostfix = mapperPostfix;
367 | }
368 |
369 | public boolean isMysql8() {
370 | return mysql8;
371 | }
372 |
373 | public void setMysql8(boolean mysql8) {
374 | this.mysql8 = mysql8;
375 | }
376 |
377 | public boolean isLombokAnnotation() {
378 | return lombokAnnotation;
379 | }
380 |
381 | public void setLombokAnnotation(boolean lombokAnnotation) {
382 | this.lombokAnnotation = lombokAnnotation;
383 | }
384 |
385 | public boolean isLombokBuilderAnnotation() {
386 | return lombokBuilderAnnotation;
387 | }
388 |
389 | public void setLombokBuilderAnnotation(boolean lombokBuilderAnnotation) {
390 | this.lombokBuilderAnnotation = lombokBuilderAnnotation;
391 | }
392 |
393 | public boolean isSwaggerAnnotation() {
394 | return swaggerAnnotation;
395 | }
396 |
397 | public void setSwaggerAnnotation(boolean swaggerAnnotation) {
398 | this.swaggerAnnotation = swaggerAnnotation;
399 | }
400 |
401 | public String getExamplePackage() {
402 | return examplePackage;
403 | }
404 |
405 | public void setExamplePackage(String examplePackage) {
406 | this.examplePackage = examplePackage;
407 | }
408 |
409 | public String getExamplePostfix() {
410 | return examplePostfix;
411 | }
412 |
413 | public void setExamplePostfix(String examplePostfix) {
414 | this.examplePostfix = examplePostfix;
415 | }
416 |
417 | public String getExampleName() {
418 | return exampleName;
419 | }
420 |
421 | public void setExampleName(String exampleName) {
422 | this.exampleName = exampleName;
423 | }
424 |
425 | public String getBasePackage() {
426 | return basePackage;
427 | }
428 |
429 | public void setBasePackage(String basePackage) {
430 | this.basePackage = basePackage;
431 | }
432 |
433 | public Map getColumnSettings() {
434 | return columnSettings;
435 | }
436 |
437 | public void setColumnSettings(Map columnSettings) {
438 | this.columnSettings = columnSettings;
439 | }
440 | }
441 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/plugin/LombokPlugin.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.plugin;
2 |
3 | import org.mybatis.generator.api.IntrospectedColumn;
4 | import org.mybatis.generator.api.IntrospectedTable;
5 | import org.mybatis.generator.api.PluginAdapter;
6 | import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
7 | import org.mybatis.generator.api.dom.java.Interface;
8 | import org.mybatis.generator.api.dom.java.Method;
9 | import org.mybatis.generator.api.dom.java.TopLevelClass;
10 |
11 | import java.util.*;
12 |
13 |
14 | /**
15 | * A MyBatis Generator plugin to use Lombok's annotations.
16 | * For example, use @Data annotation instead of getter ands setter.
17 | *
18 | * @author Paolo Predonzani (http://softwareloop.com/)
19 | */
20 | public class LombokPlugin extends PluginAdapter {
21 |
22 | private final Collection annotations;
23 |
24 | /**
25 | * LombokPlugin constructor
26 | */
27 | public LombokPlugin() {
28 | annotations = new LinkedHashSet(Annotations.values().length);
29 | }
30 |
31 | /**
32 | * @param warnings list of warnings
33 | * @return always true
34 | */
35 | @Override
36 | public boolean validate(List warnings) {
37 | return true;
38 | }
39 |
40 | /**
41 | * Intercepts base record class generation
42 | *
43 | * @param topLevelClass the generated base record class
44 | * @param introspectedTable The class containing information about the table as
45 | * introspected from the database
46 | * @return always true
47 | */
48 | @Override
49 | public boolean modelBaseRecordClassGenerated(
50 | TopLevelClass topLevelClass,
51 | IntrospectedTable introspectedTable
52 | ) {
53 | addAnnotations(topLevelClass);
54 | return true;
55 | }
56 |
57 | /**
58 | * Intercepts primary key class generation
59 | *
60 | * @param topLevelClass the generated primary key class
61 | * @param introspectedTable The class containing information about the table as
62 | * introspected from the database
63 | * @return always true
64 | */
65 | @Override
66 | public boolean modelPrimaryKeyClassGenerated(
67 | TopLevelClass topLevelClass,
68 | IntrospectedTable introspectedTable
69 | ) {
70 | addAnnotations(topLevelClass);
71 | return true;
72 | }
73 |
74 | /**
75 | * Intercepts "record with blob" class generation
76 | *
77 | * @param topLevelClass the generated record with BLOBs class
78 | * @param introspectedTable The class containing information about the table as
79 | * introspected from the database
80 | * @return always true
81 | */
82 | @Override
83 | public boolean modelRecordWithBLOBsClassGenerated(
84 | TopLevelClass topLevelClass,
85 | IntrospectedTable introspectedTable
86 | ) {
87 | addAnnotations(topLevelClass);
88 | return true;
89 | }
90 |
91 | /**
92 | * Prevents all getters from being generated.
93 | * See SimpleModelGenerator
94 | *
95 | * @param method the getter, or accessor, method generated for the specified
96 | * column
97 | * @param topLevelClass the partially implemented model class
98 | * @param introspectedColumn The class containing information about the column related
99 | * to this field as introspected from the database
100 | * @param introspectedTable The class containing information about the table as
101 | * introspected from the database
102 | * @param modelClassType the type of class that the field is generated for
103 | */
104 | @Override
105 | public boolean modelGetterMethodGenerated(
106 | Method method,
107 | TopLevelClass topLevelClass,
108 | IntrospectedColumn introspectedColumn,
109 | IntrospectedTable introspectedTable,
110 | ModelClassType modelClassType
111 | ) {
112 | return false;
113 | }
114 |
115 | /**
116 | * Prevents all setters from being generated
117 | * See SimpleModelGenerator
118 | *
119 | * @param method the setter, or mutator, method generated for the specified
120 | * column
121 | * @param topLevelClass the partially implemented model class
122 | * @param introspectedColumn The class containing information about the column related
123 | * to this field as introspected from the database
124 | * @param introspectedTable The class containing information about the table as
125 | * introspected from the database
126 | * @param modelClassType the type of class that the field is generated for
127 | * @return always false
128 | */
129 | @Override
130 | public boolean modelSetterMethodGenerated(
131 | Method method,
132 | TopLevelClass topLevelClass,
133 | IntrospectedColumn introspectedColumn,
134 | IntrospectedTable introspectedTable,
135 | ModelClassType modelClassType
136 | ) {
137 | return false;
138 | }
139 |
140 | /**
141 | * Adds the lombok annotations' imports and annotations to the class
142 | *
143 | * @param topLevelClass the partially implemented model class
144 | */
145 | private void addAnnotations(TopLevelClass topLevelClass) {
146 | for (Annotations annotation : annotations) {
147 | topLevelClass.addImportedType(annotation.javaType);
148 | topLevelClass.addAnnotation(annotation.asAnnotation());
149 | }
150 | }
151 |
152 | @Override
153 | public void setProperties(Properties properties) {
154 | super.setProperties(properties);
155 |
156 | //@Data is default annotation
157 | annotations.add(Annotations.DATA);
158 |
159 | for (String annotationName : properties.stringPropertyNames()) {
160 | if (annotationName.contains(".")) {
161 | // Not an annotation name
162 | continue;
163 | }
164 | String value = properties.getProperty(annotationName);
165 | if (!Boolean.parseBoolean(value)) {
166 | // The annotation is disabled, skip it
167 | continue;
168 | }
169 | Annotations annotation = Annotations.getValueOf(annotationName);
170 | if (annotation == null) {
171 | continue;
172 | }
173 | String optionsPrefix = annotationName + ".";
174 | for (String propertyName : properties.stringPropertyNames()) {
175 | if (!propertyName.startsWith(optionsPrefix)) {
176 | // A property not related to this annotation
177 | continue;
178 | }
179 | String propertyValue = properties.getProperty(propertyName);
180 | annotation.appendOptions(propertyName, propertyValue);
181 | }
182 | annotations.add(annotation);
183 | annotations.addAll(Annotations.getDependencies(annotation));
184 | }
185 | }
186 |
187 | @Override
188 | public boolean clientGenerated(
189 | Interface interfaze,
190 | TopLevelClass topLevelClass,
191 | IntrospectedTable introspectedTable
192 | ) {
193 | interfaze.addImportedType(new FullyQualifiedJavaType(
194 | "org.apache.ibatis.annotations.Mapper"));
195 | interfaze.addAnnotation("@Mapper");
196 | return true;
197 | }
198 |
199 | private enum Annotations {
200 | /**
201 | *
202 | */
203 | DATA("data", "@Data", "lombok.Data"),
204 | BUILDER("builder", "@Builder", "lombok.Builder"),
205 | ALL_ARGS_CONSTRUCTOR("allArgsConstructor", "@AllArgsConstructor", "lombok.AllArgsConstructor"),
206 | NO_ARGS_CONSTRUCTOR("noArgsConstructor", "@NoArgsConstructor", "lombok.NoArgsConstructor"),
207 | ACCESSORS("accessors", "@Accessors", "lombok.experimental.Accessors"),
208 | TO_STRING("toString", "@ToString", "lombok.ToString");
209 |
210 |
211 | private final String paramName;
212 | private final String name;
213 | private final FullyQualifiedJavaType javaType;
214 | private final List options;
215 |
216 |
217 | Annotations(String paramName, String name, String className) {
218 | this.paramName = paramName;
219 | this.name = name;
220 | this.javaType = new FullyQualifiedJavaType(className);
221 | this.options = new ArrayList();
222 | }
223 |
224 | private static Annotations getValueOf(String paramName) {
225 | for (Annotations annotation : Annotations.values())
226 | if (String.CASE_INSENSITIVE_ORDER.compare(paramName, annotation.paramName) == 0)
227 | return annotation;
228 |
229 | return null;
230 | }
231 |
232 | private static Collection getDependencies(Annotations annotation) {
233 | if (annotation == ALL_ARGS_CONSTRUCTOR)
234 | return Collections.singleton(NO_ARGS_CONSTRUCTOR);
235 | else
236 | return Collections.emptyList();
237 | }
238 |
239 | // A trivial quoting.
240 | // Because Lombok annotation options type is almost String or boolean.
241 | private static String quote(String value) {
242 | if (Boolean.TRUE.toString().equals(value) || Boolean.FALSE.toString().equals(value))
243 | // case of boolean, not passed as an array.
244 | return value;
245 | return value.replaceAll("[\\w]+", "\"$0\"");
246 | }
247 |
248 | private void appendOptions(String key, String value) {
249 | String keyPart = key.substring(key.indexOf(".") + 1);
250 | String valuePart = value.contains(",") ? String.format("{%s}", value) : value;
251 | this.options.add(String.format("%s=%s", keyPart, quote(valuePart)));
252 | }
253 |
254 | private String asAnnotation() {
255 | if (options.isEmpty()) {
256 | return name;
257 | }
258 | StringBuilder sb = new StringBuilder();
259 | sb.append(name);
260 | sb.append("(");
261 | boolean first = true;
262 | for (String option : options) {
263 | if (first) {
264 | first = false;
265 | } else {
266 | sb.append(", ");
267 | }
268 | sb.append(option);
269 | }
270 | sb.append(")");
271 | return sb.toString();
272 | }
273 | }
274 | }
275 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/generate/MyBatisCodeGenerator.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.generate;
2 |
3 | import com.github.leecho.idea.plugin.mybatis.generator.util.XmlFileMerger;
4 | import org.mybatis.generator.api.GeneratedJavaFile;
5 | import org.mybatis.generator.api.GeneratedXmlFile;
6 | import org.mybatis.generator.api.ProgressCallback;
7 | import org.mybatis.generator.api.ShellCallback;
8 | import org.mybatis.generator.codegen.RootClassInfo;
9 | import org.mybatis.generator.config.Configuration;
10 | import org.mybatis.generator.config.Context;
11 | import org.mybatis.generator.config.MergeConstants;
12 | import org.mybatis.generator.exception.InvalidConfigurationException;
13 | import org.mybatis.generator.exception.ShellException;
14 | import org.mybatis.generator.internal.DefaultShellCallback;
15 | import org.mybatis.generator.internal.NullProgressCallback;
16 | import org.mybatis.generator.internal.ObjectFactory;
17 |
18 | import java.io.*;
19 | import java.sql.SQLException;
20 | import java.util.ArrayList;
21 | import java.util.HashSet;
22 | import java.util.List;
23 | import java.util.Set;
24 |
25 | import static org.mybatis.generator.internal.util.ClassloaderUtility.getCustomClassloader;
26 | import static org.mybatis.generator.internal.util.messages.Messages.getString;
27 |
28 | /**
29 | * This class is the main interface to MyBatis generator. A typical execution of the tool involves these steps:
30 | *
31 | *
32 | * - Create a Configuration object. The Configuration can be the result of a parsing the XML configuration file, or it
33 | * can be created solely in Java.
34 | * - Create a MyBatisCodeGenerator object
35 | * - Call one of the generate() methods
36 | *
37 | *
38 | * @author Jeff Butler
39 | * @see org.mybatis.generator.config.xml.ConfigurationParser
40 | */
41 | public class MyBatisCodeGenerator {
42 |
43 | /**
44 | * The configuration.
45 | */
46 | private Configuration configuration;
47 |
48 | /**
49 | * The shell callback.
50 | */
51 | private ShellCallback shellCallback;
52 |
53 | /**
54 | * The generated java files.
55 | */
56 | private List generatedJavaFiles;
57 |
58 | /**
59 | * The generated xml files.
60 | */
61 | private List generatedXmlFiles;
62 |
63 | /**
64 | * The warnings.
65 | */
66 | private List warnings;
67 |
68 | /**
69 | * The projects.
70 | */
71 | private Set projects;
72 |
73 | /**
74 | * Constructs a MyBatisCodeGenerator object.
75 | *
76 | * @param configuration The configuration for this invocation
77 | * @param shellCallback an instance of a ShellCallback interface. You may specify
78 | * null in which case the DefaultShellCallback will
79 | * be used.
80 | * @param warnings Any warnings generated during execution will be added to this
81 | * list. Warnings do not affect the running of the tool, but they
82 | * may affect the results. A typical warning is an unsupported
83 | * data type. In that case, the column will be ignored and
84 | * generation will continue. You may specify null if
85 | * you do not want warnings returned.
86 | * @throws InvalidConfigurationException if the specified configuration is invalid
87 | */
88 | public MyBatisCodeGenerator(Configuration configuration, ShellCallback shellCallback,
89 | List warnings) throws InvalidConfigurationException {
90 | super();
91 | if (configuration == null) {
92 | throw new IllegalArgumentException(getString("RuntimeError.2")); //$NON-NLS-1$
93 | } else {
94 | this.configuration = configuration;
95 | }
96 |
97 | if (shellCallback == null) {
98 | this.shellCallback = new DefaultShellCallback(false);
99 | } else {
100 | this.shellCallback = shellCallback;
101 | }
102 |
103 | if (warnings == null) {
104 | this.warnings = new ArrayList();
105 | } else {
106 | this.warnings = warnings;
107 | }
108 | generatedJavaFiles = new ArrayList();
109 | generatedXmlFiles = new ArrayList();
110 | projects = new HashSet();
111 |
112 | this.configuration.validate();
113 | }
114 |
115 | /**
116 | * This is the main method for generating code. This method is long running, but progress can be provided and the
117 | * method can be canceled through the ProgressCallback interface. This version of the method runs all configured
118 | * contexts.
119 | *
120 | * @param callback an instance of the ProgressCallback interface, or null if you do not require progress
121 | * information
122 | * @throws SQLException the SQL exception
123 | * @throws IOException Signals that an I/O exception has occurred.
124 | * @throws InterruptedException if the method is canceled through the ProgressCallback
125 | */
126 | public void generate(ProgressCallback callback) throws SQLException,
127 | IOException, InterruptedException {
128 | generate(callback, null, null, true);
129 | }
130 |
131 | /**
132 | * This is the main method for generating code. This method is long running, but progress can be provided and the
133 | * method can be canceled through the ProgressCallback interface.
134 | *
135 | * @param callback an instance of the ProgressCallback interface, or null if you do not require progress
136 | * information
137 | * @param contextIds a set of Strings containing context ids to run. Only the contexts with an id specified in this list
138 | * will be run. If the list is null or empty, than all contexts are run.
139 | * @throws SQLException the SQL exception
140 | * @throws IOException Signals that an I/O exception has occurred.
141 | * @throws InterruptedException if the method is canceled through the ProgressCallback
142 | */
143 | public void generate(ProgressCallback callback, Set contextIds)
144 | throws SQLException, IOException, InterruptedException {
145 | generate(callback, contextIds, null, true);
146 | }
147 |
148 | /**
149 | * This is the main method for generating code. This method is long running, but progress can be provided and the
150 | * method can be cancelled through the ProgressCallback interface.
151 | *
152 | * @param callback an instance of the ProgressCallback interface, or null if you do not require progress
153 | * information
154 | * @param contextIds a set of Strings containing context ids to run. Only the contexts with an id specified in this list
155 | * will be run. If the list is null or empty, than all contexts are run.
156 | * @param fullyQualifiedTableNames a set of table names to generate. The elements of the set must be Strings that exactly match what's
157 | * specified in the configuration. For example, if table name = "foo" and schema = "bar", then the fully
158 | * qualified table name is "foo.bar". If the Set is null or empty, then all tables in the configuration
159 | * will be used for code generation.
160 | * @throws SQLException the SQL exception
161 | * @throws IOException Signals that an I/O exception has occurred.
162 | * @throws InterruptedException if the method is canceled through the ProgressCallback
163 | */
164 | public void generate(ProgressCallback callback, Set contextIds,
165 | Set fullyQualifiedTableNames) throws SQLException,
166 | IOException, InterruptedException {
167 | generate(callback, contextIds, fullyQualifiedTableNames, true);
168 | }
169 |
170 | /**
171 | * This is the main method for generating code. This method is long running, but progress can be provided and the
172 | * method can be cancelled through the ProgressCallback interface.
173 | *
174 | * @param callback an instance of the ProgressCallback interface, or null if you do not require progress
175 | * information
176 | * @param contextIds a set of Strings containing context ids to run. Only the contexts with an id specified in this list
177 | * will be run. If the list is null or empty, than all contexts are run.
178 | * @param fullyQualifiedTableNames a set of table names to generate. The elements of the set must be Strings that exactly match what's
179 | * specified in the configuration. For example, if table name = "foo" and schema = "bar", then the fully
180 | * qualified table name is "foo.bar". If the Set is null or empty, then all tables in the configuration
181 | * will be used for code generation.
182 | * @param writeFiles if true, then the generated files will be written to disk. If false,
183 | * then the generator runs but nothing is written
184 | * @throws SQLException the SQL exception
185 | * @throws IOException Signals that an I/O exception has occurred.
186 | * @throws InterruptedException if the method is canceled through the ProgressCallback
187 | */
188 | public void generate(ProgressCallback callback, Set contextIds,
189 | Set fullyQualifiedTableNames, boolean writeFiles) throws SQLException,
190 | IOException, InterruptedException {
191 |
192 | if (callback == null) {
193 | callback = new NullProgressCallback();
194 | }
195 |
196 | generatedJavaFiles.clear();
197 | generatedXmlFiles.clear();
198 | ObjectFactory.reset();
199 | RootClassInfo.reset();
200 |
201 | // calculate the contexts to run
202 | List contextsToRun;
203 | if (contextIds == null || contextIds.size() == 0) {
204 | contextsToRun = configuration.getContexts();
205 | } else {
206 | contextsToRun = new ArrayList();
207 | for (Context context : configuration.getContexts()) {
208 | if (contextIds.contains(context.getId())) {
209 | contextsToRun.add(context);
210 | }
211 | }
212 | }
213 |
214 | // setup custom classloader if required
215 | if (configuration.getClassPathEntries().size() > 0) {
216 | ClassLoader classLoader = getCustomClassloader(configuration.getClassPathEntries());
217 | ObjectFactory.addExternalClassLoader(classLoader);
218 | }
219 |
220 | // now run the introspections...
221 | int totalSteps = 0;
222 | for (Context context : contextsToRun) {
223 | totalSteps += context.getIntrospectionSteps();
224 | }
225 | callback.introspectionStarted(totalSteps);
226 |
227 | for (Context context : contextsToRun) {
228 | context.introspectTables(callback, warnings,
229 | fullyQualifiedTableNames);
230 | }
231 |
232 | // now run the generates
233 | totalSteps = 0;
234 | for (Context context : contextsToRun) {
235 | totalSteps += context.getGenerationSteps();
236 | }
237 | callback.generationStarted(totalSteps);
238 |
239 | for (Context context : contextsToRun) {
240 | context.generateFiles(callback, generatedJavaFiles,
241 | generatedXmlFiles, warnings);
242 | }
243 |
244 | // now save the files
245 | if (writeFiles) {
246 | callback.saveStarted(generatedXmlFiles.size()
247 | + generatedJavaFiles.size());
248 |
249 | for (GeneratedXmlFile gxf : generatedXmlFiles) {
250 | projects.add(gxf.getTargetProject());
251 | writeGeneratedXmlFile(gxf, callback);
252 | }
253 |
254 | for (GeneratedJavaFile gjf : generatedJavaFiles) {
255 | projects.add(gjf.getTargetProject());
256 | writeGeneratedJavaFile(gjf, callback);
257 | }
258 |
259 | for (String project : projects) {
260 | shellCallback.refreshProject(project);
261 | }
262 | }
263 |
264 | callback.done();
265 | }
266 |
267 | private void writeGeneratedJavaFile(GeneratedJavaFile gjf, ProgressCallback callback)
268 | throws InterruptedException, IOException {
269 | File targetFile;
270 | String source;
271 | try {
272 | File directory = shellCallback.getDirectory(gjf
273 | .getTargetProject(), gjf.getTargetPackage());
274 | targetFile = new File(directory, gjf.getFileName());
275 | if (targetFile.exists()) {
276 | if (shellCallback.isMergeSupported()) {
277 | source = shellCallback.mergeJavaFile(gjf .getFormattedContent(),
278 | targetFile,
279 | MergeConstants.OLD_ELEMENT_TAGS,
280 | gjf.getFileEncoding());
281 | } else if (shellCallback.isOverwriteEnabled()) {
282 | source = gjf.getFormattedContent();
283 | warnings.add(getString("Warning.11", //$NON-NLS-1$
284 | targetFile.getAbsolutePath()));
285 | } else {
286 | source = gjf.getFormattedContent();
287 | targetFile = getUniqueFileName(directory, gjf
288 | .getFileName());
289 | warnings.add(getString(
290 | "Warning.2", targetFile.getAbsolutePath())); //$NON-NLS-1$
291 | }
292 | } else {
293 | source = gjf.getFormattedContent();
294 | }
295 |
296 | callback.checkCancel();
297 | callback.startTask(getString(
298 | "Progress.15", targetFile.getName())); //$NON-NLS-1$
299 | writeFile(targetFile, source, gjf.getFileEncoding());
300 | } catch (ShellException e) {
301 | warnings.add(e.getMessage());
302 | }
303 | }
304 |
305 | private void writeGeneratedXmlFile(GeneratedXmlFile gxf, ProgressCallback callback)
306 | throws InterruptedException, IOException {
307 | File targetFile;
308 | String source;
309 | try {
310 | File directory = shellCallback.getDirectory(gxf
311 | .getTargetProject(), gxf.getTargetPackage());
312 | targetFile = new File(directory, gxf.getFileName());
313 | if (targetFile.exists()) {
314 | if (gxf.isMergeable()) {
315 | source = XmlFileMerger.getMergedSource(gxf,
316 | targetFile);
317 | } else if (shellCallback.isOverwriteEnabled()) {
318 | source = gxf.getFormattedContent();
319 | warnings.add(getString("Warning.11", //$NON-NLS-1$
320 | targetFile.getAbsolutePath()));
321 | } else {
322 | source = gxf.getFormattedContent();
323 | targetFile = getUniqueFileName(directory, gxf
324 | .getFileName());
325 | warnings.add(getString(
326 | "Warning.2", targetFile.getAbsolutePath())); //$NON-NLS-1$
327 | }
328 | } else {
329 | source = gxf.getFormattedContent();
330 | }
331 |
332 | callback.checkCancel();
333 | callback.startTask(getString(
334 | "Progress.15", targetFile.getName())); //$NON-NLS-1$
335 | writeFile(targetFile, source, "UTF-8"); //$NON-NLS-1$
336 | } catch (ShellException e) {
337 | warnings.add(e.getMessage());
338 | }
339 | }
340 |
341 | /**
342 | * Writes, or overwrites, the contents of the specified file.
343 | *
344 | * @param file the file
345 | * @param content the content
346 | * @param fileEncoding the file encoding
347 | * @throws IOException Signals that an I/O exception has occurred.
348 | */
349 | private void writeFile(File file, String content, String fileEncoding) throws IOException {
350 | FileOutputStream fos = new FileOutputStream(file, false);
351 | OutputStreamWriter osw;
352 | if (fileEncoding == null) {
353 | osw = new OutputStreamWriter(fos);
354 | } else {
355 | osw = new OutputStreamWriter(fos, fileEncoding);
356 | }
357 |
358 | BufferedWriter bw = new BufferedWriter(osw);
359 | bw.write(content);
360 | bw.close();
361 | }
362 |
363 | /**
364 | * Gets the unique file name.
365 | *
366 | * @param directory the directory
367 | * @param fileName the file name
368 | * @return the unique file name
369 | */
370 | private File getUniqueFileName(File directory, String fileName) {
371 | File answer = null;
372 |
373 | // try up to 1000 times to generate a unique file name
374 | StringBuilder sb = new StringBuilder();
375 | for (int i = 1; i < 1000; i++) {
376 | sb.setLength(0);
377 | sb.append(fileName);
378 | sb.append('.');
379 | sb.append(i);
380 |
381 | File testFile = new File(directory, sb.toString());
382 | if (!testFile.exists()) {
383 | answer = testFile;
384 | break;
385 | }
386 | }
387 |
388 | if (answer == null) {
389 | throw new RuntimeException(getString(
390 | "RuntimeError.3", directory.getAbsolutePath())); //$NON-NLS-1$
391 | }
392 |
393 | return answer;
394 | }
395 |
396 | /**
397 | * Returns the list of generated Java files after a call to one of the generate methods.
398 | * This is useful if you prefer to process the generated files yourself and do not want
399 | * the generator to write them to disk.
400 | *
401 | * @return the list of generated Java files
402 | */
403 | public List getGeneratedJavaFiles() {
404 | return generatedJavaFiles;
405 | }
406 |
407 | /**
408 | * Returns the list of generated XML files after a call to one of the generate methods.
409 | * This is useful if you prefer to process the generated files yourself and do not want
410 | * the generator to write them to disk.
411 | *
412 | * @return the list of generated XML files
413 | */
414 | public List getGeneratedXmlFiles() {
415 | return generatedXmlFiles;
416 | }
417 | }
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/ui/GeneratorSettingUI.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.ui;
2 |
3 | import com.github.leecho.idea.plugin.mybatis.generator.model.GlobalConfig;
4 | import com.github.leecho.idea.plugin.mybatis.generator.setting.MyBatisGeneratorConfiguration;
5 | import com.github.leecho.idea.plugin.mybatis.generator.util.StringUtils;
6 | import com.intellij.ide.util.PackageChooserDialog;
7 | import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
8 | import com.intellij.openapi.project.Project;
9 | import com.intellij.openapi.ui.Messages;
10 | import com.intellij.openapi.ui.TextBrowseFolderListener;
11 | import com.intellij.openapi.ui.TextFieldWithBrowseButton;
12 | import com.intellij.openapi.ui.VerticalFlowLayout;
13 | import com.intellij.psi.PsiPackage;
14 | import com.intellij.ui.EditorTextFieldWithBrowseButton;
15 | import com.intellij.ui.TitledSeparator;
16 | import com.intellij.ui.components.JBLabel;
17 | import com.intellij.ui.components.JBPanel;
18 |
19 | import javax.swing.*;
20 | import java.awt.*;
21 | import java.awt.event.ActionEvent;
22 |
23 | /**
24 | * 设置界面
25 | * Created by kangtian on 2018/8/3.
26 | */
27 | public class GeneratorSettingUI extends JDialog {
28 | public JPanel contentPanel = new JBPanel<>();
29 |
30 | private Project project;
31 |
32 | private EditorTextFieldWithBrowseButton domainPackageField;
33 | private EditorTextFieldWithBrowseButton mapperPackageField;
34 | private JTextField xmlPackageField = new JTextField();
35 | private EditorTextFieldWithBrowseButton examplePackageField;
36 | private TextFieldWithBrowseButton moduleRootField = new TextFieldWithBrowseButton();
37 |
38 | private JTextField sourcePathField = new JTextField();
39 | private JTextField resourcePathField = new JTextField();
40 |
41 | private JTextField tablePrefixField = new JTextField(10);
42 |
43 | private JTextField mapperPostfixField = new JTextField(10);
44 | private JTextField examplePostfixField = new JTextField(10);
45 |
46 | private JCheckBox offsetLimitBox = new JCheckBox("Pageable");
47 | private JCheckBox commentBox = new JCheckBox("Comment");
48 | private JCheckBox overrideBox = new JCheckBox("Overwrite");
49 | private JCheckBox needToStringHashcodeEqualsBox = new JCheckBox("toString/hashCode/equals");
50 | private JCheckBox useSchemaPrefixBox = new JCheckBox("Use Schema Prefix");
51 | private JCheckBox needForUpdateBox = new JCheckBox("Add ForUpdate");
52 | private JCheckBox annotationDAOBox = new JCheckBox("Repository Annotation");
53 | private JCheckBox useDAOExtendStyleBox = new JCheckBox("Parent Interface");
54 | private JCheckBox jsr310SupportBox = new JCheckBox("JSR310: Date and Time API");
55 | private JCheckBox annotationBox = new JCheckBox("JPA Annotation");
56 | private JCheckBox useActualColumnNamesBox = new JCheckBox("Actual-Column");
57 | private JCheckBox useTableNameAliasBox = new JCheckBox("Use-Alias");
58 | private JCheckBox useExampleBox = new JCheckBox("Use Example");
59 | private JCheckBox mysql8Box = new JCheckBox("MySQL 8");
60 | private JCheckBox lombokAnnotationBox = new JCheckBox("Lombok");
61 | private JCheckBox lombokBuilderAnnotationBox = new JCheckBox("Lombok Builder");
62 | private JCheckBox swaggerAnnotationBox = new JCheckBox("Swagger Model");
63 |
64 |
65 | private MyBatisGeneratorConfiguration config;
66 |
67 | public GeneratorSettingUI() {
68 | setContentPane(contentPanel);
69 | }
70 |
71 |
72 | public void createUI(Project project) {
73 | this.project = project;
74 | contentPanel.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP));
75 |
76 | config = MyBatisGeneratorConfiguration.getInstance(project);
77 |
78 | this.initPathPanel();
79 | this.initPostfixPanel();
80 | this.initPackagePanel();
81 | this.initOptionsPanel();
82 | this.initClearCachePanel();
83 | this.reset();
84 | }
85 |
86 | private void initOptionsPanel() {
87 | JBPanel optionsPanel = new JBPanel(new GridLayout(6, 2, 10, 10));
88 |
89 | optionsPanel.add(offsetLimitBox);
90 | optionsPanel.add(commentBox);
91 | optionsPanel.add(overrideBox);
92 | optionsPanel.add(needToStringHashcodeEqualsBox);
93 | optionsPanel.add(useSchemaPrefixBox);
94 | optionsPanel.add(needForUpdateBox);
95 | optionsPanel.add(annotationDAOBox);
96 | optionsPanel.add(useDAOExtendStyleBox);
97 | optionsPanel.add(jsr310SupportBox);
98 | optionsPanel.add(annotationBox);
99 | optionsPanel.add(useActualColumnNamesBox);
100 | optionsPanel.add(useTableNameAliasBox);
101 | optionsPanel.add(useExampleBox);
102 | optionsPanel.add(mysql8Box);
103 | optionsPanel.add(lombokAnnotationBox);
104 | optionsPanel.add(lombokBuilderAnnotationBox);
105 | optionsPanel.add(swaggerAnnotationBox);
106 |
107 | TitledSeparator separator = new TitledSeparator();
108 | separator.setText("Options");
109 | contentPanel.add(separator);
110 | contentPanel.add(optionsPanel);
111 | }
112 |
113 | private void initPathPanel() {
114 |
115 | JPanel sourcePathPanel = new JPanel();
116 | sourcePathPanel.setLayout(new BoxLayout(sourcePathPanel, BoxLayout.X_AXIS));
117 | JBLabel sourcePathLabel = new JBLabel("Source Path:");
118 | sourcePathLabel.setPreferredSize(new Dimension(200, 20));
119 | sourcePathPanel.add(sourcePathLabel);
120 | sourcePathPanel.add(sourcePathField);
121 |
122 | JPanel resourcePathPanel = new JPanel();
123 | resourcePathPanel.setLayout(new BoxLayout(resourcePathPanel, BoxLayout.X_AXIS));
124 | JBLabel resourcePathLabel = new JBLabel("Resource Path:");
125 | resourcePathLabel.setPreferredSize(new Dimension(200, 20));
126 | resourcePathPanel.add(resourcePathLabel);
127 | resourcePathPanel.add(resourcePathField);
128 |
129 | JPanel pathPanel = new JPanel();
130 | pathPanel.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP));
131 | TitledSeparator separator = new TitledSeparator();
132 | separator.setText("Path");
133 | pathPanel.add(sourcePathPanel);
134 | pathPanel.add(resourcePathPanel);
135 | contentPanel.add(separator);
136 | contentPanel.add(pathPanel);
137 | }
138 |
139 | private void initClearCachePanel() {
140 |
141 | JPanel clearCachePanel = new JPanel();
142 | clearCachePanel.setLayout(new BoxLayout(clearCachePanel, BoxLayout.X_AXIS));
143 | JButton clearCacheButton = new JButton("Clear Generate Setting");
144 | JBLabel clearCacheLabel = new JBLabel("");
145 | clearCachePanel.add(clearCacheButton);
146 | clearCachePanel.add(clearCacheLabel);
147 |
148 | clearCacheButton.addActionListener(e -> {
149 | int confirm = Messages.showOkCancelDialog(project, "Confirm clear generate setting?", "Mybatis Generator Plus", Messages.getQuestionIcon());
150 | if (confirm == 2) {
151 | return;
152 | }
153 | config.setTableConfigs(null);
154 | clearCacheLabel.setText("Clear generate setting successful!");
155 | });
156 | TitledSeparator separator = new TitledSeparator();
157 | separator.setText("Others");
158 | contentPanel.add(separator);
159 | contentPanel.add(clearCachePanel);
160 | }
161 |
162 |
163 | private void initPostfixPanel() {
164 |
165 | JPanel tablePrefixPanel = new JPanel();
166 | tablePrefixPanel.setLayout(new BoxLayout(tablePrefixPanel, BoxLayout.X_AXIS));
167 | JBLabel tablePrefixLabel = new JBLabel("Table Prefix:");
168 | tablePrefixLabel.setPreferredSize(new Dimension(200, 20));
169 | tablePrefixPanel.add(tablePrefixLabel);
170 | tablePrefixPanel.add(tablePrefixField);
171 |
172 | JPanel prefixPanel = new JPanel();
173 | prefixPanel.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP));
174 | TitledSeparator separator = new TitledSeparator();
175 | separator.setText("Prefix");
176 | prefixPanel.add(tablePrefixPanel);
177 | contentPanel.add(separator);
178 | contentPanel.add(prefixPanel);
179 |
180 |
181 | JPanel mapperPostfixPanel = new JPanel();
182 | mapperPostfixPanel.setLayout(new BoxLayout(mapperPostfixPanel, BoxLayout.X_AXIS));
183 | JBLabel mapperPostfixLabel = new JBLabel("Mapper Postfix:");
184 | mapperPostfixLabel.setPreferredSize(new Dimension(200, 20));
185 | mapperPostfixPanel.add(mapperPostfixLabel);
186 | mapperPostfixPanel.add(mapperPostfixField);
187 |
188 | JPanel examplePostfixPanel = new JPanel();
189 | examplePostfixPanel.setLayout(new BoxLayout(examplePostfixPanel, BoxLayout.X_AXIS));
190 | JBLabel examplePostfixLabel = new JBLabel("Example Postfix:");
191 | examplePostfixLabel.setPreferredSize(new Dimension(200, 20));
192 | examplePostfixPanel.add(examplePostfixLabel);
193 | examplePostfixPanel.add(examplePostfixField);
194 |
195 | JPanel postfixPanel = new JPanel();
196 | postfixPanel.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP));
197 | TitledSeparator separator2 = new TitledSeparator();
198 | separator2.setText("Postfix");
199 | postfixPanel.add(mapperPostfixPanel);
200 | postfixPanel.add(examplePostfixPanel);
201 | contentPanel.add(separator2);
202 | contentPanel.add(postfixPanel);
203 | }
204 |
205 | private void initPackagePanel() {
206 |
207 | GlobalConfig globalConfig = config.getGlobalConfig();
208 |
209 | JPanel projectRootPanel = new JPanel();
210 | projectRootPanel.setLayout(new BoxLayout(projectRootPanel, BoxLayout.X_AXIS));
211 | JBLabel projectRootLabel = new JBLabel("Module Root:");
212 | projectRootLabel.setPreferredSize(new Dimension(200, 20));
213 | moduleRootField.addBrowseFolderListener(new TextBrowseFolderListener(FileChooserDescriptorFactory.createSingleFolderDescriptor()) {
214 | @Override
215 | public void actionPerformed(ActionEvent e) {
216 | super.actionPerformed(e);
217 | moduleRootField.setText(moduleRootField.getText().replaceAll("\\\\", "/"));
218 | }
219 | });
220 | if (globalConfig != null && !StringUtils.isEmpty(globalConfig.getModuleRootPath())) {
221 | moduleRootField.setText(globalConfig.getModuleRootPath());
222 | } else {
223 | moduleRootField.setText(project.getBasePath());
224 | }
225 | projectRootPanel.add(projectRootLabel);
226 | projectRootPanel.add(moduleRootField);
227 |
228 | JPanel entityPackagePanel = new JPanel();
229 | entityPackagePanel.setLayout(new BoxLayout(entityPackagePanel, BoxLayout.X_AXIS));
230 | JBLabel entityPackageLabel = new JBLabel("Domain Package:");
231 | entityPackageLabel.setPreferredSize(new Dimension(200, 20));
232 | domainPackageField = new EditorTextFieldWithBrowseButton(project, false);
233 | domainPackageField.addActionListener(e -> {
234 | final PackageChooserDialog chooser = new PackageChooserDialog("Select Domain Package", project);
235 | chooser.selectPackage(domainPackageField.getText());
236 | chooser.show();
237 | final PsiPackage psiPackage = chooser.getSelectedPackage();
238 | String packageName = psiPackage == null ? null : psiPackage.getQualifiedName();
239 | domainPackageField.setText(packageName);
240 | });
241 | entityPackagePanel.add(entityPackageLabel);
242 | entityPackagePanel.add(domainPackageField);
243 |
244 | JPanel mapperPackagePanel = new JPanel();
245 | mapperPackagePanel.setLayout(new BoxLayout(mapperPackagePanel, BoxLayout.X_AXIS));
246 | JLabel mapperPackageLabel = new JLabel("Mapper Package:");
247 | mapperPackageLabel.setPreferredSize(new Dimension(200, 20));
248 | mapperPackageField = new EditorTextFieldWithBrowseButton(project, false);
249 | mapperPackageField.addActionListener(e -> {
250 | final PackageChooserDialog packageChooserDialog = new PackageChooserDialog("Select Mapper Package", project);
251 | packageChooserDialog.selectPackage(mapperPackageField.getText());
252 | packageChooserDialog.show();
253 | final PsiPackage psiPackage = packageChooserDialog.getSelectedPackage();
254 | String packageName = psiPackage == null ? null : psiPackage.getQualifiedName();
255 | mapperPackageField.setText(packageName);
256 | });
257 | mapperPackagePanel.add(mapperPackageLabel);
258 | mapperPackagePanel.add(mapperPackageField);
259 |
260 | JPanel examplePackagePanel = new JPanel();
261 | examplePackagePanel.setLayout(new BoxLayout(examplePackagePanel, BoxLayout.X_AXIS));
262 | JLabel examplePackageLabel = new JLabel("Example Package:");
263 | examplePackageLabel.setPreferredSize(new Dimension(200, 20));
264 | examplePackageField = new EditorTextFieldWithBrowseButton(project, false);
265 | examplePackageField.addActionListener(e -> {
266 | final PackageChooserDialog packageChooserDialog = new PackageChooserDialog("Select Example Package", project);
267 | packageChooserDialog.selectPackage(examplePackageField.getText());
268 | packageChooserDialog.show();
269 | final PsiPackage psiPackage = packageChooserDialog.getSelectedPackage();
270 | String packageName = psiPackage == null ? null : psiPackage.getQualifiedName();
271 | examplePackageField.setText(packageName);
272 | });
273 | examplePackagePanel.add(examplePackageLabel);
274 | examplePackagePanel.add(examplePackageField);
275 |
276 | JPanel xmlPackagePanel = new JPanel();
277 | xmlPackagePanel.setLayout(new BoxLayout(xmlPackagePanel, BoxLayout.X_AXIS));
278 | JLabel xmlPackageLabel = new JLabel("Xml Package:");
279 | xmlPackageLabel.setPreferredSize(new Dimension(200, 20));
280 | xmlPackageField.setText(globalConfig.getXmlPackage());
281 | xmlPackagePanel.add(xmlPackageLabel);
282 | xmlPackagePanel.add(xmlPackageField);
283 |
284 | JPanel packagePanel = new JPanel();
285 | packagePanel.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP));
286 | packagePanel.add(projectRootPanel);
287 | packagePanel.add(entityPackagePanel);
288 | packagePanel.add(mapperPackagePanel);
289 | packagePanel.add(examplePackagePanel);
290 | packagePanel.add(xmlPackagePanel);
291 |
292 | TitledSeparator separator = new TitledSeparator();
293 | separator.setText("Package");
294 | contentPanel.add(separator);
295 | contentPanel.add(packagePanel);
296 | }
297 |
298 | public boolean isModified() {
299 | boolean modified = !this.domainPackageField.getText().equals(config.getGlobalConfig().getDomainPackage());
300 | modified |= !this.moduleRootField.getText().equals(config.getGlobalConfig().getModuleRootPath());
301 | modified |= !this.mapperPackageField.getText().equals(config.getGlobalConfig().getMapperPackage());
302 | modified |= !this.xmlPackageField.getText().equals(config.getGlobalConfig().getXmlPackage());
303 | modified |= !this.examplePackageField.getText().equals(config.getGlobalConfig().getExamplePackage());
304 | modified |= !this.mapperPostfixField.getText().equals(config.getGlobalConfig().getMapperPostfix());
305 | modified |= !this.examplePostfixField.getText().equals(config.getGlobalConfig().getExamplePostfix());
306 | modified |= !this.tablePrefixField.getText().equals(config.getGlobalConfig().getTablePrefix());
307 | modified |= !this.sourcePathField.getText().equals(config.getGlobalConfig().getSourcePath());
308 | modified |= !this.resourcePathField.getText().equals(config.getGlobalConfig().getResourcePath());
309 | modified |= (this.offsetLimitBox.getSelectedObjects() != null) == (config.getGlobalConfig().isOffsetLimit());
310 | modified |= (this.commentBox.getSelectedObjects() != null) == (config.getGlobalConfig().isComment());
311 | modified |= (this.overrideBox.getSelectedObjects() != null) == (config.getGlobalConfig().isOverride());
312 | modified |= (this.needToStringHashcodeEqualsBox.getSelectedObjects() != null) == (config.getGlobalConfig().isNeedToStringHashcodeEquals());
313 | modified |= (this.annotationDAOBox.getSelectedObjects() != null) == (config.getGlobalConfig().isAnnotationDAO());
314 | modified |= (this.useDAOExtendStyleBox.getSelectedObjects() != null) == (config.getGlobalConfig().isUseDAOExtendStyle());
315 | modified |= (this.jsr310SupportBox.getSelectedObjects() != null) == (config.getGlobalConfig().isJsr310Support());
316 | modified |= (this.annotationBox.getSelectedObjects() != null) == (config.getGlobalConfig().isAnnotation());
317 | modified |= (this.useActualColumnNamesBox.getSelectedObjects() != null) == (config.getGlobalConfig().isUseActualColumnNames());
318 | modified |= (this.useTableNameAliasBox.getSelectedObjects() != null) == (config.getGlobalConfig().isUseTableNameAlias());
319 | modified |= (this.useExampleBox.getSelectedObjects() != null) == (config.getGlobalConfig().isUseExample());
320 | modified |= (this.mysql8Box.getSelectedObjects() != null) == (config.getGlobalConfig().isMysql8());
321 | modified |= (this.lombokAnnotationBox.getSelectedObjects() != null) == (config.getGlobalConfig().isLombokAnnotation());
322 | modified |= (this.lombokBuilderAnnotationBox.getSelectedObjects() != null) == (config.getGlobalConfig().isLombokBuilderAnnotation());
323 | modified |= (this.swaggerAnnotationBox.getSelectedObjects() != null) == (config.getGlobalConfig().isSwaggerAnnotation());
324 | return modified;
325 | }
326 |
327 | public void apply() {
328 | GlobalConfig globalConfig = new GlobalConfig();
329 | globalConfig.setModuleRootPath(moduleRootField.getText());
330 | globalConfig.setMapperPostfix(mapperPostfixField.getText());
331 | globalConfig.setExamplePostfix(examplePostfixField.getText());
332 | globalConfig.setTablePrefix(tablePrefixField.getText());
333 | globalConfig.setDomainPackage(domainPackageField.getText());
334 | globalConfig.setMapperPackage(mapperPackageField.getText());
335 | globalConfig.setExamplePackage(examplePackageField.getText());
336 | globalConfig.setXmlPackage(xmlPackageField.getText());
337 | globalConfig.setOffsetLimit(offsetLimitBox.getSelectedObjects() != null);
338 | globalConfig.setComment(commentBox.getSelectedObjects() != null);
339 | globalConfig.setOverride(overrideBox.getSelectedObjects() != null);
340 | globalConfig.setNeedToStringHashcodeEquals(needToStringHashcodeEqualsBox.getSelectedObjects() != null);
341 | globalConfig.setUseSchemaPrefix(useSchemaPrefixBox.getSelectedObjects() != null);
342 | globalConfig.setNeedForUpdate(needForUpdateBox.getSelectedObjects() != null);
343 | globalConfig.setAnnotationDAO(annotationDAOBox.getSelectedObjects() != null);
344 | globalConfig.setUseDAOExtendStyle(useDAOExtendStyleBox.getSelectedObjects() != null);
345 | globalConfig.setJsr310Support(jsr310SupportBox.getSelectedObjects() != null);
346 | globalConfig.setAnnotation(annotationBox.getSelectedObjects() != null);
347 | globalConfig.setUseActualColumnNames(useActualColumnNamesBox.getSelectedObjects() != null);
348 | globalConfig.setUseTableNameAlias(useTableNameAliasBox.getSelectedObjects() != null);
349 | globalConfig.setUseExample(useExampleBox.getSelectedObjects() != null);
350 | globalConfig.setMysql8(mysql8Box.getSelectedObjects() != null);
351 | globalConfig.setLombokAnnotation(lombokAnnotationBox.getSelectedObjects() != null);
352 | globalConfig.setLombokBuilderAnnotation(lombokBuilderAnnotationBox.getSelectedObjects() != null);
353 | globalConfig.setSwaggerAnnotation(swaggerAnnotationBox.getSelectedObjects() != null);
354 |
355 | globalConfig.setSourcePath(sourcePathField.getText());
356 | globalConfig.setResourcePath(resourcePathField.getText());
357 |
358 | this.config.setGlobalConfig(globalConfig);
359 |
360 |
361 | }
362 |
363 | public void reset() {
364 | GlobalConfig globalConfig = config.getGlobalConfig();
365 | mapperPostfixField.setText(globalConfig.getMapperPostfix());
366 | examplePostfixField.setText(globalConfig.getExamplePostfix());
367 | tablePrefixField.setText(globalConfig.getTablePrefix());
368 | domainPackageField.setText(globalConfig.getDomainPackage());
369 | mapperPackageField.setText(globalConfig.getMapperPackage());
370 | examplePackageField.setText(globalConfig.getExamplePackage());
371 | xmlPackageField.setText(globalConfig.getXmlPackage());
372 |
373 | sourcePathField.setText(globalConfig.getSourcePath());
374 | resourcePathField.setText(globalConfig.getResourcePath());
375 |
376 | offsetLimitBox.setSelected(globalConfig.isOffsetLimit());
377 | commentBox.setSelected(globalConfig.isComment());
378 | overrideBox.setSelected(globalConfig.isOverride());
379 | needToStringHashcodeEqualsBox.setSelected(globalConfig.isNeedToStringHashcodeEquals());
380 | useSchemaPrefixBox.setSelected(globalConfig.isUseSchemaPrefix());
381 | needForUpdateBox.setSelected(globalConfig.isNeedForUpdate());
382 | annotationDAOBox.setSelected(globalConfig.isAnnotationDAO());
383 | useDAOExtendStyleBox.setSelected(globalConfig.isUseDAOExtendStyle());
384 | jsr310SupportBox.setSelected(globalConfig.isJsr310Support());
385 | annotationBox.setSelected(globalConfig.isAnnotation());
386 | useActualColumnNamesBox.setSelected(globalConfig.isUseActualColumnNames());
387 | useTableNameAliasBox.setSelected(globalConfig.isUseTableNameAlias());
388 | useExampleBox.setSelected(globalConfig.isUseExample());
389 | mysql8Box.setSelected(globalConfig.isMysql8());
390 | lombokAnnotationBox.setSelected(globalConfig.isLombokAnnotation());
391 | lombokBuilderAnnotationBox.setSelected(globalConfig.isLombokBuilderAnnotation());
392 | swaggerAnnotationBox.setSelected(globalConfig.isSwaggerAnnotation());
393 |
394 | }
395 |
396 | @Override
397 | public JPanel getContentPane() {
398 | return contentPanel;
399 | }
400 |
401 |
402 | }
403 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/generate/MyBatisGenerateCommand.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.generate;
2 |
3 | import cn.kt.DbRemarksCommentGenerator;
4 | import com.github.leecho.idea.plugin.mybatis.generator.model.TableConfig;
5 | import com.intellij.credentialStore.CredentialAttributes;
6 | import com.intellij.database.model.RawConnectionConfig;
7 | import com.intellij.ide.passwordSafe.PasswordSafe;
8 | import com.intellij.notification.*;
9 | import com.intellij.openapi.fileEditor.OpenFileDescriptor;
10 | import com.intellij.openapi.progress.ProgressIndicator;
11 | import com.intellij.openapi.progress.Task;
12 | import com.intellij.openapi.project.Project;
13 | import com.intellij.openapi.ui.MessageType;
14 | import com.intellij.openapi.ui.Messages;
15 | import com.intellij.openapi.ui.popup.Balloon;
16 | import com.intellij.openapi.ui.popup.JBPopupFactory;
17 | import com.intellij.openapi.vfs.VirtualFile;
18 | import com.intellij.openapi.wm.StatusBar;
19 | import com.intellij.openapi.wm.WindowManager;
20 | import com.intellij.ui.awt.RelativePoint;
21 | import com.github.leecho.idea.plugin.mybatis.generator.model.Credential;
22 | import com.github.leecho.idea.plugin.mybatis.generator.model.DbType;
23 | import com.github.leecho.idea.plugin.mybatis.generator.setting.MyBatisGeneratorConfiguration;
24 | import com.github.leecho.idea.plugin.mybatis.generator.util.StringUtils;
25 | import org.mybatis.generator.api.ShellCallback;
26 | import org.mybatis.generator.config.*;
27 | import org.mybatis.generator.internal.DefaultShellCallback;
28 |
29 | import javax.swing.event.HyperlinkEvent;
30 | import java.io.File;
31 | import java.util.*;
32 | import java.util.stream.Collectors;
33 |
34 | /**
35 | * 生成mybatis相关代码
36 | * Created by kangtian on 2018/7/28.
37 | */
38 | public class MyBatisGenerateCommand {
39 |
40 | //持久化的配置
41 | private MyBatisGeneratorConfiguration myBatisGeneratorConfiguration;
42 | //界面默认配置
43 | private TableConfig tableConfig;
44 | private String username;
45 | //数据库类型
46 | private String databaseType;
47 | //数据库驱动
48 | private String driverClass;
49 | //数据库连接url
50 | private String url;
51 |
52 | public MyBatisGenerateCommand(TableConfig tableConfig) {
53 | this.tableConfig = tableConfig;
54 | }
55 |
56 | /**
57 | * 自动生成的主逻辑
58 | *
59 | * @param project
60 | * @param connectionConfig
61 | * @throws Exception
62 | */
63 | public void execute(Project project, RawConnectionConfig connectionConfig) {
64 | this.myBatisGeneratorConfiguration = MyBatisGeneratorConfiguration.getInstance(project);
65 |
66 | saveConfig();//执行前 先保存一份当前配置
67 |
68 | driverClass = connectionConfig.getDriverClass();
69 | url = connectionConfig.getUrl();
70 | if (driverClass.contains("mysql")) {
71 | databaseType = "MySQL";
72 | } else if (driverClass.contains("oracle")) {
73 | databaseType = "Oracle";
74 | } else if (driverClass.contains("postgresql")) {
75 | databaseType = "PostgreSQL";
76 | } else if (driverClass.contains("sqlserver")) {
77 | databaseType = "SqlServer";
78 | } else if (driverClass.contains("sqlite")) {
79 | databaseType = "Sqlite";
80 | } else if (driverClass.contains("mariadb")) {
81 | databaseType = "MariaDB";
82 | }
83 |
84 |
85 | Configuration configuration = new Configuration();
86 | Context context = new Context(ModelType.CONDITIONAL);
87 | configuration.addContext(context);
88 |
89 | context.setId("myid");
90 | context.addProperty("autoDelimitKeywords", "true");
91 | context.addProperty("beginningDelimiter", "`");
92 | context.addProperty("endingDelimiter", "`");
93 | context.addProperty("javaFileEncoding", "UTF-8");
94 | context.addProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING, "UTF-8");
95 | context.setTargetRuntime("MyBatis3");
96 |
97 | JDBCConnectionConfiguration jdbcConfig = buildJdbcConfig();
98 | if (jdbcConfig == null) {
99 | return;
100 | }
101 | TableConfiguration tableConfig = buildTableConfig(context);
102 | JavaModelGeneratorConfiguration modelConfig = buildModelConfig();
103 | SqlMapGeneratorConfiguration mapperConfig = buildMapperXmlConfig();
104 | JavaClientGeneratorConfiguration daoConfig = buildMapperConfig();
105 | CommentGeneratorConfiguration commentConfig = buildCommentConfig();
106 |
107 | context.addTableConfiguration(tableConfig);
108 | context.setJdbcConnectionConfiguration(jdbcConfig);
109 | context.setJavaModelGeneratorConfiguration(modelConfig);
110 | context.setSqlMapGeneratorConfiguration(mapperConfig);
111 | context.setJavaClientGeneratorConfiguration(daoConfig);
112 | context.setCommentGeneratorConfiguration(commentConfig);
113 | addPluginConfiguration(context);
114 |
115 | createFolderForNeed(this.tableConfig);
116 | List warnings = new ArrayList<>();
117 | // override=true
118 | ShellCallback shellCallback;
119 | if (this.tableConfig.isOverride()) {
120 | shellCallback = new DefaultShellCallback(true);
121 | } else {
122 | shellCallback = new MergeableShellCallback(true);
123 | }
124 | Set fullyQualifiedTables = new HashSet<>();
125 | Set contexts = new HashSet<>();
126 |
127 | try {
128 | MyBatisCodeGenerator myBatisCodeGenerator = new MyBatisCodeGenerator(configuration, shellCallback, warnings);
129 | StatusBar statusBar = WindowManager.getInstance().getStatusBar(project);
130 | Balloon balloon = JBPopupFactory.getInstance()
131 | .createHtmlTextBalloonBuilder("Generating Code...", MessageType.INFO, null)
132 | .createBalloon();
133 | balloon.show(RelativePoint.getCenterOf(statusBar.getComponent()), Balloon.Position.atRight);
134 |
135 | Task.Backgroundable generateTask = new Task.Backgroundable(project, "Generating MyBatis Code", false) {
136 | @Override
137 | public void run(ProgressIndicator indicator) {
138 | indicator.setText("Generating MyBatis Code");
139 | indicator.setFraction(0.0);
140 | indicator.setIndeterminate(true);
141 | try {
142 | myBatisCodeGenerator.generate(new GenerateCallback(indicator, balloon), contexts, fullyQualifiedTables);
143 | VirtualFile baseDir = project.getBaseDir();
144 | baseDir.refresh(false, true);
145 |
146 | NotificationGroup balloonNotifications = new NotificationGroup("Mybatis Generator Plus", NotificationDisplayType.STICKY_BALLOON, true);
147 |
148 | List result = myBatisCodeGenerator.getGeneratedJavaFiles().stream()
149 | .map(generatedJavaFile -> String.format("%s", getRelativePath(project), MyBatisGenerateCommand.this.tableConfig.getSourcePath(), generatedJavaFile.getTargetPackage().replace(".", "/"), generatedJavaFile.getFileName(), generatedJavaFile.getFileName()))
150 | .collect(Collectors.toList());
151 | result.addAll(myBatisCodeGenerator.getGeneratedXmlFiles().stream()
152 | .map(generatedXmlFile -> String.format("%s", getRelativePath(project).replace(project.getBasePath() + "/", ""), MyBatisGenerateCommand.this.tableConfig.getResourcePath(), generatedXmlFile.getTargetPackage().replace(".", "/"), generatedXmlFile.getFileName(), generatedXmlFile.getFileName()))
153 | .collect(Collectors.toList()));
154 | Notification notification = balloonNotifications.createNotification("Generate Successfully", "" + String.join("
", result) + "", NotificationType.INFORMATION, (notification1, hyperlinkEvent) -> {
155 | if (hyperlinkEvent.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
156 | new OpenFileDescriptor(project, Objects.requireNonNull(project.getBaseDir().findFileByRelativePath(hyperlinkEvent.getDescription()))).navigate(true);
157 | }
158 | });
159 | Notifications.Bus.notify(notification);
160 | } catch (Exception e) {
161 | e.printStackTrace();
162 | balloon.hide();
163 | Notification notification = new Notification("Mybatis Generator Plus", null, NotificationType.ERROR);
164 | notification.setTitle("Generate Failed");
165 | notification.setContent("Cause:" + e.getMessage());
166 | Notifications.Bus.notify(notification);
167 | }
168 | }
169 | };
170 | generateTask.setCancelText("Stop generate code").queue();
171 | generateTask.setCancelTooltipText("Stop generate mybatis code");
172 |
173 | } catch (Exception e) {
174 | e.printStackTrace();
175 | Messages.showMessageDialog(e.getMessage(), "Generate Failure", Messages.getInformationIcon());
176 | }
177 |
178 | }
179 |
180 | private String getRelativePath(Project project) {
181 | if (tableConfig.getModuleRootPath().equals(project.getBasePath())) {
182 | return "";
183 | } else {
184 | return tableConfig.getModuleRootPath().replace(project.getBasePath() + "/", "") + "/";
185 | }
186 | }
187 |
188 |
189 | /**
190 | * 创建所需目录
191 | *
192 | * @param tableConfig
193 | */
194 | private void createFolderForNeed(TableConfig tableConfig) {
195 |
196 |
197 | String sourcePath = tableConfig.getModuleRootPath() + "/" + tableConfig.getSourcePath() + "/";
198 | String resourcePath = tableConfig.getModuleRootPath() + "/" + tableConfig.getResourcePath() + "/";
199 |
200 | File sourceFile = new File(sourcePath);
201 | if (!sourceFile.exists() && !sourceFile.isDirectory()) {
202 | sourceFile.mkdirs();
203 | }
204 |
205 | File resourceFile = new File(resourcePath);
206 | if (!resourceFile.exists() && !resourceFile.isDirectory()) {
207 | resourceFile.mkdirs();
208 | }
209 | }
210 |
211 |
212 | /**
213 | * 保存当前配置到历史记录
214 | */
215 | private void saveConfig() {
216 | Map historyConfigList = myBatisGeneratorConfiguration.getTableConfigs();
217 | if (historyConfigList == null) {
218 | historyConfigList = new HashMap<>();
219 | }
220 |
221 | String daoName = tableConfig.getMapperName();
222 | String modelName = tableConfig.getDomainName();
223 | String daoPostfix = daoName.replace(modelName, "");
224 | tableConfig.setMapperPostfix(daoPostfix);
225 |
226 | historyConfigList.put(tableConfig.getName(), tableConfig);
227 | myBatisGeneratorConfiguration.setTableConfigs(historyConfigList);
228 |
229 | }
230 |
231 | /**
232 | * 生成数据库连接配置
233 | *
234 | * @return
235 | */
236 | private JDBCConnectionConfiguration buildJdbcConfig() {
237 |
238 | JDBCConnectionConfiguration jdbcConfig = new JDBCConnectionConfiguration();
239 | jdbcConfig.addProperty("nullCatalogMeansCurrent", "true");
240 | jdbcConfig.addProperty("remarks","true");
241 | jdbcConfig.addProperty("useInformationSchema","true");
242 |
243 | Map users = myBatisGeneratorConfiguration.getCredentials();
244 | //if (users != null && users.containsKey(url)) {
245 | Credential credential = users.get(url);
246 |
247 | username = credential.getUsername();
248 |
249 | CredentialAttributes credentialAttributes = new CredentialAttributes("mybatis-generator-" + url, username, this.getClass(), false);
250 | String password = PasswordSafe.getInstance().getPassword(credentialAttributes);
251 |
252 | jdbcConfig.setUserId(username);
253 | jdbcConfig.setPassword(password);
254 |
255 | Boolean mySQL_8 = tableConfig.isMysql8();
256 | if (mySQL_8) {
257 | driverClass = DbType.MySQL_8.getDriverClass();
258 | url += "?serverTimezone=UTC&useSSL=false";
259 | } else {
260 | url += "?useSSL=false";
261 | }
262 |
263 | jdbcConfig.setDriverClass(driverClass);
264 | jdbcConfig.setConnectionURL(url);
265 | return jdbcConfig;
266 | /*} else {
267 | DatabaseCredentialUI databaseCredentialUI = new DatabaseCredentialUI(driverClass, url, anActionEvent, tableConfig);
268 | return null;
269 | }*/
270 |
271 | }
272 |
273 | /**
274 | * 生成table配置
275 | *
276 | * @param context
277 | * @return
278 | */
279 | private TableConfiguration buildTableConfig(Context context) {
280 | TableConfiguration tableConfig = new TableConfiguration(context);
281 | tableConfig.setTableName(this.tableConfig.getTableName());
282 | tableConfig.setDomainObjectName(this.tableConfig.getDomainName());
283 |
284 | String schema;
285 | if (databaseType.equals(DbType.MySQL.name())) {
286 | String[] name_split = url.split("/");
287 | schema = name_split[name_split.length - 1];
288 | tableConfig.setSchema(schema);
289 | } else if (databaseType.equals(DbType.Oracle.name())) {
290 | String[] name_split = url.split(":");
291 | schema = name_split[name_split.length - 1];
292 | tableConfig.setCatalog(schema);
293 | } else {
294 | String[] name_split = url.split("/");
295 | schema = name_split[name_split.length - 1];
296 | tableConfig.setCatalog(schema);
297 | }
298 |
299 | if (!this.tableConfig.isUseExample()) {
300 | tableConfig.setUpdateByExampleStatementEnabled(false);
301 | tableConfig.setCountByExampleStatementEnabled(false);
302 | tableConfig.setDeleteByExampleStatementEnabled(false);
303 | tableConfig.setSelectByExampleStatementEnabled(false);
304 | }
305 |
306 | if (this.tableConfig.isUseSchemaPrefix()) {
307 | if (DbType.MySQL.name().equals(databaseType)) {
308 | tableConfig.setSchema(schema);
309 | } else if (DbType.Oracle.name().equals(databaseType)) {
310 | //Oracle的schema为用户名,如果连接用户拥有dba等高级权限,若不设schema,会导致把其他用户下同名的表也生成一遍导致mapper中代码重复
311 | tableConfig.setSchema(username);
312 | } else {
313 | tableConfig.setCatalog(schema);
314 | }
315 | }
316 |
317 | if(this.tableConfig.getColumnSettings().size() > 0){
318 | this.tableConfig.getColumnSettings().forEach((key, value) -> {
319 | if(value.getIgnore()){
320 | tableConfig.addIgnoredColumn(new IgnoredColumn(value.getColumn()));
321 | } else{
322 | ColumnOverride override = new ColumnOverride(value.getColumn());
323 | override.setJavaProperty(value.getJavaProperty());
324 | override.setJavaType(value.getJavaType());
325 | override.setJdbcType(value.getJdbcType());
326 | tableConfig.addColumnOverride(override);
327 | }
328 |
329 | });
330 | }
331 |
332 | if ("org.postgresql.Driver".equals(driverClass)) {
333 | tableConfig.setDelimitIdentifiers(true);
334 | }
335 |
336 | if (!StringUtils.isEmpty(this.tableConfig.getPrimaryKey())) {
337 | String dbType = databaseType;
338 | if (DbType.MySQL.name().equals(databaseType)) {
339 | dbType = "JDBC";
340 | //dbType为JDBC,且配置中开启useGeneratedKeys时,Mybatis会使用Jdbc3KeyGenerator,
341 | //使用该KeyGenerator的好处就是直接在一次INSERT 语句内,通过resultSet获取得到 生成的主键值,
342 | //并很好的支持设置了读写分离代理的数据库
343 | //例如阿里云RDS + 读写分离代理 无需指定主库
344 | //当使用SelectKey时,Mybatis会使用SelectKeyGenerator,INSERT之后,多发送一次查询语句,获得主键值
345 | //在上述读写分离被代理的情况下,会得不到正确的主键
346 | }
347 | tableConfig.setGeneratedKey(new GeneratedKey(this.tableConfig.getPrimaryKey(), dbType, true, null));
348 | }
349 |
350 | if (this.tableConfig.isUseActualColumnNames()) {
351 | tableConfig.addProperty("useActualColumnNames", "true");
352 | }
353 |
354 | if (this.tableConfig.isUseTableNameAlias()) {
355 | tableConfig.setAlias(this.tableConfig.getTableName());
356 | }
357 | tableConfig.setMapperName(this.tableConfig.getMapperName());
358 | return tableConfig;
359 | }
360 |
361 |
362 | /**
363 | * 生成实体类配置
364 | *
365 | * @return
366 | */
367 | private JavaModelGeneratorConfiguration buildModelConfig() {
368 | String projectFolder = tableConfig.getModuleRootPath();
369 | String entityPackage = tableConfig.getDomainPackage();
370 | String sourcePath = tableConfig.getSourcePath();
371 |
372 | JavaModelGeneratorConfiguration modelConfig = new JavaModelGeneratorConfiguration();
373 |
374 | if (!StringUtils.isEmpty(entityPackage)) {
375 | modelConfig.setTargetPackage(entityPackage);
376 | } else {
377 | modelConfig.setTargetPackage("");
378 | }
379 | modelConfig.setTargetProject(projectFolder + "/" + sourcePath + "/");
380 | return modelConfig;
381 | }
382 |
383 | /**
384 | * 生成mapper.xml文件配置
385 | *
386 | * @return
387 | */
388 | private SqlMapGeneratorConfiguration buildMapperXmlConfig() {
389 |
390 | String projectFolder = tableConfig.getModuleRootPath();
391 | String mappingXMLPackage = tableConfig.getXmlPackage();
392 | String resourcePath = tableConfig.getResourcePath();
393 |
394 | SqlMapGeneratorConfiguration mapperConfig = new SqlMapGeneratorConfiguration();
395 |
396 | if (!StringUtils.isEmpty(mappingXMLPackage)) {
397 | mapperConfig.setTargetPackage(mappingXMLPackage);
398 | } else {
399 | mapperConfig.setTargetPackage("");
400 | }
401 |
402 | mapperConfig.setTargetProject(projectFolder + "/" + resourcePath + "/");
403 |
404 | //14
405 | if (tableConfig.isOverride()) {
406 | String mappingXMLFilePath = getMappingXMLFilePath(tableConfig);
407 | File mappingXMLFile = new File(mappingXMLFilePath);
408 | if (mappingXMLFile.exists()) {
409 | mappingXMLFile.delete();
410 | }
411 | }
412 |
413 | return mapperConfig;
414 | }
415 |
416 | /**
417 | * 生成dao接口文件配置
418 | *
419 | * @return
420 | */
421 | private JavaClientGeneratorConfiguration buildMapperConfig() {
422 |
423 | String projectFolder = tableConfig.getModuleRootPath();
424 | String mapperPackage = tableConfig.getMapperPackage();
425 | String mapperPath = tableConfig.getSourcePath();
426 |
427 | JavaClientGeneratorConfiguration mapperConfig = new JavaClientGeneratorConfiguration();
428 | mapperConfig.setConfigurationType("XMLMAPPER");
429 | mapperConfig.setTargetPackage(mapperPackage);
430 |
431 | if (!StringUtils.isEmpty(mapperPackage)) {
432 | mapperConfig.setTargetPackage(mapperPackage);
433 | } else {
434 | mapperConfig.setTargetPackage("");
435 | }
436 |
437 | mapperConfig.setTargetProject(projectFolder + "/" + mapperPath + "/");
438 |
439 | return mapperConfig;
440 | }
441 |
442 | /**
443 | * 生成注释配置
444 | *
445 | * @return
446 | */
447 | private CommentGeneratorConfiguration buildCommentConfig() {
448 | CommentGeneratorConfiguration commentConfig = new CommentGeneratorConfiguration();
449 | commentConfig.setConfigurationType(DbRemarksCommentGenerator.class.getName());
450 |
451 | if (tableConfig.isComment()) {
452 | commentConfig.addProperty("columnRemarks", "true");
453 | }
454 | if (tableConfig.isAnnotation()) {
455 | commentConfig.addProperty("annotations", "true");
456 | }
457 |
458 | return commentConfig;
459 | }
460 |
461 | /**
462 | * 添加相关插件(注意插件文件需要通过jar引入)
463 | *
464 | * @param context
465 | */
466 | private void addPluginConfiguration(Context context) {
467 |
468 |
469 | //实体添加序列化
470 | PluginConfiguration serializablePlugin = new PluginConfiguration();
471 | serializablePlugin.addProperty("type", "org.mybatis.generator.plugins.SerializablePlugin");
472 | serializablePlugin.setConfigurationType("org.mybatis.generator.plugins.SerializablePlugin");
473 | context.addPluginConfiguration(serializablePlugin);
474 |
475 |
476 | if (tableConfig.isNeedToStringHashcodeEquals()) {
477 | PluginConfiguration equalsHashCodePlugin = new PluginConfiguration();
478 | equalsHashCodePlugin.addProperty("type", "org.mybatis.generator.plugins.EqualsHashCodePlugin");
479 | equalsHashCodePlugin.setConfigurationType("org.mybatis.generator.plugins.EqualsHashCodePlugin");
480 | context.addPluginConfiguration(equalsHashCodePlugin);
481 | PluginConfiguration toStringPluginPlugin = new PluginConfiguration();
482 | toStringPluginPlugin.addProperty("type", "org.mybatis.generator.plugins.ToStringPlugin");
483 | toStringPluginPlugin.setConfigurationType("org.mybatis.generator.plugins.ToStringPlugin");
484 | context.addPluginConfiguration(toStringPluginPlugin);
485 | }
486 |
487 | if (tableConfig.isLombokAnnotation()) {
488 | PluginConfiguration lombokPlugin = new PluginConfiguration();
489 | lombokPlugin.addProperty("type", "com.github.leecho.idea.plugin.mybatis.generator.plugin.LombokPlugin");
490 | lombokPlugin.setConfigurationType("com.github.leecho.idea.plugin.mybatis.generator.plugin.LombokPlugin");
491 | if (tableConfig.isLombokBuilderAnnotation()) {
492 | lombokPlugin.addProperty("builder", "true");
493 | lombokPlugin.addProperty("allArgsConstructor", "true");
494 | lombokPlugin.addProperty("noArgsConstructor", "true");
495 | }
496 | context.addPluginConfiguration(lombokPlugin);
497 | }
498 | if (tableConfig.isSwaggerAnnotation()) {
499 | PluginConfiguration swaggerPlugin = new PluginConfiguration();
500 | swaggerPlugin.addProperty("type", "com.github.leecho.idea.plugin.mybatis.generator.plugin.SwaggerPlugin");
501 | swaggerPlugin.setConfigurationType("com.github.leecho.idea.plugin.mybatis.generator.plugin.SwaggerPlugin");
502 | context.addPluginConfiguration(swaggerPlugin);
503 | }
504 |
505 | if (tableConfig.isUseExample()) {
506 | PluginConfiguration renameExamplePlugin = new PluginConfiguration();
507 | renameExamplePlugin.addProperty("type", "com.github.leecho.idea.plugin.mybatis.generator.plugin.RenameExampleClassPlugin");
508 | renameExamplePlugin.setConfigurationType("com.github.leecho.idea.plugin.mybatis.generator.plugin.RenameExampleClassPlugin");
509 | renameExamplePlugin.addProperty("target", tableConfig.getExamplePackage() + "." + tableConfig.getExampleName());
510 | context.addPluginConfiguration(renameExamplePlugin);
511 | }
512 |
513 |
514 | // limit/offset插件
515 | if (tableConfig.isOffsetLimit()) {
516 | if (DbType.MySQL.name().equals(databaseType)
517 | || DbType.PostgreSQL.name().equals(databaseType)) {
518 | PluginConfiguration mySQLLimitPlugin = new PluginConfiguration();
519 | mySQLLimitPlugin.addProperty("type", "cn.kt.MySQLLimitPlugin");
520 | mySQLLimitPlugin.setConfigurationType("cn.kt.MySQLLimitPlugin");
521 | context.addPluginConfiguration(mySQLLimitPlugin);
522 | }
523 | }
524 |
525 | //for JSR310
526 | if (tableConfig.isJsr310Support()) {
527 | JavaTypeResolverConfiguration javaTypeResolverPlugin = new JavaTypeResolverConfiguration();
528 | javaTypeResolverPlugin.setConfigurationType("cn.kt.JavaTypeResolverJsr310Impl");
529 | context.setJavaTypeResolverConfiguration(javaTypeResolverPlugin);
530 | }
531 |
532 | //forUpdate 插件
533 | if (tableConfig.isNeedForUpdate()) {
534 | if (DbType.MySQL.name().equals(databaseType)
535 | || DbType.PostgreSQL.name().equals(databaseType)) {
536 | PluginConfiguration mySQLForUpdatePlugin = new PluginConfiguration();
537 | mySQLForUpdatePlugin.addProperty("type", "cn.kt.MySQLForUpdatePlugin");
538 | mySQLForUpdatePlugin.setConfigurationType("cn.kt.MySQLForUpdatePlugin");
539 | context.addPluginConfiguration(mySQLForUpdatePlugin);
540 | }
541 | }
542 |
543 | //repository 插件
544 | if (tableConfig.isAnnotationDAO()) {
545 | if (DbType.MySQL.name().equals(databaseType)
546 | || DbType.PostgreSQL.name().equals(databaseType)) {
547 | PluginConfiguration repositoryPlugin = new PluginConfiguration();
548 | repositoryPlugin.addProperty("type", "cn.kt.RepositoryPlugin");
549 | repositoryPlugin.setConfigurationType("cn.kt.RepositoryPlugin");
550 | context.addPluginConfiguration(repositoryPlugin);
551 | }
552 | }
553 |
554 | //13
555 | if (tableConfig.isUseDAOExtendStyle()) {
556 | if (DbType.MySQL.name().equals(databaseType)
557 | || DbType.PostgreSQL.name().equals(databaseType)) {
558 | PluginConfiguration commonDAOInterfacePlugin = new PluginConfiguration();
559 | commonDAOInterfacePlugin.addProperty("type", "cn.kt.CommonDAOInterfacePlugin");
560 | commonDAOInterfacePlugin.setConfigurationType("cn.kt.CommonDAOInterfacePlugin");
561 | context.addPluginConfiguration(commonDAOInterfacePlugin);
562 | }
563 | }
564 |
565 | }
566 |
567 | /**
568 | * 获取xml文件路径 用以删除之前的xml
569 | *
570 | * @param tableConfig
571 | * @return
572 | */
573 | private String getMappingXMLFilePath(TableConfig tableConfig) {
574 | StringBuilder sb = new StringBuilder();
575 | String mappingXMLPackage = tableConfig.getXmlPackage();
576 | String xmlMvnPath = tableConfig.getResourcePath();
577 | sb.append(tableConfig.getModuleRootPath() + "/" + xmlMvnPath + "/");
578 |
579 | if (!StringUtils.isEmpty(mappingXMLPackage)) {
580 | sb.append(mappingXMLPackage.replace(".", "/")).append("/");
581 | }
582 | if (!StringUtils.isEmpty(tableConfig.getMapperName())) {
583 | sb.append(tableConfig.getMapperName()).append(".xml");
584 | } else {
585 | sb.append(tableConfig.getDomainName()).append("Mapper.xml");
586 | }
587 |
588 | return sb.toString();
589 | }
590 | }
591 |
--------------------------------------------------------------------------------
/src/com/github/leecho/idea/plugin/mybatis/generator/ui/GenerateSettingUI.java:
--------------------------------------------------------------------------------
1 | package com.github.leecho.idea.plugin.mybatis.generator.ui;
2 |
3 | import com.github.leecho.idea.plugin.mybatis.generator.contants.PluginContants;
4 | import com.github.leecho.idea.plugin.mybatis.generator.generate.MyBatisGenerateCommand;
5 | import com.github.leecho.idea.plugin.mybatis.generator.model.Credential;
6 | import com.github.leecho.idea.plugin.mybatis.generator.model.GlobalConfig;
7 | import com.github.leecho.idea.plugin.mybatis.generator.model.TableConfig;
8 | import com.github.leecho.idea.plugin.mybatis.generator.model.TableInfo;
9 | import com.github.leecho.idea.plugin.mybatis.generator.setting.MyBatisGeneratorConfiguration;
10 | import com.github.leecho.idea.plugin.mybatis.generator.util.DatabaseUtils;
11 | import com.github.leecho.idea.plugin.mybatis.generator.util.JTextFieldHintListener;
12 | import com.github.leecho.idea.plugin.mybatis.generator.util.StringUtils;
13 | import com.intellij.credentialStore.CredentialAttributes;
14 | import com.intellij.database.model.RawConnectionConfig;
15 | import com.intellij.database.psi.DbDataSource;
16 | import com.intellij.database.psi.DbTable;
17 | import com.intellij.ide.passwordSafe.PasswordSafe;
18 | import com.intellij.ide.util.PackageChooserDialog;
19 | import com.intellij.openapi.actionSystem.AnActionEvent;
20 | import com.intellij.openapi.actionSystem.LangDataKeys;
21 | import com.intellij.openapi.actionSystem.PlatformDataKeys;
22 | import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
23 | import com.intellij.openapi.progress.ProgressManager;
24 | import com.intellij.openapi.project.Project;
25 | import com.intellij.openapi.ui.*;
26 | import com.intellij.psi.PsiElement;
27 | import com.intellij.psi.PsiPackage;
28 | import com.intellij.ui.EditorTextFieldWithBrowseButton;
29 | import com.intellij.ui.TitledSeparator;
30 | import com.intellij.ui.components.JBLabel;
31 | import com.intellij.ui.components.JBPanel;
32 | import com.intellij.ui.components.JBTabbedPane;
33 | import com.intellij.ui.components.JBTextField;
34 | import com.intellij.util.ui.JBUI;
35 | import org.jetbrains.annotations.NotNull;
36 | import org.jetbrains.annotations.Nullable;
37 |
38 | import javax.swing.*;
39 | import java.awt.*;
40 | import java.awt.event.ActionEvent;
41 | import java.awt.event.KeyAdapter;
42 | import java.awt.event.KeyEvent;
43 | import java.sql.SQLException;
44 | import java.util.ArrayList;
45 | import java.util.List;
46 | import java.util.Map;
47 | import java.util.concurrent.Callable;
48 | import java.util.concurrent.ExecutionException;
49 | import java.util.concurrent.FutureTask;
50 |
51 | /**
52 | * 插件主界面
53 | * Created by kangtian on 2018/8/1.
54 | */
55 | public class GenerateSettingUI extends DialogWrapper {
56 |
57 | private AnActionEvent anActionEvent;
58 | private Project project;
59 | private MyBatisGeneratorConfiguration myBatisGeneratorConfiguration;
60 | private PsiElement[] psiElements;
61 | private TableConfig tableConfig;
62 |
63 | private JPanel contentPane = new JBPanel<>();
64 |
65 | private JTextField tableNameField = new JBTextField(20);
66 |
67 | private JButton columnSettingButton = new JButton("Column Setting");
68 | private TextFieldWithBrowseButton moduleRootField = new TextFieldWithBrowseButton();
69 | private EditorTextFieldWithBrowseButton basePackageField;
70 | private EditorTextFieldWithBrowseButton domainPackageField;
71 | private EditorTextFieldWithBrowseButton mapperPackageField;
72 | private EditorTextFieldWithBrowseButton examplePackageField;
73 | private JTextField xmlPackageField = new JTextField();
74 | private JTextField mapperNameField = new JBTextField(20);
75 | private JTextField domainNameField = new JBTextField(20);
76 | private JTextField exampleNameField = new JBTextField(20);
77 | private JTextField primaryKeyField = new JBTextField(20);
78 |
79 | private JPanel examplePackagePanel = new JPanel();
80 | private JPanel exampleNamePanel = new JPanel();
81 |
82 | private JCheckBox offsetLimitBox = new JCheckBox("Pageable");
83 | private JCheckBox commentBox = new JCheckBox("Comment");
84 | private JCheckBox overrideBox = new JCheckBox("Overwrite");
85 | private JCheckBox needToStringHashcodeEqualsBox = new JCheckBox("toString/hashCode/equals");
86 | private JCheckBox useSchemaPrefixBox = new JCheckBox("Use Schema Prefix");
87 | private JCheckBox needForUpdateBox = new JCheckBox("Add ForUpdate");
88 | private JCheckBox annotationDAOBox = new JCheckBox("Repository Annotation");
89 | private JCheckBox useDAOExtendStyleBox = new JCheckBox("Parent Interface");
90 | private JCheckBox jsr310SupportBox = new JCheckBox("JSR310: Date and Time API");
91 | private JCheckBox annotationBox = new JCheckBox("JPA Annotation");
92 | private JCheckBox useActualColumnNamesBox = new JCheckBox("Actual-Column");
93 | private JCheckBox useTableNameAliasBox = new JCheckBox("Use-Alias");
94 | private JCheckBox useExampleBox = new JCheckBox("Use Example");
95 | private JCheckBox mysql8Box = new JCheckBox("MySQL 8");
96 | private JCheckBox lombokAnnotationBox = new JCheckBox("Lombok");
97 | private JCheckBox lombokBuilderAnnotationBox = new JCheckBox("Lombok Builder");
98 | private JCheckBox swaggerAnnotationBox = new JCheckBox("Swagger Model");
99 | private JBTabbedPane tabpanel = new JBTabbedPane();
100 |
101 |
102 | public GenerateSettingUI(AnActionEvent anActionEvent) {
103 | super(anActionEvent.getData(PlatformDataKeys.PROJECT));
104 | Project project = anActionEvent.getData(PlatformDataKeys.PROJECT);
105 | this.anActionEvent = anActionEvent;
106 | this.project = anActionEvent.getData(PlatformDataKeys.PROJECT);
107 | this.myBatisGeneratorConfiguration = MyBatisGeneratorConfiguration.getInstance(project);
108 | this.psiElements = anActionEvent.getData(LangDataKeys.PSI_ELEMENT_ARRAY);
109 |
110 | GlobalConfig globalConfig = myBatisGeneratorConfiguration.getGlobalConfig();
111 | Map historyConfigList = myBatisGeneratorConfiguration.getTableConfigs();
112 |
113 | setTitle("MyBatis Generator Plus");
114 | //设置大小
115 | pack();
116 | setModal(true);
117 |
118 | PsiElement psiElement = psiElements[0];
119 | TableInfo tableInfo = new TableInfo((DbTable) psiElement);
120 | String tableName = tableInfo.getTableName();
121 | String realTableName;
122 | if (globalConfig.getTablePrefix() != null && tableName.startsWith(globalConfig.getTablePrefix())) {
123 | realTableName = tableName.substring(globalConfig.getTablePrefix().length());
124 | } else {
125 | realTableName = tableName;
126 | }
127 | String entityName = StringUtils.dbStringToCamelStyle(realTableName);
128 | String primaryKey = "";
129 | if (tableInfo.getPrimaryKeys().size() > 0) {
130 | primaryKey = tableInfo.getPrimaryKeys().get(0);
131 | }
132 |
133 | //单表时,优先使用已经存在的配置
134 | if (historyConfigList != null) {
135 | tableConfig = historyConfigList.get(tableName);
136 | }
137 | if (tableConfig == null) {
138 | //初始化配置
139 | tableConfig = new TableConfig();
140 | tableConfig.setModuleRootPath(globalConfig.getModuleRootPath());
141 | tableConfig.setSourcePath(globalConfig.getSourcePath());
142 | tableConfig.setResourcePath(globalConfig.getResourcePath());
143 | tableConfig.setDomainPackage(globalConfig.getDomainPackage());
144 | tableConfig.setMapperPackage(globalConfig.getMapperPackage());
145 | tableConfig.setMapperPostfix(globalConfig.getMapperPostfix());
146 | tableConfig.setExamplePostfix(globalConfig.getExamplePostfix());
147 | tableConfig.setExamplePackage(globalConfig.getExamplePackage());
148 | tableConfig.setXmlPackage(globalConfig.getXmlPackage());
149 |
150 | tableConfig.setOffsetLimit(globalConfig.isOffsetLimit());
151 | tableConfig.setComment(globalConfig.isComment());
152 | tableConfig.setOverride(globalConfig.isOverride());
153 | tableConfig.setNeedToStringHashcodeEquals(globalConfig.isNeedToStringHashcodeEquals());
154 | tableConfig.setUseSchemaPrefix(globalConfig.isUseSchemaPrefix());
155 | tableConfig.setNeedForUpdate(globalConfig.isNeedForUpdate());
156 | tableConfig.setAnnotationDAO(globalConfig.isAnnotationDAO());
157 | tableConfig.setUseDAOExtendStyle(globalConfig.isUseDAOExtendStyle());
158 | tableConfig.setJsr310Support(globalConfig.isJsr310Support());
159 | tableConfig.setAnnotation(globalConfig.isAnnotation());
160 | tableConfig.setUseActualColumnNames(globalConfig.isUseActualColumnNames());
161 | tableConfig.setUseTableNameAlias(globalConfig.isUseTableNameAlias());
162 | tableConfig.setUseExample(globalConfig.isUseExample());
163 | tableConfig.setMysql8(globalConfig.isMysql8());
164 | tableConfig.setLombokAnnotation(globalConfig.isLombokAnnotation());
165 | tableConfig.setLombokBuilderAnnotation(globalConfig.isLombokBuilderAnnotation());
166 | tableConfig.setSwaggerAnnotation(globalConfig.isSwaggerAnnotation());
167 | tableConfig.setPrimaryKey(primaryKey);
168 | }
169 | VerticalFlowLayout layoutManager = new VerticalFlowLayout(VerticalFlowLayout.TOP);
170 | layoutManager.setHgap(0);
171 | layoutManager.setVgap(0);
172 | contentPane.setLayout(layoutManager);
173 | this.initHeader(tableName, primaryKey);
174 | this.initGeneralPanel(entityName);
175 | this.initOptionsPanel();
176 | tabpanel.add(new ColumnTablePanel(tableConfig, tableInfo));
177 | contentPane.add(tabpanel);
178 | tabpanel.setUI(new GenerateSettingTabUI());
179 | contentPane.setBorder(JBUI.Borders.empty());
180 | this.init();
181 | }
182 |
183 | @NotNull
184 | @Override
185 | protected DialogStyle getStyle() {
186 | return DialogStyle.COMPACT;
187 | }
188 |
189 | private List validateSetting() {
190 | List errors = new ArrayList<>();
191 |
192 | if (StringUtils.isEmpty(moduleRootField.getText())) {
193 | errors.add("Module root must not be null");
194 | }
195 |
196 | if (StringUtils.isEmpty(domainNameField.getText())) {
197 | errors.add("Domain name must not be null");
198 | }
199 |
200 | if (StringUtils.isEmpty(mapperNameField.getText())) {
201 | errors.add("Mapper name must not be null");
202 | }
203 |
204 | if (StringUtils.isEmpty(domainPackageField.getText())) {
205 | errors.add("Domain package must not be null");
206 | }
207 |
208 | if (StringUtils.isEmpty(mapperPackageField.getText())) {
209 | errors.add("Mapper package must not be null");
210 | }
211 |
212 | if (StringUtils.isEmpty(xmlPackageField.getText())) {
213 | errors.add("Mapper xml package must not be null");
214 | }
215 |
216 | if (useExampleBox.getSelectedObjects() != null) {
217 | if (StringUtils.isEmpty(exampleNameField.getText())) {
218 | errors.add("Example name must not be null");
219 | }
220 | if (StringUtils.isEmpty(examplePackageField.getText())) {
221 | errors.add("Example package must not be null");
222 | }
223 | }
224 | return errors;
225 | }
226 |
227 | @Override
228 | protected void doOKAction() {
229 |
230 | List errors = this.validateSetting();
231 | if (!errors.isEmpty()) {
232 | Messages.showMessageDialog("Invalid setting: \n" + String.join("\n", errors), "Mybatis Generator Plus", Messages.getWarningIcon());
233 | return;
234 | }
235 |
236 | DbDataSource dbDataSource = null;
237 | PsiElement current = psiElements[0];
238 | while (current != null) {
239 | if (DbDataSource.class.isAssignableFrom(current.getClass())) {
240 | dbDataSource = (DbDataSource) current;
241 | break;
242 | }
243 | current = current.getParent();
244 | }
245 |
246 | if (dbDataSource == null) {
247 | Messages.showMessageDialog(project, "Cannot get datasource", "Mybatis Generator Plus", Messages.getErrorIcon());
248 | return;
249 | }
250 |
251 | RawConnectionConfig connectionConfig = dbDataSource.getConnectionConfig();
252 |
253 | if (connectionConfig == null) {
254 | Messages.showMessageDialog(project, "Cannot get connection config", "Mybatis Generator Plus", Messages.getErrorIcon());
255 | return;
256 | }
257 |
258 | Map credentials = myBatisGeneratorConfiguration.getCredentials();
259 | Credential credential;
260 | if (credentials == null || !credentials.containsKey(connectionConfig.getUrl())) {
261 | boolean result = getDatabaseCredential(connectionConfig);
262 | if (result) {
263 | credentials = myBatisGeneratorConfiguration.getCredentials();
264 | credential = credentials.get(connectionConfig.getUrl());
265 | } else {
266 | return;
267 | }
268 | } else {
269 | credential = credentials.get(connectionConfig.getUrl());
270 | }
271 | Callable callable = new Callable() {
272 | @Override
273 | public Exception call() {
274 | String url = connectionConfig.getUrl();
275 | CredentialAttributes credentialAttributes = new CredentialAttributes(PluginContants.PLUGIN_NAME + "-" + url, credential.getUsername(), this.getClass(), false);
276 | String password = PasswordSafe.getInstance().getPassword(credentialAttributes);
277 | try {
278 | DatabaseUtils.testConnection(connectionConfig.getDriverClass(), connectionConfig.getUrl(), credential.getUsername(), password, mysql8Box.getSelectedObjects() != null);
279 | } catch (ClassNotFoundException | SQLException e) {
280 | return e;
281 | }
282 | return null;
283 | }
284 | };
285 | FutureTask future = new FutureTask<>(callable);
286 | ProgressManager.getInstance().runProcessWithProgressSynchronously(future, "Connect to Database", true, project);
287 | Exception exception;
288 | try {
289 | exception = future.get();
290 | } catch (InterruptedException | ExecutionException e) {
291 | Messages.showMessageDialog(project, "Failed to connect to database \n " + e.getMessage(), "Mybatis Generator Plus", Messages.getErrorIcon());
292 | return;
293 | }
294 | if (exception != null) {
295 | Messages.showMessageDialog(project, "Failed to connect to database \n " + exception.getMessage(), "Mybatis Generator Plus", Messages.getErrorIcon());
296 | if (exception.getClass().equals(SQLException.class)) {
297 | SQLException sqlException = (SQLException) exception;
298 | if (sqlException.getErrorCode() == 1045) {
299 | boolean result = getDatabaseCredential(connectionConfig);
300 | if (result) {
301 | this.doOKAction();
302 | return;
303 | }
304 | }
305 | }
306 | return;
307 | }
308 |
309 | if (overrideBox.getSelectedObjects() != null) {
310 | int confirm = Messages.showOkCancelDialog(project, "The exists file will be overwrite ,Confirm generate?", "Mybatis Generator Plus", Messages.getQuestionIcon());
311 | if (confirm == 2) {
312 | return;
313 | }
314 | } else {
315 | int confirm = Messages.showOkCancelDialog(project, "Confirm generate mybatis code?", "Mybatis Generator Plus", Messages.getQuestionIcon());
316 | if (confirm == 2) {
317 | return;
318 | }
319 | }
320 |
321 | super.doOKAction();
322 |
323 | this.generate(connectionConfig);
324 |
325 | }
326 |
327 | private boolean testConnection(RawConnectionConfig connectionConfig, Credential credential) {
328 | String url = connectionConfig.getUrl();
329 | CredentialAttributes credentialAttributes = new CredentialAttributes(PluginContants.PLUGIN_NAME + "-" + url, credential.getUsername(), this.getClass(), false);
330 | String password = PasswordSafe.getInstance().getPassword(credentialAttributes);
331 | try {
332 | DatabaseUtils.testConnection(connectionConfig.getDriverClass(), connectionConfig.getUrl(), credential.getUsername(), password, mysql8Box.getSelectedObjects() != null);
333 | return true;
334 | } catch (ClassNotFoundException e) {
335 | Messages.showMessageDialog(project, "Failed to connect to database \n " + e.getMessage(), "Mybatis Generator Plus", Messages.getErrorIcon());
336 | e.printStackTrace();
337 | return false;
338 | } catch (SQLException e) {
339 | Messages.showMessageDialog(project, "Failed to connect to database \n " + e.getMessage(), "Mybatis Generator Plus", Messages.getErrorIcon());
340 | if (e.getErrorCode() == 1045) {
341 | boolean result = getDatabaseCredential(connectionConfig);
342 | if (result) {
343 | Map credentials = myBatisGeneratorConfiguration.getCredentials();
344 | return testConnection(connectionConfig, credentials.get(connectionConfig.getUrl()));
345 | } else {
346 | return false;
347 | }
348 | } else {
349 | return false;
350 | }
351 | }
352 | }
353 |
354 | private boolean getDatabaseCredential(RawConnectionConfig connectionConfig) {
355 | DatabaseCredentialUI databaseCredentialUI = new DatabaseCredentialUI(anActionEvent.getProject(), connectionConfig.getUrl());
356 | return databaseCredentialUI.showAndGet();
357 | }
358 |
359 | private void initOptionsPanel() {
360 | JBPanel optionsPanel = new JBPanel(new GridLayout(8, 4, 10, 10));
361 | optionsPanel.add(offsetLimitBox);
362 | optionsPanel.add(commentBox);
363 | optionsPanel.add(overrideBox);
364 | optionsPanel.add(needToStringHashcodeEqualsBox);
365 | optionsPanel.add(useSchemaPrefixBox);
366 | optionsPanel.add(needForUpdateBox);
367 | optionsPanel.add(annotationDAOBox);
368 | optionsPanel.add(useDAOExtendStyleBox);
369 | optionsPanel.add(jsr310SupportBox);
370 | optionsPanel.add(annotationBox);
371 | optionsPanel.add(useActualColumnNamesBox);
372 | optionsPanel.add(useTableNameAliasBox);
373 | optionsPanel.add(useExampleBox);
374 | optionsPanel.add(mysql8Box);
375 | optionsPanel.add(lombokAnnotationBox);
376 | optionsPanel.add(lombokBuilderAnnotationBox);
377 | optionsPanel.add(swaggerAnnotationBox);
378 |
379 | useExampleBox.addChangeListener(e -> {
380 | exampleNamePanel.setVisible(useExampleBox.getSelectedObjects() != null);
381 | examplePackagePanel.setVisible(useExampleBox.getSelectedObjects() != null);
382 | });
383 |
384 | offsetLimitBox.setSelected(tableConfig.isOffsetLimit());
385 | commentBox.setSelected(tableConfig.isComment());
386 | overrideBox.setSelected(tableConfig.isOverride());
387 | needToStringHashcodeEqualsBox.setSelected(tableConfig.isNeedToStringHashcodeEquals());
388 | useSchemaPrefixBox.setSelected(tableConfig.isUseSchemaPrefix());
389 | needForUpdateBox.setSelected(tableConfig.isNeedForUpdate());
390 | annotationDAOBox.setSelected(tableConfig.isAnnotationDAO());
391 | useDAOExtendStyleBox.setSelected(tableConfig.isUseDAOExtendStyle());
392 | jsr310SupportBox.setSelected(tableConfig.isJsr310Support());
393 | annotationBox.setSelected(tableConfig.isAnnotation());
394 | useActualColumnNamesBox.setSelected(tableConfig.isUseActualColumnNames());
395 | useTableNameAliasBox.setSelected(tableConfig.isUseTableNameAlias());
396 | useExampleBox.setSelected(tableConfig.isUseExample());
397 | mysql8Box.setSelected(tableConfig.isMysql8());
398 | lombokAnnotationBox.setSelected(tableConfig.isLombokAnnotation());
399 | lombokBuilderAnnotationBox.setSelected(tableConfig.isLombokBuilderAnnotation());
400 | swaggerAnnotationBox.setSelected(tableConfig.isSwaggerAnnotation());
401 | optionsPanel.setName("Options");
402 | tabpanel.add(optionsPanel);
403 | }
404 |
405 | /**
406 | * 初始化Package组件
407 | */
408 | private void initHeader(String tableName, String primaryKey) {
409 | JPanel headerPanel = new JBPanel<>();
410 | headerPanel.setBorder(JBUI.Borders.empty(0, 5));
411 | VerticalFlowLayout layout = new VerticalFlowLayout(VerticalFlowLayout.TOP);
412 | layout.setVgap(0);
413 | headerPanel.setLayout(layout);
414 | JPanel moduleRootPanel = new JPanel();
415 | moduleRootPanel.setLayout(new BoxLayout(moduleRootPanel, BoxLayout.X_AXIS));
416 | JBLabel projectRootLabel = new JBLabel("Module Root:");
417 | projectRootLabel.setPreferredSize(new Dimension(150, 10));
418 | moduleRootField.addBrowseFolderListener(new TextBrowseFolderListener(FileChooserDescriptorFactory.createSingleFolderDescriptor()) {
419 | @Override
420 | public void actionPerformed(ActionEvent e) {
421 | super.actionPerformed(e);
422 | moduleRootField.setText(moduleRootField.getText().replaceAll("\\\\", "/"));
423 | }
424 | });
425 | if (tableConfig != null && !StringUtils.isEmpty(tableConfig.getModuleRootPath())) {
426 | moduleRootField.setText(tableConfig.getModuleRootPath());
427 | } else {
428 | moduleRootField.setText(project.getBasePath());
429 | }
430 | moduleRootPanel.add(projectRootLabel);
431 | moduleRootPanel.add(moduleRootField);
432 |
433 | //Table
434 | JPanel tableNamePanel = new JPanel();
435 | tableNamePanel.setLayout(new BoxLayout(tableNamePanel, BoxLayout.X_AXIS));
436 | JLabel tableLabel = new JLabel("Table Name:");
437 | tableLabel.setLabelFor(tableNameField);
438 | tableLabel.setPreferredSize(new Dimension(150, 10));
439 | tableNamePanel.add(tableLabel);
440 | tableNamePanel.add(tableNameField);
441 |
442 | if (psiElements.length > 1) {
443 | tableNameField.addFocusListener(new JTextFieldHintListener(tableNameField, "eg:db_table"));
444 | } else {
445 | tableNameField.setText(tableName);
446 | }
447 | tableNameField.setEditable(false);
448 | tableNameField.addKeyListener(new KeyAdapter() {
449 | @Override
450 | public void keyReleased(KeyEvent e) {
451 | String entityName = StringUtils.dbStringToCamelStyle(tableNameField.getText());
452 | domainNameField.setText(entityName);
453 | mapperNameField.setText(getMapperName(entityName));
454 | exampleNameField.setText(getExampleName(entityName));
455 | }
456 | });
457 |
458 | JPanel primaryPanel = new JPanel();
459 | primaryPanel.setLayout(new BoxLayout(primaryPanel, BoxLayout.X_AXIS));
460 | JLabel primaryKeyLabel = new JLabel(" Primary Key:");
461 | primaryKeyLabel.setLabelFor(primaryKeyField);
462 | primaryKeyLabel.setPreferredSize(new Dimension(150, 10));
463 | tableNamePanel.add(primaryKeyLabel);
464 | tableNamePanel.add(primaryKeyField);
465 |
466 | primaryKeyField.setText(primaryKey);
467 | primaryKeyField.setEditable(false);
468 | headerPanel.add(moduleRootPanel);
469 | headerPanel.add(tableNamePanel);
470 | headerPanel.add(primaryPanel);
471 | contentPane.add(headerPanel);
472 | }
473 |
474 | private void initGeneralPanel(String modelName) {
475 | JPanel domainNamePanel = new JPanel();
476 | domainNamePanel.setLayout(new BoxLayout(domainNamePanel, BoxLayout.X_AXIS));
477 | JLabel entityNameLabel = new JLabel("Domain Name:");
478 | entityNameLabel.setPreferredSize(new Dimension(150, 10));
479 | domainNamePanel.add(entityNameLabel);
480 | domainNamePanel.add(domainNameField);
481 | if (psiElements.length > 1) {
482 | domainNameField.addFocusListener(new JTextFieldHintListener(domainNameField, "eg:DbTable"));
483 | } else {
484 | domainNameField.setText(modelName);
485 | }
486 | domainNameField.addKeyListener(new KeyAdapter() {
487 | @Override
488 | public void keyReleased(KeyEvent e) {
489 | mapperNameField.setText(getMapperName(domainNameField.getText()));
490 | exampleNameField.setText(getExampleName(domainNameField.getText()));
491 | }
492 | });
493 |
494 | //MapperName
495 | JPanel mapperNamePanel = new JPanel();
496 | mapperNamePanel.setLayout(new BoxLayout(mapperNamePanel, BoxLayout.X_AXIS));
497 | JLabel mapperNameLabel = new JLabel("Mapper Name:");
498 | mapperNameLabel.setPreferredSize(new Dimension(150, 10));
499 | mapperNameLabel.setLabelFor(domainNameField);
500 | mapperNamePanel.add(mapperNameLabel);
501 | mapperNamePanel.add(mapperNameField);
502 | if (psiElements.length > 1) {
503 | if (tableConfig != null && !StringUtils.isEmpty(tableConfig.getMapperPostfix())) {
504 | mapperNameField.addFocusListener(new JTextFieldHintListener(mapperNameField, "eg:DbTable" + tableConfig.getMapperPostfix()));
505 | } else {
506 | mapperNameField.addFocusListener(new JTextFieldHintListener(mapperNameField, "eg:DbTable" + "Mapper"));
507 | }
508 | } else {
509 | mapperNameField.setText(getMapperName(modelName));
510 | }
511 |
512 | exampleNamePanel.setLayout(new BoxLayout(exampleNamePanel, BoxLayout.X_AXIS));
513 | JLabel exampleNameLabel = new JLabel("Example Name:");
514 | exampleNameLabel.setPreferredSize(new Dimension(150, 10));
515 | exampleNameLabel.setLabelFor(domainNameField);
516 | exampleNamePanel.add(exampleNameLabel);
517 | exampleNamePanel.add(exampleNameField);
518 | if (psiElements.length > 1) {
519 | if (tableConfig != null && !StringUtils.isEmpty(tableConfig.getExamplePostfix())) {
520 | exampleNameField.addFocusListener(new JTextFieldHintListener(exampleNameField, "eg:DbTable" + tableConfig.getExamplePostfix()));
521 | } else {
522 | exampleNameField.addFocusListener(new JTextFieldHintListener(exampleNameField, "eg:DbTable" + "Example"));
523 | }
524 | } else {
525 | exampleNameField.setText(getExampleName(modelName));
526 | }
527 |
528 | exampleNamePanel.setVisible(tableConfig.isUseExample());
529 |
530 |
531 | JPanel basePackagePanel = new JPanel();
532 | basePackagePanel.setLayout(new BoxLayout(basePackagePanel, BoxLayout.X_AXIS));
533 | JBLabel basePackageLabel = new JBLabel("Base Package:");
534 | basePackageLabel.setPreferredSize(new Dimension(150, 10));
535 | basePackageField = new EditorTextFieldWithBrowseButton(project, false);
536 | basePackageField.addActionListener(e -> {
537 | final PackageChooserDialog chooser = new PackageChooserDialog("Select Base Package", project);
538 | chooser.selectPackage(basePackageField.getText());
539 | chooser.show();
540 | final PsiPackage psiPackage = chooser.getSelectedPackage();
541 | String packageName = psiPackage == null ? null : psiPackage.getQualifiedName();
542 | if (!StringUtils.isEmpty(packageName)) {
543 | basePackageField.setText(packageName);
544 | domainPackageField.setText(packageName + ".domain");
545 | mapperPackageField.setText(packageName + "." + getMapperPostfix().toLowerCase());
546 | examplePackageField.setText(packageName + "." + getExamplePostfix().toLowerCase());
547 | }
548 | });
549 | basePackageField.addKeyListener(new KeyAdapter() {
550 | @Override
551 | public void keyReleased(KeyEvent e) {
552 | domainPackageField.setText(basePackageField.getText() + ".domain");
553 | mapperPackageField.setText(basePackageField.getText() + "." + getMapperPostfix().toLowerCase());
554 | examplePackageField.setText(basePackageField.getText() + "." + getExamplePostfix().toLowerCase());
555 | }
556 | });
557 | if (tableConfig != null && !StringUtils.isEmpty(tableConfig.getBasePackage())) {
558 | basePackageField.setText(tableConfig.getBasePackage());
559 | } else {
560 | basePackageField.setText("");
561 | }
562 | basePackagePanel.add(basePackageLabel);
563 | basePackagePanel.add(basePackageField);
564 |
565 | this.domainPackageField = new EditorTextFieldWithBrowseButton(project, false);
566 |
567 |
568 | JPanel entityPackagePanel = new JPanel();
569 | entityPackagePanel.setLayout(new BoxLayout(entityPackagePanel, BoxLayout.X_AXIS));
570 | JBLabel entityPackageLabel = new JBLabel("Domain Package:");
571 | entityPackageLabel.setPreferredSize(new Dimension(150, 10));
572 | domainPackageField.addActionListener(e -> {
573 | final PackageChooserDialog chooser = new PackageChooserDialog("Select Entity Package", project);
574 | chooser.selectPackage(domainPackageField.getText());
575 | chooser.show();
576 | final PsiPackage psiPackage = chooser.getSelectedPackage();
577 | String packageName = psiPackage == null ? null : psiPackage.getQualifiedName();
578 | if (!StringUtils.isEmpty(packageName)) {
579 | domainPackageField.setText(packageName);
580 | }
581 | });
582 | if (tableConfig != null && !StringUtils.isEmpty(tableConfig.getDomainPackage())) {
583 | domainPackageField.setText(tableConfig.getDomainPackage());
584 | } else {
585 | domainPackageField.setText("");
586 | }
587 | entityPackagePanel.add(entityPackageLabel);
588 | entityPackagePanel.add(domainPackageField);
589 |
590 | JPanel mapperPackagePanel = new JPanel();
591 | mapperPackagePanel.setLayout(new BoxLayout(mapperPackagePanel, BoxLayout.X_AXIS));
592 | JLabel mapperPackageLabel = new JLabel("Mapper Package:");
593 | mapperPackageLabel.setPreferredSize(new Dimension(150, 10));
594 | mapperPackageField = new EditorTextFieldWithBrowseButton(project, false);
595 | mapperPackageField.addActionListener(event -> {
596 | final PackageChooserDialog packageChooserDialog = new PackageChooserDialog("Select Mapper Package", project);
597 | packageChooserDialog.selectPackage(mapperPackageField.getText());
598 | packageChooserDialog.show();
599 |
600 | final PsiPackage psiPackage = packageChooserDialog.getSelectedPackage();
601 | String packageName = psiPackage == null ? null : psiPackage.getQualifiedName();
602 | if (!StringUtils.isEmpty(packageName)) {
603 | mapperPackageField.setText(packageName);
604 | }
605 | });
606 | if (tableConfig != null && !StringUtils.isEmpty(tableConfig.getMapperPackage())) {
607 | mapperPackageField.setText(tableConfig.getMapperPackage());
608 | } else {
609 | mapperPackageField.setText("");
610 | }
611 | mapperPackagePanel.add(mapperPackageLabel);
612 | mapperPackagePanel.add(mapperPackageField);
613 |
614 | examplePackagePanel.setLayout(new BoxLayout(examplePackagePanel, BoxLayout.X_AXIS));
615 |
616 | examplePackageField = new EditorTextFieldWithBrowseButton(project, false);
617 | examplePackageField.addActionListener(e -> {
618 | final PackageChooserDialog packageChooserDialog = new PackageChooserDialog("Select Example Package", project);
619 | packageChooserDialog.selectPackage(examplePackageField.getText());
620 | packageChooserDialog.show();
621 |
622 | final PsiPackage psiPackage = packageChooserDialog.getSelectedPackage();
623 | String packageName = psiPackage == null ? null : psiPackage.getQualifiedName();
624 | if (!StringUtils.isEmpty(packageName)) {
625 | examplePackageField.setText(packageName);
626 | }
627 | });
628 |
629 | JLabel examplePackageLabel = new JLabel("Example Package:");
630 | examplePackageLabel.setPreferredSize(new Dimension(150, 10));
631 | examplePackageField.setText(tableConfig.getExamplePackage());
632 | examplePackagePanel.add(examplePackageLabel);
633 | examplePackagePanel.add(examplePackageField);
634 | examplePackagePanel.setVisible(tableConfig.isUseExample());
635 |
636 | JPanel xmlPackagePanel = new JPanel();
637 | xmlPackagePanel.setLayout(new BoxLayout(xmlPackagePanel, BoxLayout.X_AXIS));
638 | JLabel xmlPackageLabel = new JLabel("Xml Package:");
639 | xmlPackageLabel.setPreferredSize(new Dimension(150, 10));
640 | xmlPackageField.setText(tableConfig.getXmlPackage());
641 | xmlPackagePanel.add(xmlPackageLabel);
642 | xmlPackagePanel.add(xmlPackageField);
643 |
644 | JPanel generalPanel = new JPanel();
645 | generalPanel.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP));
646 | generalPanel.add(new TitledSeparator("Domain"));
647 |
648 | JPanel domainPanel = new JPanel();
649 | domainPanel.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP));
650 |
651 | domainPanel.add(domainNamePanel);
652 | domainPanel.add(mapperNamePanel);
653 | domainPanel.add(exampleNamePanel);
654 | generalPanel.add(domainPanel);
655 |
656 | generalPanel.add(new TitledSeparator("Package"));
657 |
658 | JPanel packagePanel = new JPanel();
659 | packagePanel.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP));
660 |
661 | packagePanel.add(basePackagePanel);
662 | packagePanel.add(entityPackagePanel);
663 | packagePanel.add(mapperPackagePanel);
664 | packagePanel.add(examplePackagePanel);
665 | packagePanel.add(xmlPackagePanel);
666 | generalPanel.add(packagePanel);
667 | generalPanel.setName("General");
668 | tabpanel.add(generalPanel);
669 | }
670 |
671 | public void generate(RawConnectionConfig connectionConfig) {
672 | tableConfig.setName(tableNameField.getText());
673 | tableConfig.setTableName(tableNameField.getText());
674 | tableConfig.setModuleRootPath(moduleRootField.getText());
675 |
676 | tableConfig.setBasePackage(basePackageField.getText());
677 | tableConfig.setDomainPackage(domainPackageField.getText());
678 | tableConfig.setMapperPackage(mapperPackageField.getText());
679 | tableConfig.setExamplePackage(examplePackageField.getText());
680 | tableConfig.setXmlPackage(xmlPackageField.getText());
681 |
682 | tableConfig.setMapperName(mapperNameField.getText());
683 | tableConfig.setDomainName(domainNameField.getText());
684 | tableConfig.setPrimaryKey(primaryKeyField.getText());
685 | tableConfig.setExampleName(exampleNameField.getText());
686 |
687 | tableConfig.setOffsetLimit(offsetLimitBox.getSelectedObjects() != null);
688 | tableConfig.setComment(commentBox.getSelectedObjects() != null);
689 | tableConfig.setOverride(overrideBox.getSelectedObjects() != null);
690 | tableConfig.setNeedToStringHashcodeEquals(needToStringHashcodeEqualsBox.getSelectedObjects() != null);
691 | tableConfig.setUseSchemaPrefix(useSchemaPrefixBox.getSelectedObjects() != null);
692 | tableConfig.setNeedForUpdate(needForUpdateBox.getSelectedObjects() != null);
693 | tableConfig.setAnnotationDAO(annotationDAOBox.getSelectedObjects() != null);
694 | tableConfig.setUseDAOExtendStyle(useDAOExtendStyleBox.getSelectedObjects() != null);
695 | tableConfig.setJsr310Support(jsr310SupportBox.getSelectedObjects() != null);
696 | tableConfig.setAnnotation(annotationBox.getSelectedObjects() != null);
697 | tableConfig.setUseActualColumnNames(useActualColumnNamesBox.getSelectedObjects() != null);
698 | tableConfig.setUseTableNameAlias(useTableNameAliasBox.getSelectedObjects() != null);
699 | tableConfig.setUseExample(useExampleBox.getSelectedObjects() != null);
700 | tableConfig.setMysql8(mysql8Box.getSelectedObjects() != null);
701 | tableConfig.setLombokAnnotation(lombokAnnotationBox.getSelectedObjects() != null);
702 | tableConfig.setLombokBuilderAnnotation(lombokBuilderAnnotationBox.getSelectedObjects() != null);
703 | tableConfig.setSwaggerAnnotation(swaggerAnnotationBox.getSelectedObjects() != null);
704 | tableConfig.setSourcePath(this.tableConfig.getSourcePath());
705 | tableConfig.setResourcePath(this.tableConfig.getResourcePath());
706 |
707 | new MyBatisGenerateCommand(tableConfig).execute(project, connectionConfig);
708 |
709 | }
710 |
711 | private String getMapperName(String entityName) {
712 | if (tableConfig != null && !StringUtils.isEmpty(tableConfig.getMapperPostfix())) {
713 | return entityName + tableConfig.getMapperPostfix();
714 | } else {
715 | return (entityName + "Mapper");
716 | }
717 | }
718 |
719 | private String getMapperPostfix() {
720 | if (tableConfig != null && !StringUtils.isEmpty(tableConfig.getMapperPostfix())) {
721 | return tableConfig.getMapperPostfix();
722 | } else {
723 | return "Mapper";
724 | }
725 | }
726 |
727 | private String getExamplePostfix() {
728 | if (tableConfig != null && !StringUtils.isEmpty(tableConfig.getExamplePostfix())) {
729 | return tableConfig.getExamplePostfix();
730 | } else {
731 | return "Example";
732 | }
733 | }
734 |
735 | private String getExampleName(String entityName) {
736 | if (tableConfig != null && !StringUtils.isEmpty(tableConfig.getExamplePostfix())) {
737 | return entityName + tableConfig.getExamplePostfix();
738 | } else {
739 | return (entityName + "Example");
740 | }
741 | }
742 |
743 | @Nullable
744 | @Override
745 | protected JComponent createCenterPanel() {
746 | return contentPane;
747 | }
748 | }
749 |
--------------------------------------------------------------------------------