当前位置: 首页 > news >正文

IntelliJ IDEA给Controller、Service、Mapper不同文件设置不同的文件头注释模板、Velocity模板引擎

通过在 IntelliJ IDEA 中的 “Includes” 部分添加多个文件头模板,并在 “Files” 模板中利用这些包含来实现不同类型文件的注释。以下是为 Controller、Service、Mapper 文件设置不同文件头的完整示例:

1. 设置 Includes 文件头模板

File > Settings (在 macOS 上是 Preferences)> Editor > File and Code Templates > includes

在 “Includes” 选项卡中,创建以下三个文件头模板:

ControllerHeader

/*** 控制层:* Controller Class: ${NAME}* @Author: ${USER}* @Date: ${DATE} ${TIME}* @Version: ${VERSION}* @Description: ${DESCRIPTION}*/

ServiceHeader

/*** 服务层:* Service Class: ${NAME}* @Author: ${USER}* @Date: ${DATE} ${TIME}* @Version: ${VERSION}* @Description: ${DESCRIPTION}*/

MapperHeader

 /*** 数据层:* Mapper Class: ${NAME}* @Author: ${USER}* @Date: ${DATE} ${TIME}* @Version: ${VERSION}* @Description: ${DESCRIPTION}*/

2. 设置 Files 模板

2.1 设置路径

File > Settings (在 macOS 上是 Preferences)> Editor > File and Code Templates > includes
在这里插入图片描述

2.2 在 “Files” 选项卡中,找到或创建 Java 类模板,并使用条件判断来选择合适的文件头:

2.2.1 根据文件名区分

${NAME.endsWith("Controller")}这种写法专业名词叫Velocity 模板引擎,关于该引擎在后续有详细介绍

#if (${NAME.endsWith("Controller")})#parse("ControllerHeader.java")
#elseif (${NAME.endsWith("Service")})#parse("ServiceHeader.java")
#elseif (${NAME.endsWith("Mapper")})#parse("MapperHeader.java")
#else
/*** Class: ${NAME}* Author: ${USER}* Date: ${DATE}* Description: ${DESCRIPTION}*/
#end

使用更严谨的File template


#if (${NAME.matches(".*Controller$")})#parse("ControllerHeader.java")
#elseif ($NAME.matches(".*Service$") || $NAME.matches(".*ServiceImpl$"))#parse("ServiceHeader.java")
#elseif (${NAME.matches(".*(Mapper|Dao|Repo)$")})#parse("DataLayerHeader.java")
#else
/*** Class: ${NAME}* Author: ${USER}* Date: ${DATE}* Description: ${DESCRIPTION}*/
#end

2.2.2根据包名区分


#if (${PACKAGE_NAME}.contains("controller"))
/*** Controller层 - ${NAME}* 包路径:${PACKAGE_NAME}*/
#elseif (${PACKAGE_NAME}.contains("service"))
/*** Service层 - ${NAME}*/
#elseif (${PACKAGE_NAME}.contains("mapper"))
/*** Mapper接口 - ${NAME}*/
#end
  • 更严谨的判断
#set($isMapperPackage = ${PACKAGE_NAME.contains(".mapper")} || ${PACKAGE_NAME.contains(".dao")})
#set($isServiceImplPackage = ${PACKAGE_NAME.contains(".service.impl")})#if ($isMapperPackage && ($isMapper || ${NAME.endsWith("Repository")}))#parse("mapperHeader.java")
#elseif ($isServiceImplPackage)#parse("serviceImplHeader.java")
#end

3. 应用模板

  • 当你创建一个新文件时,例如 UserController.javaUserService.javaUserMapper.java,IDEA 将根据文件名后缀自动应用相应的文件头注释。
  • 确保新文件的命名遵循 *Controller*Service*Mapper 的模式,以便条件判断能够正确匹配。

4. 为不同文件类型创建完全独立模板

4.1 实图讲解

  • 新增Controller模板—效果图:
    在这里插入图片描述
  • New -> Java Class-> Controller 就会出现新添加的模板
    在这里插入图片描述

4.2 自定义Files模板详细设置

