计算机系统应用教程网站

网站首页 > 技术文章 正文

IDEA模板逆向生成插件

btikc 2024-09-18 08:37:17 技术文章 19 ℃ 0 评论

EasyCode

EasyCode是一款专为IntelliJ IDEA设计的代码生成工具插件,旨在通过自动化和模板化的方式,极大地提高Java开发者的编码效率和代码质量。这款插件深度融合于IDEA的开发环境中,为开发者带来全新的开发体验,让编程变得更加轻松愉快。

功能特点

  1. 智能代码生成
  2. EasyCode基于模板引擎的原理,能够快速生成标准化的代码片段,包括类、方法、注释、测试等。通过简单的配置和选择,开发者可以在几秒钟内完成繁琐的代码编写工作,如实体类的属性、Getter和Setter方法、数据库操作代码等。
  3. 它支持自定义代码模板,开发者可以根据项目需求和团队编码规范,定制适合自己的代码模板,以最佳实践的方式生成代码,减少因格式问题而浪费的时间。
  4. 智能代码补全
  5. 在编程过程中,开发者只需输入少量的关键字或方法名,EasyCode便能自动补全剩余部分,不仅减少了输入的工作量,还降低了出现拼写错误或语法错误的可能性,提高了代码的可读性和稳定性。
  6. 丰富的模板库
  7. EasyCode提供了丰富的代码模板库,涵盖了常见的代码结构和设计模式。开发者可以根据项目需求,选择合适的模板快速生成代码,节省了大量的编码时间。
  8. 高效便捷的操作
  9. 插件支持通过快捷键和上下文菜单快速生成代码。开发者可以自定义快捷键组合,或在编辑器中选中代码片段后,通过右键菜单选择EasyCode的相关选项,快速生成对应的代码。
  10. 其他实用功能
  11. EasyCode还提供了快速生成文档注释、自动导入所需的包和类、代码格式化等实用功能,帮助开发者更加专注于解决问题和实现功能,而不必在琐碎的代码编写上花费过多的时间和精力。

优缺点

优点

  • 简单容易上手:EasyCode与IDEA完美结合,界面操作简洁明了,操作起来简单方便。
  • 配置少,修改少:几乎不需要手写配置,只需修改模板文件,即可轻松适应项目需求,生成所需代码。
  • 提高开发效率:通过自动生成重复性的代码,减少了手动编写代码的时间和精力,使开发者能够更专注于业务逻辑的实现。
  • 保持代码一致性:使用EasyCode生成的代码遵循统一的标准和规范,提高了代码的一致性和可读性。

缺点

  • 精细度不够:EasyCode主要基于数据库表的字段生成代码,但在实际开发中,某些字段可能需要更精细的处理,如状态字段的多种状态表示、关联字段的关联关系等。
  • 团队共享性差:在团队中,如果某个成员修改了模板,需要手动导出并分享给其他成员导入,才能获得最新的模板,这在一定程度上影响了模板的共享性和更新效率。

综上所述,EasyCode作为一款高效的IDEA插件,通过自动化和模板化的方式,为Java开发者带来了极大的便利和效率提升。尽管存在一些缺点,但在大多数情况下,它仍然是提高开发效率、保持代码一致性的有力工具。

?

其实这么古老的插件大家应该都知道,我就简单讲述一下。并且逆向生成也有很多的方式,这篇文章主要是记录下生成的模板配置信息,方便后续使用。

image.png

使用教程

1.通过IDEA自带的数据库工具连接上数据库

image.png

image.png

2.配置EasyCode生成的模板

*注:点击上面的+是创建分组,输入分组名创建后点击里面的+是创建该分组的模板,后续生成的时候选择其分组就行

3.选择数据表,鼠标右键选择EasyCode来生成模板

image.png

image.png

*注:Package和Path选到要生成的模块级就行了(模块包名会根据模板自动创建,不要自己去创),比如:xxx/src/main/java/com/xx/包名

Mybatis-plus模板:

  • controller.java.vm
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Controller"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/controller"))
##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import $!{tableInfo.savePackageName}.domain.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;
import $!{tableInfo.savePackageName}.common.R;
import org.springframework.web.bind.annotation.*;

import jakarta.annotation.Resource;
import java.io.Serializable;
import java.util.List;

/**
 * $!{tableInfo.comment}($!{tableInfo.name})控制层
 *
 * @author ycc
 * @since $!time.currTime()
 */
