整个小东西,在IDEA中自动生成PO、DAO、Mapper
持续坚持原创输出,点击蓝字关注我吧
作者:小傅哥
博客:https://bugstack.cn
❝沉淀、分享、成长,让自己和他人都能有所收获!😜
❞
目录
一、前言
二、需求目的
三、案例开发
1. 工程结构
2. 拖拽Swing面板
3. 配置鼠标右键弹窗
4. 给窗体添加功能
5. 代码生成领域服务
四、测试验证
五、总结
六、系列推荐
一、前言
都能用,都能凑活用!
一个东西好几套,为了晋升都来搞。拿了成绩就要跑,后面兄弟再重造!
几年前,大家并不是这样,那时候还有很多东西可以创新,乱世出英雄总能在一个方向深耕并做出一款款好用的产品功能、框架服务、技术组件等。但后来好像这样的情况开始减少了,取而代之的是重复、复刻、照搬,换个新的皮肤、换个新的样式、换个新的名字,就是取巧的新东西了。
有时候公司或者组织也像家,但家里的东西一般是破了补补、坏了修修,实在不行就换个,但没有谁的家里卫生间一个马桶、厨房一个马桶、客厅一个马桶、卧室一个马桶的,虽然你的新马桶可以自动喷水。
所以,在建设一个好的产品功能时,尽可能要学学那些已经非常的优秀的产品,IDEA、GitHub、Mysql等等,在IDEA提供了满足用户扩展功能的插件开发,而不是你说一个东西我没有,你就自己造。共建会让这个东西变得更加优秀!
二、需求目的
在上一章节中我们通过扩展创建工程向导,添加我们需要创建DDD工程脚手架的步骤,最终提供一个DDD开发框架。那么在这个DDD工程开发框架中,还缺少一部分基于数据库表信息自动生成对应PO、DAO、Mapper文件的功能。
-
那么本章节我们就来在工程中扩展这部分内容,实际操作的效果就是我们可以在工程上通过鼠标右键的方式,唤出添加ORM代码块的窗体,通过选择库表的方式,使用 freemarker 自动生成代码。 -
在生成的代码块中需要完成对所需要包的引入,同时会使用到 lombok 注解的方式替代PO对象中的get、set方法,以减少代码量逻辑的创建。
三、案例开发
1. 工程结构
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
源码获取:#公众号:bugstack虫洞栈
回复:idea
即可下载全部 IDEA 插件开发源码
在此 IDEA 插件工程中,主要分为5块区域:
-
action:用于提供菜单栏,这个菜单的位置在 plugin.xml 中配置,我们把它配置到工程鼠标右键出现的列表上。 这样可以更加方便的让我们选取工程,以及在这个工程下添加生成的代码片段 -
domain:领域服务层,其实你直接写一个Service包也是可以的,只不过最近作者小傅哥更喜欢使用DDD的思想和结构来创建代码实现功能逻辑。 -
infrastructure:基础层,提供数据在工程下的存放,每一个工程右键都有自己的配置存储默认信息,方便下次打开的时候可以读取到这部分内容。同时这一层还提供了用于处理数据库操作的类,因为我们需要从数据库中读取出表的信息、字段、注释,用于创建PO、DAO、Mapper使用。 -
module:模块层,这里提供了一个用于选择文件路径的组件,可以让我们在工程上鼠标右键后出来的窗体中,点击模块选择对应的要生成代码的位置路径。 -
ui:提供配置面板,也就是我们在代码工程上鼠标右键弹出来的面板,这个面板配置后用于生成ORM代码。
2. 拖拽Swing面板
ORMSettingsUI:咱们先把用于创建代码配置的面板创建出来,有了画面,就好进入了。
-
面板包括生成 PO、DAO、XML 的代码路径,以及配置数据库和选择表的内容。 -
操作过程就是在你配置好了这些基本信息后,就可以选择查询表名,并选择好你要给哪几个表生成对应的ORM代码了。
3. 配置鼠标右键弹窗
首先我们需要创建一个 Action 实现类,通过 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));
}
}
-
这是一个右键菜单的入口,通过这个入口才能去打开我们自己的UI窗体,这个UI窗体就是我们上面拖拽出来的配置面板,ORMSettingsUI -
接下来我们还需要把这个 Action 配置到 plugin.xml 文件中,才能被右键菜单创建出来。 开发代码的时候也是这样一个流程,你总要从一个点开始,有了抓手才好抓下去
plugin.xml 配置
<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>
-
把我们的 Action 实现类配置到 xml 中,同时你还要配置它应该出现的位置,比如你需要把这个菜单添加到工程创建中 ProjectViewPopupMenu
以及位置信息anchor="last"
-
另外为了让插件看上去更加高大上还美观适合吹牛,那么还需要配置 icon,这个位置配置一个 16*16
的图片,图片可以从 iconfont 进行下载。
4. 给窗体添加功能
这一步其实干的就是注入灵魂的事情,让窗体活起来。给输入框添加内容、给按钮添加事件、给确认按钮增加上生成创建ORM代码块的上下文。文章的描述尽可能会偏向于核心代码的讲解,详情可以参考源码
接下来这部分内容会在 ORMSettingsUI 类中反复摩擦,直到补全所有功能。
4.1 选择框事件
// 选择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());
}
});
-
还记得我们提到的 拖拽Swing面板
吗,那么这个添加事件的步骤就是给你的 PO 目录添加一个事件,允许我们可以自己选择出要把对应PO的代码生成到哪个目录结构下。 -
关于dao、xml都是类似操作,这里就不在演示了。
4.2 数据表事件
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");
}
});
-
这一步操作核心流程就在于把你需要生成ORM的代码的表给拉出来,只要把表选择上,才能根据表生成PO、DAO、Mapper,其实你用的其他一些自动生成代码框架也是这么干的。 -
另外你的建表最好规范,比如有表注释、有字段注释、字段的设计遵守下划线和小写字母,这样会更加容易创建出好看的代码。
4.3 组装生成代码上下文
当我们点击配置窗体的 OK 按钮时候,要干啥,对喽,我们要创建出代码片段了,那么这个时候需要在重写的 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);
}
-
在 apply 中的核心代码主要就是使用 DBHelper 数据操作工具获取到对应的库下链接信息,同时把选择的号的表创建出用于生成代码类的参数,比如;类的名称、字段名称、注释名称等。 -
最后就是调用生成代码的服务了, projectGenerator.generation(project, codeGenContext);
这一部分就是在我们领域服务 domain 中实现的。
5. 代码生成领域服务
-
用于创建PO、DAO、Mapper的代码块的代码主要是这里实现的,核心在于提供了一个抽象类以及对应的实现类,因为处理代码生成需要使用到 freemarker 所以就在抽象类里包装了下,这样可以免去实现类中还需要关心这部分逻辑。
ProjectGeneratorImpl 生成代码
@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);
}
}
-
创建代码的过程就比较简单了,通过循环提取出来的表信息,映射成对应的类和属性以及注释,再使用 resources 下的 ftl 文件创建出对应的类和xml配置文件就可以了。 -
如果你还需要生成起来代码片段或者创建调用一些常用的组件,也是可以通过这样的方式进行实现的。
四、测试验证
-
点击 Plugin
启动 IDEA 插件,之后在工程右键如下:
1. 鼠标右键,选择菜单
2. 配置页面,配置信息
3. 自动创建,生成代码
-
好了,选择代码块就这么嗖的创建了出来,是不是非常方便,而且可以满足你在任何时候的把新的库表代码补充进来,减少了手敲CRUD操作。
五、总结
-
本章节小傅哥带着你又在 IDEA DDD 插件生成工程的结构下,又完善了一步生成ORM代码,当然你也可以在创建工程向导中添加生成ORM代码的步骤。而在工程下创建ORM的方式可以当做是对脚手架工程的补充,满足不同场景下的需求。 -
此外在 IDEA 插件开发的系列内容中我们是不断的尝试使用新的方式完善不同的功能点,如果你需要开发一个完整的插件那么可以结合这些功能一起来开发你的需求。 -
插件开发中还是有很多的内容需要了解和学习的,同时也要注意一些代码实现细节,例如我们本章节中的数据保存是在一个什么维度,是IDEA开发工具维度,还是在IDEA中的工程维度,这些是有区别。 比如你的不同工程,是不需要保存同一份配置的
六、系列推荐
- END -
下方扫码关注 bugstack虫洞栈,与小傅哥一起学习成长、共同进步,做一个码场最贵Coder!
-
回复【设计模式】,获取《重学Java设计模式》,这是一本互联网真实案例的实践书籍,从实际业务中抽离出,交易、营销、秒杀、中间件、源码等众多场景进行学习代码设计。 -
回复【Spring专栏】, 获取《手撸Spring》,这是一本通过带着读者手写简化版 Spring 框架,了解 Spring IOC、AOP、循环依赖等核心原理和设计实现的技术资料。 -
回复【面经手册】,获取《面经手册 • 拿大厂Offer》,这是一本有深度的Java核心内容,从数据结构、算法、并发编程以及JVM系8不断深入讲解,让懂了就是真的懂。
java
工程师、架构师,开发过交易&营销、写过运营&活动、设计过中间件也倒腾过中继器、IO板卡。不只是写Java语言,也搞过C#、PHP,是一个技术活跃的折腾者。 CodeGuide
、 itstack-demo-design
,持续霸榜 Trending,成为全球热门项目。 本文分享自微信公众号 - bugstack虫洞栈(bugstack)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
英特尔的 Cloud-Hypervisor 项目将转移到 Linux 基金会
Cloud-Hypervisor 开源项目是一个由 Rust 编写的专注于云工作负载的 VMM,几年前由英特尔启动,现在将由 Linux 基金会托管。 该项目非常注重安全性,其特点包括CPU、内存和设备热插拔,支持运行 Windows 和 Linux 客体,使用 vhost-user 进行设备卸载等等。创立时,该项目得到了阿里巴巴、ARM、ByteDance、英特尔和微软的支持,其创始成员包括英特尔研究员 Arjan van de Ven、微软杰出工程师和副总裁 K. Y Srinivasan、ARM 员工工程师 Michael Zhao、阿里巴巴高级员工工程师 Gerry Liu 和 ByteDance 高级软件工程师 Felix Zhang。 上周,Cloud-Hypervisor 20.0 发布,现在为了保证其继续良好发展,它将成为 Linux 基金会的一部分。该项目的重点仍然是 "为现代云工作负载创建一个高性能、轻量级的虚拟机监视器"。此外,微软在 Linux 基金会公告中指出,此举将帮助他们加速云计算超级管理员的开发和采用。 本文转自OSCHINA 本文标题:英特尔的 Clo...
- 下一篇
字典树之旅02.Trie 的标准实现
1. 概述 上一篇文章简单介绍了 Trie,让大家对其有一些感性认知。 这篇文章会先介绍 Trie 的标准实现,然后给出完整代码和测试用例,然后再结合代码实现来分析其优缺点。 论文中通常称这种简单实现为 standard trie,有些文章译为标准实现,还有些译为朴素实现,《算法.第4版》中则译为单词查找树,这些说的都是同一种数据结构。 2. 基本介绍 假如有六个单词:ab, abc, abcd, abd, bcd, cda 如果想查找某个单词,我们可以用散列表来保存。但: 输入"ab",输出前缀为 "ab" 的所有单词; 输入一段文本,输出文本中存在这六个单词的哪几个,以及单词出现的起止位置…… 那么,散列表处理起来就有些困难了。这时,我们可以建立下图所示的树形结构。 图1:字典树 注:图中蓝色(根节点)、白色(无值节点)和红色(有值节点)仅仅是为了便于理解作出的标识,字典树并没有颜色概念。 每个键是一个字符序列,每个字符是一个节点,节点之间用边相连。 基本性质: 根节点不包含字符,非根节点包含一个字符; 一个节点的所有子节点包含的字符均不相同; 非根节点有且仅有一个指向它的父节点;...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Hadoop3单机部署,实现最简伪集群
- MySQL8.0.19开启GTID主从同步CentOS8
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS关闭SELinux安全模块
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS8安装Docker,最新的服务器搭配容器使用
- SpringBoot2配置默认Tomcat设置,开启更多高级功能