在 IntelliJ IDEA 中创建需要的文件模板,比如 Controller、Service、Mapper,可以通过以下步骤来实现:

  1. 打开文件模板设置

    • 在 IntelliJ IDEA 的菜单栏中,点击 File -> Settings(在 macOS 上是 IntelliJ IDEA -> Preferences)。
    • 在左侧栏中,选择 Editor -> File and Code Templates
  2. 创建新的文件模板

    • Files 标签页中,点击右上角的 + 按钮,创建一个新的文件模板(如Controller)。
    • 为你的模板命名,比如 ControllerServiceMapper
    • 设置文件名:如Controller等,扩展名:java
  3. 定义文件模板内容

    • 在模板的编辑器中输入你希望的文件内容。你可以使用变量来动态生成代码,如 ${NAME}${PACKAGE_NAME} 等。

    • 例如,对于一个 Controller 模板,你可以这样定义:

      package ${PACKAGE_NAME};import org.springframework.web.bind.annotation.*;#parse("ControllerHeader.java")
      @RestController
      @RequestMapping("/${NAME}")
      public class ${NAME}Controller {// Add your endpoints here
      }
      
    • 对于 Service 模板,可以这样定义:

      package ${PACKAGE_NAME};import org.springframework.stereotype.Service;#parse("ServiceHeader.java")
      @Service
      public class ${NAME}Service {// Add your service methods here
      }
      
    • 对于 Mapper 模板,可以这样定义:

      package ${PACKAGE_NAME};import org.apache.ibatis.annotations.Mapper;#parse("MapperHeader.java")
      @Mapper
      public interface ${NAME}Mapper {// Add your mapper methods here
      }
      
  4. 使用模板

    • 当你创建新文件时,右键点击项目结构树中的目标包或目录,选择 New -> Java Class
    • 在弹出的对话框中,选择你创建的模板(如 ControllerServiceMapper)。
    • 输入文件名,IDEA 会根据模板自动生成文件内容,包括你预定义的文件头注释。

通过这些步骤,你可以为常用的文件类型创建模板,提升开发效率和代码的一致性。

5. Velocity 模板引擎

如**#set** 是 Velocity 模板引擎的核心指令之一。以下为您完整解析 Velocity 的语法体系和学习路径:


5.0 相关指令

以下是 Velocity 模板引擎核心指令的详细解析:


一、变量操作指令

1. #set - 变量赋值
#set($var = "value")              ## 字符串
#set($num = 10 + 5)               ## 数值计算
#set($list = [1, 2, 3])           ## 列表
#set($map = {"key":"value"})      ## 键值对

特性

  • 右值可以是表达式、方法调用或嵌套指令
  • 变量类型动态推断(无需声明类型)
  • 变量作用域为整个模板(类似全局变量)

特殊场景

## 多变量赋值
#set($a = $b = 10)## 空值处理
#set($result = $optionalValue ?: "default")

二、流程控制指令

2. #if / #elseif / #else - 条件分支
#if($user.role == "admin")ADMIN MODE
#elseif($user.age >= 18)ADULT USER
#elseGUEST MODE
#end

判断规则

条件表达式判定为 false 的情况
$varnull、空字符串、空集合、false
$var == 5值不相等或类型不同
$list && $list.size() > 0组合逻辑判断
3. #foreach - 循环迭代
#foreach($item in $items)Item $foreach.index: $item.name#if($foreach.count == 5)#break  ## 退出循环#end
#end

循环变量

属性说明
$foreach.index当前索引(从 0 开始)
$foreach.count当前计数(从 1 开始)
$foreach.first是否是第一次迭代(布尔值)
$foreach.last是否是最后一次迭代(布尔值)

三、模板组织指令

4. #include - 静态引入
#include("header.html") 

特点

  • 引入的文件内容不解析 Velocity 语法
  • 适合引入静态 HTML/CSS/JS 片段
  • 可一次引入多个文件:
    #include("head.html", "footer.html")
    
5. #parse - 动态解析
#parse("user_card.vm")

与 #include 对比

特性#parse#include
语法解析✅ 会解析 VTL 指令❌ 原样输出
变量共享✅ 共享当前上下文变量❌ 无变量传递
性能较低(需解析)较高(直接读取)
6. #stop - 引擎停止
#if($error)#stop  ## 立即终止模板渲染
#end

使用场景

  • 遇到致命错误时中断渲染
  • 调试时快速定位问题

四、逻辑控制指令

7. #break - 退出当前指令
#foreach($item in $list)#if($item == "stop") #break  ## 退出当前 #foreach 循环#end
#end

