Author: Xiao Fu Ge
Blog: https://bugstack.cn
Source code: https://github.com/fuzhengwei/CodeGuide/wiki
Precipitate, share, grow, so that you and others can gain something! 😄
I. Introduction
can be used, can make use of it!
There are several sets of one thing, all for promotion. If you get the result, you have to run, and then the brothers will remake it!
A few years ago, this was not the case for everyone. At that time, there were still many things that could be innovated. Heroes in troubled times could always cultivate in one direction and make a useful product function, framework service, technical component, etc. But then it seemed that this situation began to decrease, and replaced by repetition, re-engraving, copying, changing to a new skin, a new style, and a new name, which are new tricks.
Sometimes a company or organization is like a home, but the things in the home are usually broken and repaired, broken and repaired. If it doesn't work, change it. But no one has one toilet in the bathroom, one toilet in the kitchen, one toilet in the living room, and one toilet in the bedroom. Yes, although your new toilet can automatically spray water.
Therefore, when building a good product function, you should learn as much as possible from the already excellent products, such as IDEA, GitHub, Mysql, etc. IDEA provides plug-in development that meets the user's extended functions, instead of just saying something. I don't have one, you just make it yourself. construction of 161b15c2cf2639 will make this thing even better!
2. Demand Purpose
In the previous chapter, we extended the creation project wizard, added the steps we need to create the DDD project scaffolding, and finally provided a DDD development framework. Then, in this DDD project development framework, there is still a lack of functions that automatically generate corresponding PO, DAO, and Mapper files based on database table information.
- Then in this chapter, we will expand this part of the project. The effect of the actual operation is that we can use the right mouse button on the project to call up the form for adding ORM code blocks, and use freemarker to automatically select the library table. Generate code.
- In the generated code block, it is necessary to complete the introduction of the required packages, and at the same time, the lombok annotation method will be used to replace the get and set methods in the PO object to reduce the amount of code and the creation of logic.
3. Case development
1. Engineering structure
guide-idea-plugin-orm
├── .gradle
└── src
├── main
│ └── java
│ └── cn.bugstack.guide.idea.plugin
│ ├── action
│ │ └── CodeGenerateAction.java
│ ├── domain
│ │ ├── model.vo
│ │ │ ├── CodeGenContextVO.java
│ │ │ └── ORMConfigVO.java
│ │ └── service
│ │ ├── impl
│ │ │ └── ProjectGeneratorImpl.java
│ │ ├── AbstractProjectGenerator.java
│ │ ├── GeneratorConfig.java
│ │ └── IProjectGenerator.java
│ ├── infrastructure
│ │ ├── data
│ │ │ ├── DataSetting.java
│ │ │ └── DataState.java
│ │ ├── po
│ │ │ ├── Base.java
│ │ │ ├── Column.java
│ │ │ ├── Dao.java
│ │ │ ├── Field.java
│ │ │ ├── Model.java
│ │ │ └── Table.java
│ │ └── utils
│ │ ├── DBHelper.java
│ │ └── JavaType.java
│ ├── module
│ │ └── FileChooserComponent.java
│ └── ui
│ ├── ORMSettingsUI.java
│ └── ORMSettingsUI.form
├── resources
│ ├── META-INF
│ │ └── plugin.xml
│ └── template
│ ├── dao.ftl
│ ├── mapper.ftl
│ └── model.ftl
├── build.gradle
└── gradle.properties
source code acquisition : #public number: bugstack wormhole stack reply:
idea
can download all IDEA plug-in development source code# Chapter 5: Right-click in the development project to generate ORM code
In this IDEA plug-in project, it is mainly divided into 5 areas:
- action: used to provide the menu bar. The position of this menu is configured in plugin.xml, and we configure it to the list that appears on the right mouse button of the project. This makes it more convenient for us to select the project, and add the generated code snippet
- Domain: Domain service layer. In fact, you can write a Service package directly, but recently the author Xiao Fu prefers to use the idea and structure of DDD to create code to implement functional logic.
- Infrastructure: The basic layer, which provides the storage of data under the project. Each project has its own configuration storage default information, so that this part of the content can be read when it is opened next time. At the same time, this layer also provides classes for processing database operations, because we need to read table information, fields, and comments from the database for use in creating PO, DAO, and Mapper.
- module: Module layer, here is a component used to select the file path, which allows us to click on the module to select the location path of the corresponding code to be generated in the window that comes out of the right mouse button on the project.
- ui: Provides a configuration panel, which is the panel that pops up from the right mouse button on the code project. After configuration, this panel is used to generate ORM code.
2. Drag and drop the Swing panel
ORMSettingsUI 161b15c2cf2936: Let's first create the panel used to create the code configuration. With the screen, it's
- The panel includes the code path for generating PO, DAO, XML, and the content of the configuration database and selection table.
- The operation process is that after you have configured these basic information, you can select the query table name, and choose which tables you want to generate the corresponding ORM code for.
3. Configure the right mouse button pop-up window
First we need to create an Action implementation class, through New -> Plugin DevKit -> Action
cn.bugstack.guide.idea.plugin.action.CodeGenerateAction
/**
* @author: 小傅哥,微信:fustack
* @github: https://github.com/fuzhengwei
* @Copyright: 公众号:bugstack虫洞栈 | 博客:https://bugstack.cn - 沉淀、分享、成长,让自己和他人都能有所收获!
*/
public class CodeGenerateAction extends AnAction {
private IProjectGenerator projectGenerator = new ProjectGeneratorImpl();
@Override
public void actionPerformed(AnActionEvent e) {
Project project = e.getRequiredData(CommonDataKeys.PROJECT);
ShowSettingsUtil.getInstance().editConfigurable(project, new ORMSettingsUI(project, projectGenerator));
}
}
- This is the entrance of a right-click menu, through which we can open our own UI form. This UI form is the configuration panel we dragged above, ORMSettingsUI
- Next, we need to configure this Action in the plugin.xml file before it can be created by the right-click menu. is the same process when developing code. You always have to start from a certain point.
plugin.xml configuration
<actions>
<!-- Add your actions here -->
<action id="CodeGenerateAction" class="cn.bugstack.guide.idea.plugin.action.CodeGenerateAction"
text="ORMCodeGenerate - 小傅哥" description="Code Generate ORM" icon="/icons/logo.png">
<add-to-group group-id="ProjectViewPopupMenu" anchor="last"/>
</action>
</actions>
ea-plugin>
- Configure our Action implementation class in xml, and you also need to configure where it should appear. For example, you need to add this menu to the project creation
ProjectViewPopupMenu
and location informationanchor="last"
- In addition, in order to make the plug-in look taller and more beautiful and suitable for bragging, you also need to configure the icon. This location is equipped with a
16*16
. The picture can be downloaded iconfont
4. Add functions to the form
What this step actually does is to inject the soul and make the form come alive. Add content to the input box, add events to the button, and add the context for generating the ORM code block to the confirmation button. article will be biased towards the explanation of the core code as much as possible. For details, please refer to the source code
The next part of the content will rub repeatedly until all functions are completed.
4.1 Select box event
// 选择PO生成目录
this.poButton.addActionListener(e -> {
FileChooserComponent component = FileChooserComponent.getInstance(project);
VirtualFile baseDir = project.getBaseDir();
VirtualFile virtualFile = component.showFolderSelectionDialog("选择PO生成目录", baseDir, baseDir);
if (null != virtualFile) {
ORMSettingsUI.this.poPath.setText(virtualFile.getPath());
}
});
- Remember the
drag-and-drop Swing panel we mentioned, then the step of adding an event is to add an event to your PO directory, allowing us to choose which directory structure to generate the corresponding PO code into.
- About dao and xml are similar operations, it is not demonstrated here.
4.2 Data table events
this.selectButton.addActionListener(e -> {
try {
DBHelper dbHelper = new DBHelper(this.host.getText(), Integer.parseInt(this.port.getText()), this.user.getText(), this.password.getText(), this.database.getText());
List<String> tableList = dbHelper.getAllTableName(this.database.getText());
String[] title = {"", "表名"};
Object[][] data = new Object[tableList.size()][2];
for (int i = 0; i < tableList.size(); i++) {
data[i][1] = tableList.get(i);
}
table1.setModel(new DefaultTableModel(data, title));
TableColumn tc = table1.getColumnModel().getColumn(0);
tc.setCellEditor(new DefaultCellEditor(new JCheckBox()));
tc.setCellEditor(table1.getDefaultEditor(Boolean.class));
tc.setCellRenderer(table1.getDefaultRenderer(Boolean.class));
tc.setMaxWidth(100);
} catch (Exception exception) {
Messages.showWarningDialog(project, "数据库连接错误,请检查配置.", "Warning");
}
});
- The core process of this step is to pull out the table of the code you need to generate ORM. As long as you select the table, you can generate PO, DAO, and Mapper according to the table. In fact, some other automatic code generation frameworks you use do the same. .
- In addition, it’s better to build tables with specifications, such as table comments, field comments, and field design to comply with underscores and lowercase letters. This will make it easier to create good-looking codes.
4.3 Assemble the generated code context
When we click the OK button in the configuration window, what do we need to do? Yes, we need to create a code snippet, so this time we need to complete this operation apply
public void apply() {
// 链接DB
DBHelper dbHelper = new DBHelper(config.getHost(), Integer.parseInt(config.getPort()), config.getUser(), config.getPassword(), config.getDatabase());
// 组装代码生产上下文
CodeGenContextVO codeGenContext = new CodeGenContextVO();
codeGenContext.setModelPackage(config.getPoPath() + "/po/");
codeGenContext.setDaoPackage(config.getDaoPath() + "/dao/");
codeGenContext.setMapperDir(config.getXmlPath() + "/mapper/");
List<Table> tables = new ArrayList<>();
Set<String> tableNames = config.getTableNames();
for (String tableName : tableNames) {
tables.add(dbHelper.getTable(tableName));
}
codeGenContext.setTables(tables);
// 生成代码
projectGenerator.generation(project, codeGenContext);
}
- The core code in apply is mainly to use the DBHelper data manipulation tool to obtain the link information under the corresponding library, and at the same time create the selected number table to generate the parameters of the code class, such as; class name, field name, comment name Wait.
- The last step is to call the service that generates the code.
projectGenerator.generation(project, codeGenContext);
is implemented in our domain service domain.
5. Code generation services
- The code used to create the code blocks of PO, DAO, and Mapper is mainly implemented here. The core is to provide an abstract class and corresponding implementation class. Because the freemarker is used to process code generation, it is wrapped in an abstract class. This can avoid the need to care about this part of the logic in the implementation class.
ProjectGeneratorImpl Generate code
@Override
protected void generateORM(Project project, CodeGenContextVO codeGenContext) {
List<Table> tables = codeGenContext.getTables();
for (Table table : tables) {
List<Column> columns = table.getColumns();
List<Field> fields = new ArrayList<>();
for (Column column : columns) {
Field field = new Field(column.getComment(), JavaType.convertType(column.getType()), column.getName());
field.setId(column.isId());
fields.add(field);
}
// 生成PO
Model model = new Model(table.getComment(), codeGenContext.getModelPackage() + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, table.getName()), table.getName(), fields);
writeFile(project, codeGenContext.getModelPackage(), model.getSimpleName() + ".java", "domain/orm/model.ftl", model);
// 生成DAO
Dao dao = new Dao(table.getComment(), codeGenContext.getDaoPackage() + "I" + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, table.getName()) + "Dao", model);
writeFile(project, codeGenContext.getDaoPackage(), dao.getSimpleName() + ".java", "domain/orm/dao.ftl", dao);
// 生成Mapper
writeFile(project, codeGenContext.getMapperDir(), dao.getModel().getSimpleName() + "Mapper.xml", "domain/orm/mapper.ftl", dao);
}
}
- The process of creating code is relatively simple. The table information extracted through the loop is mapped into the corresponding class, attribute and comment, and then the corresponding class and xml configuration file are created using the ftl file under resources.
- If you still need to generate code fragments or create and call some commonly used components, you can also achieve this in this way.
Four, test verification
- Click
Plugin
start the IDEA plug-in, and then right-click the project as follows:
1. Right mouse button, select menu
2. Configuration page, configuration information
3. Automatically create, generate code
- Well, the selection code block is created in such a whisper, is it very convenient, and it can satisfy you to add new library table codes at any time, reducing the CRUD operation by hand.
Five, summary
- In this chapter, Brother Xiaofu takes you to complete the ORM code generation step under the IDEA DDD plug-in generation project structure. Of course, you can also add the ORM code generation step in the Create Project Wizard. The way to create an ORM under the project can be regarded as a supplement to the scaffolding project to meet the needs of different scenarios.
- In addition, in the series of IDEA plug-in development, we are constantly trying to use new ways to improve different functions. If you need to develop a complete plug-in, you can combine these functions to develop your needs.
- There are still a lot of content to understand and learn in plug-in development. At the same time, we must also pay attention to some code implementation details. For example, in what dimension is the data stored in this chapter, is it the IDEA development tool dimension, or the engineering dimension in IDEA? , These are different. example, your different projects do not need to save the same configuration
Sixth, series recommendation
- Develop a plug-in that can fish and read in IDEA
- scheme design: based on IDEA plug-in development and bytecode instrumentation technology, automatic analysis of R&D delivery quality is realized
- Technical Literacy: Design and Analysis on Sustainable Delivery of Low Code Programming
- 💥 🎁 Lottery lottery system-Internet distributed development practice based on the four-tier architecture of domain-driven design
- "SpringBoot Middleware Design and Development" | Yes, I will teach you how to build a rocket at the end of the year!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。