文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

IDEA工程右键菜单,自动生成 ORM码

2024-12-02 14:44

关注

一、前言

都能用,都能凑活用!

一个东西好几套,为了晋升都来搞。拿了成绩就要跑,后面兄弟再重造!

几年前,大家并不是这样,那时候还有很多东西可以创新,乱世出英雄总能在一个方向深耕并做出一款款好用的产品功能、框架服务、技术组件等。但后来好像这样的情况开始减少了,取而代之的是重复、复刻、照搬,换个新的皮肤、换个新的样式、换个新的名字,就是取巧的新东西了。

有时候公司或者组织也像家,但家里的东西一般是破了补补、坏了修修,实在不行就换个,但没有谁的家里卫生间一个马桶、厨房一个马桶、客厅一个马桶、卧室一个马桶的,虽然你的新马桶可以自动喷水。

所以,在建设一个好的产品功能时,尽可能要学学那些已经非常的优秀的产品,IDEA、GitHub、Mysql等等,在IDEA提供了满足用户扩展功能的插件开发,而不是你说一个东西我没有,你就自己造。共建会让这个东西变得更加优秀!

二、需求目的

在上一章节中我们通过扩展创建工程向导,添加我们需要创建DDD工程脚手架的步骤,最终提供一个DDD开发框架。那么在这个DDD工程开发框架中,还缺少一部分基于数据库表信息自动生成对应PO、DAO、Mapper文件的功能。

那么本章节我们就来在工程中扩展这部分内容,实际操作的效果就是我们可以在工程上通过鼠标右键的方式,唤出添加ORM代码块的窗体,通过选择库表的方式,使用 freemarker 自动生成代码。

在生成的代码块中需要完成对所需要包的引入,同时会使用到 lombok 注解的方式替代PO对象中的get、set方法,以减少代码量逻辑的创建。

三、案例开发

1. 工程结构

  1. guide-idea-plugin-orm 
  2. ├── .gradle 
  3. └── src 
  4.     ├── main 
  5.     │   └── java 
  6.     │    └── cn.bugstack.guide.idea.plugin  
  7.     │        ├── action 
  8.     │        │   └── CodeGenerateAction.java       
  9.     │        ├── domain 
  10.     │        │   ├── model.vo  
  11.     │        │   │   ├── CodeGenContextVO.java        
  12.     │        │   │   └── ORMConfigVO.java        
  13.     │        │   └── service    
  14.     │        │     ├── impl      
  15.     │        │     │   └── ProjectGeneratorImpl.java   
  16.     │        │     ├── AbstractProjectGenerator.java      
  17.     │        │     ├── GeneratorConfig.java       
  18.     │        │     └── IProjectGenerator.java       
  19.     │        ├── infrastructure 
  20.     │        │   ├── data     
  21.     │        │   │   ├── DataSetting.java        
  22.     │        │   │   └── DataState.java       
  23.     │        │   ├── po     
  24.     │        │   │   ├── Base.java     
  25.     │        │   │   ├── Column.java  
  26.     │        │   │   ├── Dao.java  
  27.     │        │   │   ├── Field.java  
  28.     │        │   │   ├── Model.java      
  29.     │        │   │   └── Table.java        
  30.     │        │   └── utils  
  31.     │        │       ├── DBHelper.java      
  32.     │        │       └── JavaType.java       
  33.     │        ├── module   
  34.     │        │   └── FileChooserComponent.java          
  35.     │        └── ui 
  36.     │            ├── ORMSettingsUI.java   
  37.     │            └── ORMSettingsUI.form 
  38.     ├── resources 
  39.     │   ├── META-INF 
  40.     │   │   └── plugin.xml  
  41.     │   └── template 
  42.     │       ├── dao.ftl 
  43.     │       ├── mapper.ftl 
  44.     │       └── model.ftl 
  45.     ├── build.gradle   
  46.     └── gradle.properties 

在此 IDEA 插件工程中,主要分为5块区域:

2. 拖拽Swing面板