作用范围

  • 仅对当前所在指令有效(如 #foreach#macro
8. #evaluate - 动态执行
#set($template = "Hello $name")
#evaluate($template)  ## 输出:Hello John

危险操作

## 可能引发代码注入(慎用!)
#evaluate($userInput)

五、代码复用指令

9. #define - 定义代码块
#define($block)<div class="alert">This is a reusable block</div>
#end## 调用
$block

特点

  • 类似变量赋值,但可包含复杂 HTML/VTL
  • 每次调用输出相同内容
10. #macro - 定义可传参宏
#macro(renderUser $user $isAdmin)<div class="#if($isAdmin)admin#end">$user.name</div>
#end## 调用
#renderUser($currentUser true)

高级特性

功能示例
默认参数#macro(show $msg="Hello")
可变参数#macro(sum $nums...)
嵌套调用宏内可调用其他宏

六、指令对比矩阵

指令是否解析内容是否共享变量典型应用场景
#include引入静态资源文件
#parse模块化动态模板
#define定义重复使用的静态内容块
#macro创建带参数的复用组件

七、安全实践建议

  1. 避免 #evaluate 用户输入

    ## 危险!
    #evaluate($request.getParameter("tpl"))
    
  2. 防御性模板设计

    ## 安全变量引用
    $!{userInput}  ## 自动处理 null## 集合判空
    #if($!{list} && $list.size() > 0)
    
  3. 性能优化

    ## 复杂计算预编译
    #set($regex = "^\\d{4}-\\d{2}-\\d{2}$")
    #if($dateStr.matches($regex))
    

八、完整示例模板

## 用户列表模板 (user_list.vm)
#define($header)<!DOCTYPE html><html><head><title>User List</title>#include("styles.css")</head>
#end#macro(userCard $user)<div class="card">#parse("user_avatar.vm")<h3>$!{user.name}</h3>#if($user.isAdmin)<span class="badge">ADMIN</span>#end</div>
#end$header
<body>#foreach($user in $users)#if($user.name == "root")#stop  ## 禁止显示 root 用户#end#userCard($user)#if($foreach.count >= 100)#break  ## 最多显示 100 条#end#end#parse("footer.vm")
</body>
</html>

以上内容可作为 Velocity 开发的权威参考,建议结合官方文档实践验证。每个指令的详细行为可能因 Velocity 版本略有差异(本文基于 2.x 版本)。

5.1、#set 指令详解

5.1.1. 基础作用

#set($variable = "value") 
  • 变量定义:创建或修改变量(类似编程中的赋值)
  • 动态计算:可赋值为字符串、数字、布尔值,或通过表达式计算的结果
  • 作用域:在整个模板中有效(类似全局变量)

5.1.2. 典型用法

## 字符串赋值
#set($className = "UserController")## 数值计算
#set($total = 10 + 5 * 3)  ## $total = 25## 布尔逻辑
#set($isValid = $name && $name.length() > 5)## 对象方法调用
#set($firstChar = $className.substring(0,1)) 

5.2、Velocity 的语法规则

Velocity 的语法规则来源于以下渠道:
5.2.1. 官方文档
Apache Velocity 官网 (velocity.apache.org) 提供完整的 VTL (Velocity Template Language) 规范。

5.2.2. IDE 集成

  • IntelliJ IDEA 等 IDE 的 Velocity 模板编辑界面会提供语法提示
  • 输入 # 时会自动弹出指令列表(如 #if, #foreach, #macro

5.2.3. 开源项目实践

  • 许多 Java 项目(如 Spring Boot 的代码生成器)使用 Velocity 模板
  • 通过阅读开源代码学习实际应用技巧

5.3、系统学习 Velocity 语法的路径

5.3.1. 基础语法

指令/语法用途示例
变量引用输出变量值$variable${variable}
注释添加模板注释## 单行注释#* 多行注释 *#
#set变量赋值#set($price = 99.9)
#if/#else/#elseif条件分支见下方示例
#foreach循环遍历集合见下方示例

条件判断示例

#if($user.role == "admin")<p>管理员权限</p>
#elseif($user.age > 18)<p>成年用户</p>
#else<p>未成年用户</p>
#end

循环示例

<ul>
#foreach($item in $items)<li>${foreach.index} - ${item.name}</li>
#end
</ul>

5.3.2. 高级功能

功能说明示例
宏 (Macro)定义可复用的代码片段#macro(showError $msg)<div class="error">$msg</div>#end
引入其他模板模块化模板设计#parse("header.vm")
内置工具对象提供字符串/数学等工具方法$math.add(1,2)$date.format('yyyy-MM-dd')
转义输出防止 XSS 攻击$!{userInput}#escape($htmlContent)

宏定义与调用

## 定义宏
#macro(renderButton $text $color)<button style="color:${color}">$text</button>
#end## 调用宏
#renderButton("提交", "blue")

5.3.3. 调试技巧

  • 输出原始文本:使用 #[[ 不解析的内容 ]]#
    #[[这里的 $variable 不会被解析 → 直接输出 $variable
    ]]#
    
  • 查看变量类型
    $variable.class.name  ## 输出变量类型(如 java.lang.String)
    