@RestController
@RequestMapping("$!tool.firstLowerCase($tableInfo.name)")
public class $!{tableName} {

    /**
     * 服务对象
     */
    @Resource
    private $!{tableInfo.name}Service $!tool.firstLowerCase($tableInfo.name)Service;

    /**
     * 分页查询所有数据
     */
    @GetMapping
    public R page(@RequestParam int current,@RequestParam int size){
        Page<$!{tableInfo.name}> page=new Page<>(current,size);
        return R.ok($!{tool.firstLowerCase($tableInfo.name)}Service.page(page));}


    /**
     * 通过主键查询单条数据
     */
    @GetMapping("{id}")
    public R selectOne(@PathVariable Serializable id){
        return R.ok($!{tool.firstLowerCase($tableInfo.name)}Service.getById(id));}
    
    /**
     * 新增数据
     */
    @PostMapping
    public R save(@RequestBody $!{tableInfo.name} $!tool.firstLowerCase($tableInfo.name)){
        return R.ok($!{tool.firstLowerCase($tableInfo.name)}Service.save($!tool.firstLowerCase($tableInfo.name)));}
    
    /**
     * 修改数据
     */
    @PutMapping
    public R updateById(@RequestBody $!{tableInfo.name} $!tool.firstLowerCase($tableInfo.name)){
        return R.ok($!{tool.firstLowerCase($tableInfo.name)}Service.updateById($!tool.firstLowerCase($tableInfo.name)));}
    
    /**
     * 单条/批量删除数据
     */
    @DeleteMapping
    public R delete(@RequestParam List<Long> id){
        return R.ok($!{tool.firstLowerCase($tableInfo.name)}Service.removeByIds(id));
    }
}
  • service.java.vm
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Service"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service;

import $!{tableInfo.savePackageName}.domain.$!{tableInfo.name};
import com.baomidou.mybatisplus.extension.service.IService;

/**
 * $!{tableInfo.comment}($!{tableInfo.name})服务接口
 *
 * @author ycc
 * @since $!time.currTime()
 */
public interface $!{tableName} extends IService<$!tableInfo.name> {}
  • serviceImpl.java.vm
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "ServiceImpl"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service/impl"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import $!{tableInfo.savePackageName}.domain.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.mapper.$!{tableInfo.name}Mapper;
import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;
import org.springframework.stereotype.Service;

/**
 * $!{tableInfo.comment}($!{tableInfo.name})服务实现类
 *
 * @author ycc
 * @since $!time.currTime()
 */
@Service
public class $!{tableName} extends ServiceImpl<$!{tableInfo.name}Mapper, $!{tableInfo.name}> implements $!{tableInfo.name}Service {}
  • mapper.java.vm
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Mapper"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/mapper"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import $!{tableInfo.savePackageName}.domain.$!tableInfo.name;

/**
 * $!{tableInfo.comment}($!{tableInfo.name})数据库访问层
 *
 * @author ycc
 * @since $!time.currTime()
 */
 @Mapper
public interface $!{tableName} extends BaseMapper<$!tableInfo.name> {}
  • mapper.xml.vm
##引入mybatis支持
$!{mybatisSupport.vm}