ORMSettingsUI:咱们先把用于创建代码配置的面板创建出来,有了画面,就好进入了。

3. 配置鼠标右键弹窗

首先我们需要创建一个 Action 实现类,通过 New -> Plugin DevKit -> Action

cn.bugstack.guide.idea.plugin.action.CodeGenerateAction

  1.  
  2. public class CodeGenerateAction extends AnAction { 
  3.  
  4.     private IProjectGenerator projectGenerator = new ProjectGeneratorImpl(); 
  5.  
  6.     @Override 
  7.     public void actionPerformed(AnActionEvent e) { 
  8.         Project project = e.getRequiredData(CommonDataKeys.PROJECT); 
  9.         ShowSettingsUtil.getInstance().editConfigurable(project, new ORMSettingsUI(project, projectGenerator)); 
  10.     } 
  11.  

plugin.xml 配置

  1.  
  2.     -- Add your actions here --> 
  3.     <action id="CodeGenerateAction" class="cn.bugstack.guide.idea.plugin.action.CodeGenerateAction" 
  4.             text="ORMCodeGenerate - 小傅哥" description="Code Generate ORM" icon="/icons/logo.png"
  5.         <add-to-group group-id="ProjectViewPopupMenu" anchor="last"/> 
  6.     action
  7.  
  8. ea-plugin> 

4. 给窗体添加功能

这一步其实干的就是注入灵魂的事情,让窗体活起来。给输入框添加内容、给按钮添加事件、给确认按钮增加上生成创建ORM代码块的上下文。文章的描述尽可能会偏向于核心代码的讲解,详情可以参考源码

接下来这部分内容会在 ORMSettingsUI 类中反复摩擦,直到补全所有功能。

4.1 选择框事件

  1. // 选择PO生成目录 
  2. this.poButton.addActionListener(e -> { 
  3.     FileChooserComponent component = FileChooserComponent.getInstance(project); 
  4.     VirtualFile baseDir = project.getBaseDir(); 
  5.     VirtualFile virtualFile = component.showFolderSelectionDialog("选择PO生成目录", baseDir, baseDir); 
  6.     if (null != virtualFile) { 
  7.         ORMSettingsUI.this.poPath.setText(virtualFile.getPath()); 
  8.     } 
  9. }); 

还记得我们提到的拖拽Swing面板吗,那么这个添加事件的步骤就是给你的 PO 目录添加一个事件,允许我们可以自己选择出要把对应PO的代码生成到哪个目录结构下。

关于dao、xml都是类似操作,这里就不在演示了。

4.2 数据表事件

  1. this.selectButton.addActionListener(e -> { 
  2.     try { 
  3.         DBHelper dbHelper = new DBHelper(this.host.getText(), Integer.parseInt(this.port.getText()), this.user.getText(), this.password.getText(), this.database.getText()); 
  4.         List tableList = dbHelper.getAllTableName(this.database.getText()); 
  5.         String[] title = {"""表名"}; 
  6.         Object[][] data = new Object[tableList.size()][2]; 
  7.         for (int i = 0; i < tableList.size(); i++) { 
  8.             data[i][1] = tableList.get(i); 
  9.         } 
  10.         table1.setModel(new DefaultTableModel(data, title)); 
  11.         TableColumn tc = table1.getColumnModel().getColumn(0); 
  12.         tc.setCellEditor(new DefaultCellEditor(new JCheckBox())); 
  13.         tc.setCellEditor(table1.getDefaultEditor(Boolean.class)); 
  14.         tc.setCellRenderer(table1.getDefaultRenderer(Boolean.class)); 
  15.         tc.setMaxWidth(100); 
  16.     } catch (Exception exception) { 
  17.         Messages.showWarningDialog(project, "数据库连接错误,请检查配置.""Warning"); 
  18.     } 
  19. }); 

4.3 组装生成代码上下文

当我们点击配置窗体的 OK 按钮时候,要干啥,对喽,我们要创建出代码片段了,那么这个时候需要在重写的 apply 中完成此项操作。

  1. public void apply() { 
  2.     // 链接DB 
  3.     DBHelper dbHelper = new DBHelper(config.getHost(), Integer.parseInt(config.getPort()), config.getUser(), config.getPassword(), config.getDatabase()); 
  4.      
  5.     // 组装代码生产上下文 
  6.     CodeGenContextVO codeGenContext = new CodeGenContextVO(); 
  7.     codeGenContext.setModelPackage(config.getPoPath() + "/po/"); 
  8.     codeGenContext.setDaoPackage(config.getDaoPath() + "/dao/"); 
  9.     codeGenContext.setMapperDir(config.getXmlPath() + "/mapper/"); 
  10.     List<Table> tables = new ArrayList<>(); 
  11.     Set tableNames = config.getTableNames(); 
  12.     for (String tableName : tableNames) { 
  13.         tables.add(dbHelper.getTable(tableName)); 
  14.     } 
  15.     codeGenContext.setTables(tables); 
  16.      
  17.     // 生成代码 
  18.     projectGenerator.generation(project, codeGenContext); 

5. 代码生成领域服务

用于创建PO、DAO、Mapper的代码块的代码主要是这里实现的,核心在于提供了一个抽象类以及对应的实现类,因为处理代码生成需要使用到 freemarker 所以就在抽象类里包装了下,这样可以免去实现类中还需要关心这部分逻辑。

ProjectGeneratorImpl 生成代码

  1. @Override 
  2. protected void generateORM(Project project, CodeGenContextVO codeGenContext) { 
  3.     List<Table> tables = codeGenContext.getTables(); 
  4.     for (Table table : tables) { 
  5.         List<Column> columns = table.getColumns(); 
  6.         List fields = new ArrayList<>(); 
  7.         for (Column column : columns) { 
  8.             Field field = new Field(column.getComment(), JavaType.convertType(column.getType()), column.getName()); 
  9.             field.setId(column.isId()); 
  10.             fields.add(field); 
  11.         } 
  12.         // 生成PO 
  13.         Model model = new Model(table.getComment(), codeGenContext.getModelPackage() + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, table.getName()), table.getName(), fields); 
  14.         writeFile(project, codeGenContext.getModelPackage(), model.getSimpleName() + ".java""domain/orm/model.ftl", model); 
  15.          
  16.         // 生成DAO 
  17.         Dao dao = new Dao(table.getComment(), codeGenContext.getDaoPackage() + "I" + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, table.getName()) + "Dao", model); 
  18.         writeFile(project, codeGenContext.getDaoPackage(), dao.getSimpleName() + ".java""domain/orm/dao.ftl", dao); 
  19.          
  20.         // 生成Mapper 
  21.         writeFile(project, codeGenContext.getMapperDir(), dao.getModel().getSimpleName() + "Mapper.xml""domain/orm/mapper.ftl", dao); 
  22.     } 

四、测试验证

点击 Plugin 启动 IDEA 插件,之后在工程右键如下:

1. 鼠标右键,选择菜单

2. 配置页面,配置信息

3. 自动创建,生成代码

好了,选择代码块就这么嗖的创建了出来,是不是非常方便,而且可以满足你在任何时候的把新的库表代码补充进来,减少了手敲CRUD操作。

五、总结

本章节小傅哥带着你又在 IDEA DDD 插件生成工程的结构下,又完善了一步生成ORM代码,当然你也可以在创建工程向导中添加生成ORM代码的步骤。而在工程下创建ORM的方式可以当做是对脚手架工程的补充,满足不同场景下的需求。

此外在 IDEA 插件开发的系列内容中我们是不断的尝试使用新的方式完善不同的功能点,如果你需要开发一个完整的插件那么可以结合这些功能一起来开发你的需求。

插件开发中还是有很多的内容需要了解和学习的,同时也要注意一些代码实现细节,例如我们本章节中的数据保存是在一个什么维度,是IDEA开发工具维度,还是在IDEA中的工程维度,这些是有区别。比如你的不同工程,是不需要保存同一份配置的

 

 

来源:bugstack虫洞栈内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