5.4、快速查询手册

在模板开发中常用以下语法:

需求场景对应语法
避免变量为 null 时报错$!{variable}
字符串拼接#set($fullName = "$firstName $lastName")
集合是否为空判断#if($list.isEmpty()) 或 `#if(!$list
数值格式化$number.format("#,###", $price)
日期格式化$date.format('yyyy-MM-dd', $today)

5.5、学习资源推荐

5.5.1. 官方文档(必读)

  • VTL 语法参考
  • 用户指南

5.5.2. 实战教程

  • Baeldung 的 Velocity 指南
  • TutorialsPoint 的 Velocity 教程

5.5.3. IDE 辅助

  • 在 IntelliJ IDEA 中创建 .vm 文件,IDE 会提供:
    • 语法高亮
    • 指令自动补全(输入 # 触发)
    • 错误检查

5.6、示例:完整模板文件

## 模板:user_profile.vm
#set($user = $data.getUser())
#set($birthday = $date.format('yyyy-MM-dd', $user.birthDate))<html>
<head><title>$!{user.name} 的资料</title>
</head>
<body>#if($user.isAdmin())<div class="admin-banner">管理员用户</div>#end<h1>用户信息</h1><ul><li>姓名:$!{user.name}</li><li>年龄:$math.sub($date.getYear(), $user.birthYear)</li><li>生日:$birthday</li></ul>#macro(renderSection $title $content)<div class="section"><h2>$title</h2><p>$content</p></div>#end#renderSection("联系方式", $user.contactInfo)
</body>
</html>

通过系统学习上述内容,您将能:

  1. 熟练使用 Velocity 生成动态内容
  2. 理解模板引擎的运行机制
  3. 快速定位和解决模板渲染问题

建议边学边实践,在 IntelliJ 中创建 .vm 文件体验实时语法反馈。

5.7 Velocity引擎与Freemarker等热门引擎对比以及应用场景

Velocity 确实不如 Freemarker、Thymeleaf 这类模板引擎知名度高,但它是一个历史悠久特定场景下非常高效的模板引擎。以下是它的核心应用场景和特点解析,帮助您理解为什么某些场景(比如 IDEA 的注释模板)会选择它:


一、Velocity 的典型应用场景

1. 代码生成(核心优势场景)
  • Java 注释模板(如 IDEA 内置)
  • MyBatis 逆向工程(生成 DAO/Mapper 文件)
  • Spring Boot 项目脚手架(如 JHipster 早期版本)
  • API 文档生成(结合 Swagger 模板)

优势
✅ 语法简单,适合非前端开发者使用
✅ 无复杂依赖,可嵌入任何 Java 环境
✅ 生成纯文本(代码/配置文件)时性能极高

2. 传统 Web 页面渲染(逐渐被替代)
  • 早期的 Java Web 项目(如 Struts 1.x 时代)
  • 企业级 CMS 内容模板(如 Alfresco)

现状
⚠️ 新项目更推荐 Thymeleaf/FreeMarker(对现代前端更友好)
⚠️ 不支持响应式设计等现代特性

3. 邮件模板
  • 企业级邮件内容动态生成(如订单通知)
  • 相比 HTML 页面,邮件模板更简单,Velocity 足够轻量
4. 配置文件动态化
#set($dbHost = "192.168.1.100")
jdbc.url=jdbc:mysql://${dbHost}:3306/db

二、为什么 IDEA 选择 Velocity 做注释模板?

  1. 轻量级
    无需引入额外依赖,IDEA 内置的模板引擎需要极低的开销。

  2. 逻辑简单
    注释模板通常只需要变量替换和简单条件判断,例如:

    /*** @author ${USER}* @date ${DATE}#if(${DESCRIPTION})* @description ${DESCRIPTION}#end*/
    
  3. 无副作用
    不会像 FreeMarker 那样产生意外换行或空格(对代码格式敏感)。


三、与现代模板引擎对比

特性VelocityFreeMarkerThymeleaf
学习曲线⭐(最简单)⭐⭐⭐⭐⭐(需懂 HTML)
性能⭐⭐⭐(最快)⭐⭐
前端友好度❌(纯后端)✅⭐⭐⭐(原生 HTML)
动态代码生成✅⭐⭐⭐✅⭐
社区活跃度⭐(维护模式)⭐⭐⭐⭐⭐⭐⭐

四、经典代码生成示例

MyBatis 生成器模板(mapper.xml.vm
<!-- 生成于 ${date} -->
<mapper namespace="${package.Mapper}.${table.mapperName}">#foreach($field in ${table.fields})#if(${field.keyFlag})<id column="${field.name}" property="${field.propertyName}" />#else<result column="${field.name}" property="${field.propertyName}" />#end#end<select id="selectById" resultMap="BaseResultMap">SELECT * FROM ${table.name} WHERE id = #{id}</select>
</mapper>
Spring Controller 模板(Controller.java.vm
#set($entity = ${table.entityName.toLowerCase()})
@RestController
@RequestMapping("/api/${entity}")
public class ${table.controllerName} {@Autowiredprivate ${table.serviceName} ${entity}Service;@GetMapping("/{id}")public Result<${table.entityName}> getById(@PathVariable ${table.primaryKeyType} id) {return Result.success(${entity}Service.getById(id));}
}

五、什么时候应该选择 Velocity?

  1. 需要生成代码/配置文件
    (如自动生成 CRUD 代码、批量创建相似文件)

  2. 嵌入式模板需求
    (如插件系统需要允许用户自定义模板)

  3. 历史项目维护
    (老系统升级时保留原有模板)


六、为什么不推荐新项目用 Velocity 做页面渲染?

  1. 功能局限
    缺少模板继承、片段复用等现代特性,复杂页面难以维护。

  2. 前后端协作困难
    设计师无法直接修改 HTML(模板语法混合在标签中)。

  3. 安全风险
    默认不开启 HTML 转义,容易导致 XSS 攻击(需手动处理)。


七、快速识别 Velocity 模板

  1. 文件扩展名.vm
  2. 语法特征
    <!-- 变量使用 $ 前缀 -->
    <h1>$title</h1><!-- 指令以 # 开头 -->
    #foreach($item in $list)<li>$item</li>
    #end
    

如果您只需要一个轻量级文本生成工具(如代码注释、配置文件生成),Velocity 仍然是优秀选择。但对于 Web 页面开发,建议转向 FreeMarker/Thymeleaf 等现代引擎。

相关文章:

  • 【认知思维】光环效应:第一印象的持久力量
  • 中国版 Cursor---腾讯云 CodeBuddy | 从安装VSCode到数独小游戏问世
  • IDEA查看类结构视图窗口,接口的所有的实现类图
  • TensorFlow 常见使用场景及开源项目实例
  • Spring WebFlux 与 WebClient 使用指南
  • PHP-FPM 调优配置建议
  • 开源自定义Python库并上传到PyPi
  • 利用 Python 进行量化的主要步骤
  • .Net HttpClient 使用Json数据
  • 原生小程序+springboot+vue医院医患纠纷管理系统的设计与开发(程序+论文+讲解+安装+售后)
  • 桑德拉精神与开源链动2+1模式AI智能名片S2B2C商城小程序的协同价值研究
  • GPT-4.1和GPT-4.1-mini系列模型支持微调功能,助力企业级智能应用深度契合业务需求
  • 运用数组和矩阵对数据进行存取和运算——NumPy模块 之六
  • 面试中被问到谈谈你对threadlocal的理解
  • 是 OpenCV 的 CUDA 模块中用于在 GPU 上对图像或矩阵进行转置操作函数cv::cuda::transpose
  • 职坐标AIoT开发技能精讲培训
  • 通过POI实现对word基于书签的内容替换、删除、插入
  • 随言随语(十二):盖章
  • Hadoop的目录结构和组成
  • Springboot之类路径扫描
  • 兰州大学教授安成邦加盟复旦大学中国历史地理研究所
  • 万科:存续债券均正常付息兑付
  • 最美西游、三星堆遗址等入选“2025十大年度IP”
  • 甘肃:今年6月前,由县级党委、政府制定农村彩礼倡导性标准
  • 通辽警方侦破一起积压21年的命案:嫌疑人企图强奸遭反抗后杀人
  • 中国潜水救捞行业协会发布《呵护潜水员职业健康安全宣言》