##设置保存名称与保存位置
$!callback.setFileName($tool.append($!{tableInfo.name}, "Mapper.xml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources/mapper"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="$!{tableInfo.savePackageName}.mapper.$!{tableInfo.name}Mapper">

    <resultMap type="$!{tableInfo.savePackageName}.domain.vo.$!{tableInfo.name}VO" id="$!{tableInfo.name}VOMap">
#foreach($column in $tableInfo.fullColumn)
        <result property="$!column.name" column="$!column.obj.name" jdbcType="$!column.ext.jdbcType"/>
#end
    </resultMap>
    
</mapper>
  • domain.java.vm
##引入宏定义
$!{define.vm}

##使用宏定义设置回调(保存位置与文件后缀)
#save("/domain", ".java")

##使用宏定义设置包后缀
#setPackageSuffix("domain")

##使用全局变量实现默认包导入
import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


/**
 * $!{tableInfo.comment}($!{tableInfo.comment})表
 *
 * @author ycc
 * @since $!time.currTime()
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class $!{tableInfo.name}{
private static final long serialVersionUID= 1L;
#foreach($column in $tableInfo.pkColumn)
    #if(${column.comment})/**
     * ${column.comment}
     */#end

    @TableId(value = "$!{column.obj.name}" , type = IdType.NONE)
    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end
#foreach($column in $tableInfo.otherColumn)

    #if(${column.comment})
/**
     * ${column.comment}
     */
    #end
@TableField(value = "$!{column.obj.name}")
    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end
}
  • dto.java.vm
##引入宏定义
$!{define.vm}

##使用宏定义设置回调(保存位置与文件后缀)
#save("/domain/dto", "DTO.java")

##使用宏定义设置包后缀
#setPackageSuffix("domain.dto")

import $!{tableInfo.savePackageName}.domain.$!{tableInfo.name};

##使用全局变量实现默认包导入
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * $!{tableInfo.comment}($!{tableInfo.name})DTO
 *
 * @author ycc
 * @since $!time.currTime()
 */
##使用宏定义实现类注释信息
@Data
@NoArgsConstructor
public class $!{tableInfo.name}DTO extends $!{tableInfo.name}{
    
}
  • vo.java.vm
##引入宏定义
$!{define.vm}

##使用宏定义设置回调(保存位置与文件后缀)
#save("/domain/vo", "VO.java")

##使用宏定义设置包后缀
#setPackageSuffix("domain.vo")

import $!{tableInfo.savePackageName}.domain.$!{tableInfo.name};

##使用全局变量实现默认包导入
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * $!{tableInfo.comment}($!{tableInfo.name})VO
 *
 * @author ycc
 * @since $!time.currTime()
 */
##使用宏定义实现类注释信息
@Data
@NoArgsConstructor
public class $!{tableInfo.name}VO extends $!{tableInfo.name}{
    
}

VO/DTO/DOMAIN区别

VO(View Object)、DTO(Data Transfer Object)和DOMAIN(领域模型)是三种常见的用于数据传递和处理的类型,它们各自在不同的场景下发挥着重要作用。下面分别解释它们的区别和使用场景。

1. VO(View Object)

定义:VO通常用于表示视图层(如JSP、HTML页面等)与控制器(Controller)之间的数据传输对象。它封装了需要展示给用户的数据,但不包含业务逻辑。

使用场景

  • 当需要将数据库中的某些数据展示到页面上时,可以使用VO来封装这些数据。
  • VO可以包含多个领域模型(Domain)的属性,用于满足特定视图的展示需求。
  • 便于前端直接处理,减少数据转换的复杂度。

2. DTO(Data Transfer Object)

定义:DTO是一种设计模式,用于在系统不同层(如表现层与业务层之间,或微服务之间的远程调用)之间传输数据。DTO主要用于封装跨层或跨系统边界传输的数据。

使用场景

  • 在微服务架构中,服务间的通信通常使用DTO来传递数据。
  • 当需要在网络间传输数据时(如REST API的返回数据),DTO可以有效地封装需要传输的数据。
  • DTO可以只包含需要的字段,减少数据传输的冗余,提高性能。
  • 在分层架构中,DTO可以隔离层与层之间的数据依赖,提高系统的可扩展性和可维护性。

3. DOMAIN(领域模型)

定义:DOMAIN是领域驱动设计(Domain-Driven Design, DDD)中的一个核心概念,表示业务领域内的一组具有业务含义和规则的类及它们之间的关系。Domain类通常包含业务逻辑和状态信息。

使用场景

  • Domain模型是业务逻辑的核心,它封装了业务领域的知识和规则。
  • 在复杂的业务系统中,Domain模型帮助开发者理解和实现业务逻辑。
  • Domain模型可以直接与数据库表映射(通过ORM工具),但更重要的是,它代表了业务逻辑和数据行为的抽象。
  • 相比DTO和VO,Domain模型更加侧重于业务逻辑的实现和表达。

总结

  • VO 专注于视图展示,封装展示层需要的数据。
  • DTO 专注于数据的跨层或跨系统传输,减少数据冗余,提高传输效率。
  • DOMAIN 专注于业务逻辑的实现,封装业务领域的知识和规则。

在实际项目中,应根据具体需求和场景来选择合适的类型,以达到最佳的开发效率和系统性能。

结语

?

"非常感谢您一直观看到现在,这些看似基础的内容,实则构建了我们知识的基石。我惊喜地发现,将这些基础知识系统地记录下来,不仅是对自我学习的一种巩固,也是一件非常有意义且值得分享的事情。您也完全可以这样做,让我们一起在基础中深耕,发现更多可能。"


原文:https://juejin.cn/post/7392513123860365339

作者:世界哪有真情

#记录我的2024#

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表