• Java培训:自定义代码生成器


    1 概述

    1.1 介绍

    在项目开发过程中,有很多业务模块的代码是具有一定规律性的,例如controller控制器、service接口、service实现类、mapper接口、model实体类等等,这部分代码可以使用代码生成器生成,我们就可以将更多的时间放在业务逻辑上。

      传统的开发步骤:

       创建数据库和表

       根据表设计实体类

       编写mapper接口

       编写service接口和实现类

       编写controller控制器

       编写前端页面

       前后端联调

      基于代码生成器开发步骤:

       创建数据库和表

       使用代码生成器生成实体类、mapper、service、controller、前端页面

       将生成好的代码拷贝到项目中并做调整

       前后端联调

      我们只需要知道数据库和表相关信息,就可以结合模版生成各个模块的代码,减少了很多重复工作,也减少出错概率,提高效率。

      1.2 实现思路
     

      (1)需要对数据库表解析获取到元数据,包含表字段名称、字段类型等等。

      (2)将通用的代码编写成模版文件,部分数据需使用占位符替换。

      (3)将元数据和模版文件结合,使用一些模版引擎工具(例如freemarker)即可生成源代码文件。

      2 Freemarker

      2.1 介绍

       FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

       模板编写为FreeMarker Template Language (FTL)。它是简单的,专用的语言, 在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。

      2.2 应用场景

      (1)动态页面

      freemarker可以作为springmvc一种视图格式,像jsp一样被浏览器访问。

      (2)页面静态化

      对于一些内容比较多,更新频率很小,访问又很频繁的页面,可以使用freemarker静态化,减少DB的压力,提高页面打开速度。

      (3)代码生成器

      根据配置生成页面和代码,减少重复工作,提高开发效率。
     

      2.3 快速入门

      (1)创建freemarker-demo模块,并导入相关依赖

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0</modelVersion>
    6. <groupId>com.itheima</groupId>
    7. <artifactId>freemarker-demo</artifactId>
    8. <version>1.0-SNAPSHOT</version>
    9. <parent>
    10. <groupId>org.springframework.boot</groupId>
    11. <artifactId>spring-boot-starter-parent</artifactId>
    12. <version>2.3.1.RELEASE</version>
    13. </parent>
    14. <properties>
    15. <maven.compiler.source>8</maven.compiler.source>
    16. <maven.compiler.target>8</maven.compiler.target>
    17. </properties>
    18. <dependencies>
    19. <dependency>
    20. <groupId>org.springframework.boot</groupId>
    21. <artifactId>spring-boot-starter-web</artifactId>
    22. </dependency>
    23. <dependency>
    24. <groupId>org.springframework.boot</groupId>
    25. <artifactId>spring-boot-starter-test</artifactId>
    26. </dependency>
    27. <!-- freemarker -->
    28. <dependency>
    29. <groupId>org.springframework.boot</groupId>
    30. <artifactId>spring-boot-starter-freemarker</artifactId>
    31. </dependency>
    32. <!-- lombok -->
    33. <dependency>
    34. <groupId>org.projectlombok</groupId>
    35. <artifactId>lombok</artifactId>
    36. </dependency>
    37. </dependencies>
    38. </project>

      (2)application.yml相关配置

    1. server:
    2. port: 8881 #服务端口
    3. spring:
    4. application:
    5. name: freemarker-demo #指定服务名
    6. freemarker:
    7. cache: false #关闭模板缓存,方便测试
    8. settings:
    9. template_update_delay: 0 #检查模板更新延迟时间,设置为0表示立即检查,如果时间大于0会有缓存不方便进行模板测试
    10. suffix: .ftl #指定Freemarker模板文件的后缀名

      (3)创建启动类

    1. package com.heima.freemarker;
    2. import org.springframework.boot.SpringApplication;
    3. import org.springframework.boot.autoconfigure.SpringBootApplication;
    4. @SpringBootApplication
    5. public class FreemarkerDemotApplication {
    6. public static void main(String[] args) {
    7. SpringApplication.run(FreemarkerDemotApplication.class,args);
    8. }
    9. }

      (4)创建Student模型类

    1. package com.itheima.freemarker.entity;
    2. import lombok.AllArgsConstructor;
    3. import lombok.Data;
    4. import lombok.NoArgsConstructor;
    5. import java.util.Date;
    6. @Data
    7. @NoArgsConstructor
    8. @AllArgsConstructor
    9. public class Student {
    10. private Integer id;
    11. private String name;//姓名
    12. private Integer age;//年龄
    13. private Date birthday;//生日
    14. private Float money;//钱包
    15. }

      (5)创建StudentController

    1. package com.itheima.freemarker.controller;
    2. import com.itheima.freemarker.entity.Student;
    3. import org.springframework.stereotype.Controller;
    4. import org.springframework.ui.Model;
    5. import org.springframework.web.bind.annotation.GetMapping;
    6. import org.springframework.web.bind.annotation.RequestMapping;
    7. import java.util.Date;
    8. @Controller
    9. @RequestMapping("student")
    10. public class StudentController {
    11. @GetMapping("index")
    12. public String index(Model model){
    13. //1.纯文本形式的参数
    14. model.addAttribute("name", "Freemarker");
    15. //2.实体类相关的参数
    16. Student student = new Student();
    17. student.setName("黑马");
    18. student.setAge(18);
    19. model.addAttribute("stu", student);
    20. return "01-index";
    21. }
    22. }

      (6)在resources/templates下创建01-index.ftl模版文件

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>首页</title>
    6. </head>
    7. <body>
    8. <b>普通文本 String 展示:</b><br/>
    9. Hello ${name} <br>
    10. <hr>
    11. <b>对象Student中的数据展示:</b><br/>
    12. 姓名:${stu.name}<br/>
    13. 年龄:${stu.age}
    14. <hr>
    15. </body>
    16. </html>

      (7)测试
     

      浏览器访问 http://localhost:8881/student/index
     

      效果如下

      2.4 模版
     

      2.4.1 基础语法种类
     

      (1)注释,即<#-- -->,介于其之间的内容会被freemarker忽略

    <#--我是一个freemarker注释-->

      (2)插值(Interpolation):即 **`${..}`** 部分,freemarker会用真实的值代替**`${..}`**

    Hello ${name}

      (3)FTL指令:和HTML标记类似,名字前加#予以区分,Freemarker会解析标签中的表达式或逻辑。

    <# >FTL指令</#>

      (4)文本,仅文本信息,这些不是freemarker的注释、插值、FTL指令的内容会被freemarker忽略解析,直接输出内容。

    1. <#--freemarker中的普通文本-->
    2. 我是一个普通的文本

      2.4.2 if指令
     

      if 指令即判断指令,是常用的FTL指令,freemarker在解析时遇到if会进行判断,条件为真则输出if中间的内容,否则跳过内容不再输出。
     

      格式如下

    1. <#if condition>
    2. ....
    3. <#elseif condition2>
    4. ...
    5. <#elseif condition3>
    6. ...
    7. <#else>
    8. ...
    9. </#if>

      需求:根据年龄输出所处的年龄段
     

      > 童年:0岁—6岁(周岁,下同)

      > 少年:7岁—17岁

      > 青年:18岁—40岁

      > 中年:41—65岁

      > 老年:66岁以后
     

      实例代码:
     

      (1)在01-index.ftl添加如下代码

    1. <#if stu.age <= 6>
    2. 童年
    3. <#elseif stu.age <= 17>
    4. 少年
    5. <#elseif stu.age <= 40>
    6. 青年
    7. <#elseif stu.age <= 65>
    8. 中年
    9. <#else>
    10. 老年
    11. </#if>

      (2)测试
     

      浏览器访问http://localhost:8881/student/index
     

      效果如下

      2.4.3 list指令
     

      list指令时一个迭代输出指令,用于迭代输出数据模型中的集合
     

      格式如下

    1. <#list items as item>
    2. ${item_index + 1}------${item}-----<#if item_has_next>,</#if>
    3. </#list>

      
           迭代集合对象时,包括两个特殊的循环变量:

      (1)item_index:当前变量的索引值。

      (2)item_has_next:是否存在下一个对象
     

      > item_index 和 item_has_nex 中的item为<#list items as item> 中as后面的临时变量
     

      需求:遍历学生集合,输出序号,学生id,姓名,所处的年龄段,是否最后一条数据
     

      (1)在StudentController中增加方法

    1. @GetMapping("list")
    2. public String list(Model model) throws ParseException {
    3. List<Student> list = new ArrayList<>();
    4. list.add(new Student(1001,"张飞",15, null, 1000.11F));
    5. list.add(new Student(1002,"刘备",28, null, 5000.3F));
    6. list.add(new Student(1003,"关羽",45, null, 9000.63F));
    7. list.add(new Student(1004,"诸葛亮",62, null, 10000.99F));
    8. list.add(new Student(1005,"成吉思汗",75, null, 16000.66F));
    9. model.addAttribute("stus",list);
    10. return "02-list";
    11. }

      (2)在resources/templates目录下创建02-list.ftl模版

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>列表页面</title>
    6. <style>
    7. table{
    8. border-spacing: 0;/*把单元格间隙设置为0*/
    9. border-collapse: collapse;/*设置单元格的边框合并为1*/
    10. }
    11. td{
    12. border:1px solid #ACBED1;
    13. text-align: center;
    14. }
    15. </style>
    16. </head>
    17. <body>
    18. <table>
    19. <tr>
    20. <td>序号</td>
    21. <td>id</td>
    22. <td>姓名</td>
    23. <td>所处的年龄段</td>
    24. <td>生日</td>
    25. <td>钱包</td>
    26. <td>是否最后一条数据</td>
    27. </tr>
    28. <#list stus as stu >
    29. <tr>
    30. <td>${stu_index + 1}</td>
    31. <td>${stu.id}</td>
    32. <td>${stu.name}</td>
    33. <td>
    34. <#if stu.age <= 6>
    35. 童年
    36. <#elseif stu.age <= 17>
    37. 少年
    38. <#elseif stu.age <= 40>
    39. 青年
    40. <#elseif stu.age <= 65>
    41. 中年
    42. <#else>
    43. 老年
    44. </#if>
    45. </td>
    46. <td></td>
    47. <td>${stu.money}</td>
    48. <td>
    49. <#if stu_has_next>
    50. <#else>
    51. </#if>
    52. </td>
    53. </tr>
    54. </#list>
    55. </table>
    56. <hr>
    57. </body>
    58. </html>

      (2)测试
     

      浏览器访问http://localhost:8881/student/list
     

      效果如下
     

      2.4.4 include指令
     

      include指令的作用类似于JSP的包含指令,用于包含指定页,include指令的语法格式如下

    <#include filename [options]></#include>

     
        (1)filename:该参数指定被包含的模板文件

      (2)options:该参数可以省略,指定包含时的选项,包含encoding和parse两个选项,encoding

      指定包含页面时所使用的解码集,而parse指定被包含是否作为FTL文件来解析。如果省略了parse选项值,则该选项值默认是true
     

      需求:"早上好,尊敬的 某某 用户!" 这句话在很多页面都有用到,请合理设计!
     

      (1)在resources/templates目录下创建00-head.ftl模版,内容如下

    早上好,尊敬的 ${name} 用户!

      (2)在resources/templates目录下创建03-include.ftl模版,使用include引入00-head.ftl模版,内容如下

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>详情页</title>
    6. </head>
    7. <body>
    8. <#include "00-head.ftl" />
    9. <br>
    10. 欢迎来到黑马程序员。
    11. </body>
    12. </html>

      (3)在StudentController中增加方法

    1. @GetMapping("include")
    2. public String include(Model model) throws ParseException {
    3. model.addAttribute("name", "黑马");
    4. return "03-include";
    5. }

      (4)测试
     

      浏览器访问http://localhost:8881/student/include
     

      效果如下

      2.4.5 assign指令
     

      它用于为该模板页面创建或替换一个顶层变量

    <#assign name = "zhangsan" />

      2.4.6 运算符
     

      (1)算数运算符
     

      FreeMarker表达式中完全支持算术运算,FreeMarker支持的算术运算符包括:
     

      - 加法: `+`

      - 减法: `-`

      - 乘法: `*`

      - 除法: `/`

      - 求模 (求余): `%`
     

      (2)比较运算符
     

      - `=`或者`==`:判断两个值是否相等.

      - `!=`:判断两个值是否不等.

      - `>`或者`gt`:判断左边值是否大于右边值

      - `>=`或者`gte`:判断左边值是否大于等于右边值

      - `<`或者`lt`:判断左边值是否小于右边值

      - `<=`或者`lte`:判断左边值是否小于等于右边值
     

      比较运算符注意
     

      - `=`和`!=`可以用于字符串、数值和日期来比较是否相等

      - `=`和`!=`两边必须是相同类型的值,否则会产生错误

      - 字符串 `"x"` 、`"x "` 、`"X"`比较是不等的.因为FreeMarker是精确比较

      - 其它的运行符可以作用于数字和日期,但不能作用于字符串

      - 使用`gt`等字母运算符代替`>`会有更好的效果,因为 FreeMarker会把`>`解释成FTL标签的结束字符

      - 可以使用括号来避免这种情况,如:`<#if (x>y)>`
     

      (3)逻辑运算符
     

      - 逻辑与:&&

      - 逻辑或:||

      - 逻辑非:!
     

      逻辑运算符只能作用于布尔值,否则将产生错误 。
     

      2.4.7 空值处理
     

      (1)缺失变量默认值使用 “!”
     

      - 使用!要以指定一个默认值,当变量为空时显示默认值
     

      例: ${name!''}表示如果name为空显示空字符串。
     

      - 如果是嵌套对象则建议使用()括起来
     

      例: ${(stu.bestFriend.name)!''}表示,如果stu或bestFriend或name为空默认显示空字符串。
     

      (2)判断某变量是否存在使用 “??”
     

      用法为:variable??,如果该变量存在,返回true,否则返回false
     

      例:为防止stus为空报错可以加上判断如下:

    1. <#if stus??>
    2. <#list stus as stu>
    3. ......
    4. </#list>
    5. </#if>

      2.4.8 内建函数
     

      内建函数语法格式: `变量+?+函数名称`
     

      (1)求集合的大小
     

      `${集合名?size}`
     

      (2)日期格式化
     

      显示年月日: `${today?date}`

      显示时分秒:`${today?time}`

      显示日期+时间:`${today?datetime}`

      自定义格式化: `${today?string("yyyy年MM月")}`
     

      (3)内建函数`c`
     

      model.addAttribute("point", 102920122);
     

      point是数字型,使用${point}会显示这个数字的值,每三位使用逗号分隔。
     

      如果不想显示为每三位分隔的数字,可以使用c函数将数字型转成字符串输出
     

      `${point?c}`
     

      (4)将json字符串转成对象
     

      一个例子:
     

      其中用到了 assign标签,assign的作用是定义一个变量。

    1. <#assign text="{'bank':'工商银行','account':'10101920201920212'}" />
    2. <#assign data=text?eval />
    3. 开户行:${data.bank} 账号:${data.account}

      ```

      (5)常见内建函数汇总

    1. ?html:html字符转义
    2. ?cap_first: 字符串的第一个字母变为大写形式
    3. ?lower_case :字符串的小写形式
    4. ?upper_case :字符串的大写形式
    5. ?trim:去掉字符串首尾的空格
    6. ?substring(from,to):截字符串 from是第一个字符的开始索引,to最后一个字符之后的位置索引,当to为空时,默认的是字符串的长度
    7. ?lenth: 取长度
    8. ?size: 序列中元素的个数
    9. ?int: 数字的整数部分(比如 -1.9?int 就是 -1
    10. ?replace(param1,param2):字符串替换 param1是匹配的字符串 param2是将匹配的字符替换成指定字符

      内建函数测试demo1
     

      (1)在StudentController新增方法:

    1. @GetMapping("innerFunc")
    2. public String testInnerFunc(Model model) {
    3. //1.1 小强对象模型数据
    4. Student stu1 = new Student();
    5. stu1.setName("小强");
    6. stu1.setAge(18);
    7. stu1.setMoney(1000.86f);
    8. stu1.setBirthday(new Date());
    9. //1.2 小红对象模型数据
    10. Student stu2 = new Student();
    11. stu2.setName("小红");
    12. stu2.setMoney(200.1f);
    13. stu2.setAge(19);
    14. //1.3 将两个对象模型数据存放到List集合中
    15. List<Student> stus = new ArrayList<>();
    16. stus.add(stu1);
    17. stus.add(stu2);
    18. model.addAttribute("stus", stus);
    19. // 2.1 添加日期
    20. Date date = new Date();
    21. model.addAttribute("today", date);
    22. // 3.1 添加数值
    23. model.addAttribute("point", 102920122);
    24. return "04-innerFunc";
    25. }

      (2)在resources/templates目录下创建04-innerFunc.ftl模版页面:

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>inner Function</title>
    6. </head>
    7. <body>
    8. <b>获得集合大小</b><br>
    9. 集合大小:${stus?size}
    10. <hr>
    11. <b>获得日期</b><br>
    12. 显示年月日: ${today?date} <br>
    13. 显示时分秒:${today?time}<br>
    14. 显示日期+时间:${today?datetime}<br>
    15. 自定义格式化: ${today?string("yyyy年MM月")}<br>
    16. <hr>
    17. <b>内建函数C</b><br>
    18. 没有C函数显示的数值:${point} <br>
    19. 有C函数显示的数值:${point?c}
    20. <hr>
    21. <b>声明变量assign</b><br>
    22. <#assign text="{'bank':'工商银行','account':'10101920201920212'}" />
    23. <#assign data=text?eval />
    24. 开户行:${data.bank} 账号:${data.account}
    25. <hr>
    26. </body>
    27. </html>

      (3)测试
     

      浏览器访问http://localhost:8881/student/innerFunc
     

      效果如下

      内建函数测试demo2
     

      需求:遍历学生集合,显示集合总条数,id不要逗号隔开,显示学生的生日(只显示年月日),钱包显示整数并显示单位`元`,用户姓名做脱敏处理(如果是两个字第二个字显示为星号,例如张三显示为`张*`,如果大于两个字,中间字显示为星号,例如成吉思汗显示为`成*汗`,诸葛亮显示为`诸*亮`)
     

      (1)修改StudentController中的list方法,

    1. @GetMapping("list")
    2. public String list(Model model) throws ParseException {
    3. DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    4. List<Student> list = new ArrayList<>();
    5. list.add(new Student(1001,"张三",15, dateFormat.parse("2007-10-01 10:00:00"), 1000.11F));
    6. list.add(new Student(1002,"李四",28, dateFormat.parse("1994-10-01 10:00:00"), 5000.3F));
    7. list.add(new Student(1003,"王五",45, dateFormat.parse("1977-10-01 10:00:00"), 9000.63F));
    8. list.add(new Student(1004,"赵六",62, dateFormat.parse("1960-10-01 10:00:00"), 10000.99F));
    9. list.add(new Student(1005,"孙七",75, dateFormat.parse("1947-10-01 10:00:00"), 16000.66F));
    10. model.addAttribute("stus",list);
    11. return "02-list";
    12. }

      (2)修改02-list.ftl模版
     

      共${stus?size}条数据:输出总条数
     

      `stu.id`后面加`?c `:id不需要逗号分割
     

      `stu.birthday`后面加`?date`:生日只输出年月日
     

      `stu.money`后面加`?int`:金额取整
     

      姓名需要使用replace和substring函数处理
     

      完整内容如下
     

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>列表页面</title>
    6. <style>
    7. table{
    8. border-spacing: 0;/*把单元格间隙设置为0*/
    9. border-collapse: collapse;/*设置单元格的边框合并为1*/
    10. }
    11. td{
    12. border:1px solid #ACBED1;
    13. text-align: center;
    14. }
    15. </style>
    16. </head>
    17. <body>
    18. 共${stus?size}条数据
    19. <table>
    20. <tr>
    21. <td>序号</td>
    22. <td>id</td>
    23. <td>姓名</td>
    24. <td>所处的年龄段</td>
    25. <td>生日</td>
    26. <td>钱包</td>
    27. <td>是否最后一条数据</td>
    28. </tr>
    29. <#list stus as stu >
    30. <tr>
    31. <td>${stu_index + 1}</td>
    32. <td>${stu.id?c}</td>
    33. <td>
    34. <#if stu.name?length=2>
    35. ${stu.name?replace(stu.name?substring(1), "*")}
    36. <#else>
    37. ${stu.name?replace(stu.name?substring(1, stu.name?length-1), "*")}
    38. </#if>
    39. </td>
    40. <td>
    41. <#if stu.age <= 6>
    42. 童年
    43. <#elseif stu.age <= 17>
    44. 少年
    45. <#elseif stu.age <= 40>
    46. 青年
    47. <#elseif stu.age <= 65>
    48. 中年
    49. <#else>
    50. 老年
    51. </#if>
    52. </td>
    53. <td>${stu.birthday?date}</td>
    54. <td>${stu.money?int}元</td>
    55. <td>
    56. <#if stu_has_next>
    57. <#else>
    58. </#if>
    59. </td>
    60. </tr>
    61. </#list>
    62. </table>
    63. <hr>
    64. </body>
    65. </html>

      (3)测试
     

      浏览器访问http://localhost:8881/student/list
     

      效果如下
     

      2.4.9 静态化
     

      (1)springboot整合freemarker静态化文件用法
     

      编写springboot测试用例

    1. package com.itheima.test;
    2. import com.itheima.freemarker.FreemarkerDemoApplication;
    3. import com.itheima.freemarker.entity.Student;
    4. import freemarker.template.Configuration;
    5. import freemarker.template.Template;
    6. import freemarker.template.TemplateException;
    7. import org.junit.Test;
    8. import org.junit.runner.RunWith;
    9. import org.springframework.beans.factory.annotation.Autowired;
    10. import org.springframework.boot.test.context.SpringBootTest;
    11. import org.springframework.test.context.junit4.SpringRunner;
    12. import java.io.FileWriter;
    13. import java.io.IOException;
    14. import java.util.*;
    15. @SpringBootTest(classes = FreemarkerDemoApplication.class)
    16. @RunWith(SpringRunner.class)
    17. public class FreemarkerTest {
    18. //注入freemarker配置类
    19. @Autowired
    20. private Configuration configuration;
    21. @Test
    22. public void test() throws IOException, TemplateException {
    23. Template template = configuration.getTemplate("04-innerFunc.ftl");
    24. /**
    25. * 静态化并输出到文件中 参数1:数据模型 参数2:文件输出流
    26. */
    27. template.process(getData(), new FileWriter("d:/list.html"));
    28. /**
    29. * 静态化并输出到字节输出流中
    30. */
    31. //StringWriter out = new StringWriter();
    32. //template.process(getData(), out);
    33. //System.out.println(out.toString());
    34. }
    35. private Map getData(){
    36. Map<String,Object> map = new HashMap<>();
    37. Student stu1 = new Student();
    38. stu1.setName("小强");
    39. stu1.setAge(18);
    40. stu1.setMoney(1000.86f);
    41. stu1.setBirthday(new Date());
    42. //小红对象模型数据
    43. Student stu2 = new Student();
    44. stu2.setName("小红");
    45. stu2.setMoney(200.1f);
    46. stu2.setAge(19);
    47. //将两个对象模型数据存放到List集合中
    48. List<Student> stus = new ArrayList<>();
    49. stus.add(stu1);
    50. stus.add(stu2);
    51. //向model中存放List集合数据
    52. map.put("stus",stus);
    53. //map数据
    54. Map<String,Student> stuMap = new HashMap<>();
    55. stuMap.put("stu1",stu1);
    56. stuMap.put("stu2",stu2);
    57. map.put("stuMap",stuMap);
    58. //日期
    59. map.put("today",new Date());
    60. //长数值
    61. map.put("point",38473897438743L);
    62. return map;
    63. }
    64. }

      (2)freemarker原生静态化用法

    1. package com.itheima.freemarker.test;
    2. import com.itheima.freemarker.entity.Student;
    3. import freemarker.cache.FileTemplateLoader;
    4. import freemarker.cache.NullCacheStorage;
    5. import freemarker.template.Configuration;
    6. import freemarker.template.Template;
    7. import freemarker.template.TemplateException;
    8. import freemarker.template.TemplateExceptionHandler;
    9. import java.io.File;
    10. import java.io.FileWriter;
    11. import java.io.IOException;
    12. import java.util.*;
    13. public class FreemarkerTest {
    14. public static void main(String[] args) throws IOException, TemplateException {
    15. //创建配置类
    16. Configuration CONFIGURATION = new Configuration(Configuration.VERSION_2_3_22);
    17. //设置模版加载路径
    18. //ClassTemplateLoader方式:需要将模版放在FreemarkerTest类所在的包,加载模版时会从该包下加载
    19. //CONFIGURATION.setTemplateLoader(new ClassTemplateLoader(FreemarkerTest.class,""));
    20. String path = java.net.URLDecoder.decode(FreemarkerTest.class.getClassLoader().getResource("").getPath(),"utf-8");
    21. //FileTemplateLoader方式:需要将模版放置在classpath目录下 目录有中文也可以
    22. CONFIGURATION.setTemplateLoader(new FileTemplateLoader(new File(path)));
    23. //设置编码
    24. CONFIGURATION.setDefaultEncoding("UTF-8");
    25. //设置异常处理器
    26. CONFIGURATION.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
    27. //设置缓存方式
    28. CONFIGURATION.setCacheStorage(NullCacheStorage.INSTANCE);
    29. //加载模版
    30. Template template = CONFIGURATION.getTemplate("templates/04-innerFunc.ftl");
    31. /**
    32. * 静态化并输出到文件中 参数1:数据模型 参数2:文件输出流
    33. */
    34. template.process(getModel(), new FileWriter("d:/list.html"));
    35. /**
    36. * 静态化并输出到字节输出流中
    37. */
    38. //StringWriter out = new StringWriter();
    39. //template.process(getData(), out);
    40. //System.out.println(out.toString());
    41. }
    42. public static Map getModel(){
    43. Map map = new HashMap();
    44. //1.1 小强对象模型数据
    45. Student stu1 = new Student();
    46. stu1.setName("小强");
    47. stu1.setAge(18);
    48. stu1.setMoney(1000.86f);
    49. stu1.setBirthday(new Date());
    50. //1.2 小红对象模型数据
    51. Student stu2 = new Student();
    52. stu2.setName("小红");
    53. stu2.setMoney(200.1f);
    54. stu2.setAge(19);
    55. //1.3 将两个对象模型数据存放到List集合中
    56. List<Student> stus = new ArrayList<>();
    57. stus.add(stu1);
    58. stus.add(stu2);
    59. map.put("stus", stus);
    60. // 2.1 添加日期
    61. Date date = new Date();
    62. map.put("today", date);
    63. // 3.1 添加数值
    64. map.put("point", 102920122);
    65. return map;
    66. }
    67. }

      3 数据库元数据
     

      3.1 介绍
     

      元数据(Metadata)是描述数据的数据。
     

      数据库元数据(DatabaseMetaData)就是指定义数据库各类对象结构的数据。
     

      在mysql中可以通过show关键字获取相关的元数据

    1. show status; 获取数据库的状态
    2. show databases; 列出所有数据库
    3. show tables; 列出所有表
    4. show create database [数据库名]; 获取数据库的定义
    5. show create table [数据表名]; 获取数据表的定义
    6. show columns from <table_name>; 显示表的结构
    7. show index from <table_name>; 显示表中有关索引和索引列的信息
    8. show character set; 显示可用的字符集以及其默认整理
    9. show collation; 显示每个字符集的整理
    10. show variables; 列出数据库中的参数定义值

      也可以从 information_schema库中获取元数据,information_schema数据库是MySQL自带的信息数据库,它提供了访问数据库元数据的方式。存着其他数据库的信息。

    1. select schema_name from information_schema.schemata; 列出所有的库
    2. select table_name FROM information_schema.tables; 列出所有的表

      在代码中可以由JDBC的Connection对象通过getMetaData方法获取而来,主要封装了是对数据库本身的一些整体综合信息,例如数据库的产品名称,数据库的版本号,数据库的URL,是否支持事务等等。
     

      DatabaseMetaData的常用方法:

    1. getDatabaseProductName:获取数据库的产品名称
    2. getDatabaseProductName:获取数据库的版本号
    3. getUserName:获取数据库的用户名
    4. getURL:获取数据库连接的URL
    5. getDriverName:获取数据库的驱动名称
    6. driverVersion:获取数据库的驱动版本号
    7. isReadOnly:查看数据库是否只允许读操作
    8. supportsTransactions:查看数据库是否支持事务

      3.2 搭建环境
     

      (1)导入mysql依赖

    1. <dependency>
    2. <groupId>mysql</groupId>
    3. <artifactId>mysql-connector-java</artifactId>
    4. <version>5.1.47</version>
    5. </dependency>

      (2)创建测试用例

    1. package com.itheima.test;
    2. import org.junit.Before;
    3. import org.junit.Test;
    4. import java.sql.*;
    5. import java.util.Properties;
    6. public class DataBaseMetaDataTest {
    7. private Connection conn;
    8. @Before
    9. public void init() throws Exception {
    10. Properties pro = new Properties();
    11. pro.setProperty("user", "root");
    12. pro.setProperty("password", "123456");
    13. pro.put("useInformationSchema", "true");//获取mysql表注释
    14. //pro.setProperty("remarksReporting","true");//获取oracle表注释
    15. conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/?useUnicode=true&characterEncoding=UTF8", pro);
    16. }
    17. }

      3.3 综合信息元数据
     

      (1)获取数据库元信息综合信息

    1. @Test
    2. public void testDatabaseMetaData() throws SQLException {
    3. //获取数据库元数据
    4. DatabaseMetaData dbMetaData = conn.getMetaData();
    5. //获取数据库产品名称
    6. String productName = dbMetaData.getDatabaseProductName();
    7. System.out.println(productName);
    8. //获取数据库版本号
    9. String productVersion = dbMetaData.getDatabaseProductVersion();
    10. System.out.println(productVersion);
    11. //获取数据库用户名
    12. String userName = dbMetaData.getUserName();
    13. System.out.println(userName);
    14. //获取数据库连接URL
    15. String userUrl = dbMetaData.getURL();
    16. System.out.println(userUrl);
    17. //获取数据库驱动
    18. String driverName = dbMetaData.getDriverName();
    19. System.out.println(driverName);
    20. //获取数据库驱动版本号
    21. String driverVersion = dbMetaData.getDriverVersion();
    22. System.out.println(driverVersion);
    23. //查看数据库是否允许读操作
    24. boolean isReadOnly = dbMetaData.isReadOnly();
    25. System.out.println(isReadOnly);
    26. //查看数据库是否支持事务操作
    27. boolean supportsTransactions = dbMetaData.supportsTransactions();
    28. System.out.println(supportsTransactions);
    29. }

      (2)获取数据库列表

    1. @Test
    2. public void testFindAllCatalogs() throws Exception {
    3. //获取元数据
    4. DatabaseMetaData metaData = conn.getMetaData();
    5. //获取数据库列表
    6. ResultSet rs = metaData.getCatalogs();
    7. //遍历获取所有数据库表
    8. while (rs.next()) {
    9. //打印数据库名称
    10. System.out.println(rs.getString(1));
    11. }
    12. //释放资源
    13. rs.close();
    14. conn.close();
    15. }

      (3)获取某数据库中的所有表信息

    1. @Test
    2. public void testFindAllTable() throws Exception {
    3. //获取元数据
    4. DatabaseMetaData metaData = conn.getMetaData();
    5. //获取所有的数据库表信息
    6. ResultSet rs = metaData.getTables("库名", "%", "%", new String[]{"TABLE"});
    7. //拼装table
    8. while (rs.next()) {
    9. //所属数据库
    10. System.out.println(rs.getString(1));
    11. //所属schema
    12. System.out.println(rs.getString(2));
    13. //表名
    14. System.out.println(rs.getString(3));
    15. //数据库表类型
    16. System.out.println(rs.getString(4));
    17. //数据库表备注
    18. System.out.println(rs.getString(5));
    19. System.out.println("--------------");
    20. }
    21. }

      (4)获取某张表所有的列信息

    1. @Test
    2. public void testFindAllColumns() throws Exception {
    3. //获取元数据
    4. DatabaseMetaData metaData = conn.getMetaData();
    5. //获取所有的数据库某张表所有列信息
    6. ResultSet rs = metaData.getColumns("库名", "%", "表名","%");
    7. while(rs.next()) {
    8. //表名
    9. System.out.println(rs.getString("TABLE_NAME"));
    10. //列名
    11. System.out.println(rs.getString("COLUMN_NAME"));
    12. //类型码值
    13. System.out.println(rs.getString("DATA_TYPE"));
    14. //类型名称
    15. System.out.println(rs.getString("TYPE_NAME"));
    16. //列的大小
    17. System.out.println(rs.getString("COLUMN_SIZE"));
    18. //小数部分位数,不适用的类型会返回null
    19. System.out.println(rs.getString("DECIMAL_DIGITS"));
    20. //是否允许使用null
    21. System.out.println(rs.getString("NULLABLE"));
    22. //列的注释信息
    23. System.out.println(rs.getString("REMARKS"));
    24. //默认值
    25. System.out.println(rs.getString("COLUMN_DEF"));
    26. //是否自增
    27. System.out.println(rs.getString("IS_AUTOINCREMENT"));
    28. //表中的列的索引(从 1 开始
    29. System.out.println(rs.getString("ORDINAL_POSITION"));
    30. System.out.println("--------------");
    31. }
    32. }

      3.4 参数元数据
     

      参数元数据(ParameterMetaData):是由PreparedStatement对象通过getParameterMetaData方法获取而

      来,主要是针对PreparedStatement对象和其预编译的SQL命令语句提供一些信息,ParameterMetaData能提供占位符参数的个数,获取指定位置占位符的SQL类型等等
     

      以下有一些关于ParameterMetaData的常用方法:

      ```

      getParameterCount:获取预编译SQL语句中占位符参数的个数

      ```

    1. @Test
    2. public void testParameterMetaData() throws Exception {
    3. String sql = "select * from health.t_checkgroup where id=? and code=?";
    4. PreparedStatement pstmt = conn.prepareStatement(sql);
    5. pstmt.setString(1, "7");
    6. pstmt.setString(2, "0003");
    7. //获取ParameterMetaData对象
    8. ParameterMetaData paramMetaData = pstmt.getParameterMetaData();
    9. //获取参数个数
    10. int paramCount = paramMetaData.getParameterCount();
    11. System.out.println(paramCount);
    12. }

      3.5 结果集元数据
     

      结果集元数据(ResultSetMetaData):是由ResultSet对象通过getMetaData方法获取而来,主要是针对由数据库执行的SQL脚本命令获取的结果集对象ResultSet中提供的一些信息,比如结果集中的列数、指定列的名称、指定列的SQL类型等等,可以说这个是对于框架来说非常重要的一个对象。
     

      以下有一些关于ResultSetMetaData的常用方法:
     

      ```

      getColumnCount:获取结果集中列项目的个数

      getColumnType:获取指定列的SQL类型对应于Java中Types类的字段

      getColumnTypeName:获取指定列的SQL类型

      getClassName:获取指定列SQL类型对应于Java中的类型(包名加类名

      ```

    1. @Test
    2. public void testResultSetMetaData() throws Exception {
    3. String sql = "select * from health.t_checkgroup where id=?";
    4. PreparedStatement pstmt = conn.prepareStatement(sql);
    5. pstmt.setString(1, "7");
    6. //执行sql语句
    7. ResultSet rs = pstmt.executeQuery();
    8. //获取ResultSetMetaData对象
    9. ResultSetMetaData metaData = rs.getMetaData();
    10. //获取查询字段数量
    11. int columnCount = metaData.getColumnCount();
    12. System.out.println("字段总数量:"+ columnCount);
    13. for (int i = 1; i <= columnCount; i++) {
    14. //获取表名称
    15. System.out.println(metaData.getColumnName(i));
    16. //获取java类型
    17. System.out.println(metaData.getColumnClassName(i));
    18. //获取sql类型
    19. System.out.println(metaData.getColumnTypeName(i));
    20. System.out.println("----------");
    21. }
    22. }

      4 代码生成器环境搭建
     

      4.1 创建maven工程
     

      创建maven工程并导入以下依赖

    1. <properties>
    2. <java.version>11</java.version>
    3. <!-- 项目源码及编译输出的编码 -->
    4. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    5. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    6. <!-- 项目编译JDK版本 -->
    7. <maven.compiler.source>11</maven.compiler.source>
    8. <maven.compiler.target>11</maven.compiler.target>
    9. </properties>
    10. <dependencies>
    11. <dependency>
    12. <groupId>org.freemarker</groupId>
    13. <artifactId>freemarker</artifactId>
    14. <version>2.3.23</version>
    15. </dependency>
    16. <dependency>
    17. <groupId>mysql</groupId>
    18. <artifactId>mysql-connector-java</artifactId>
    19. <version>5.1.47</version>
    20. </dependency>
    21. <dependency>
    22. <groupId>org.projectlombok</groupId>
    23. <artifactId>lombok</artifactId>
    24. <version>1.18.8</version>
    25. </dependency>
    26. <dependency>
    27. <groupId>org.apache.commons</groupId>
    28. <artifactId>commons-lang3</artifactId>
    29. <version>3.10</version>
    30. </dependency>
    31. </dependencies>

      目录结构如下

      4.2 编码
     

      4.2.1 常量类

    1. package freemarker.constant;
    2. public class TemplateConstant {
    3. //实体类模板
    4. public static final String entityTemplate = "templates/Entity.ftl";
    5. //Mapper模板
    6. public static final String mapperTemplate = "templates/Mapper.ftl";
    7. //Mapper映射文件模版
    8. public static final String mapperXmlTemplate = "templates/MapperXml.ftl";
    9. //service模版
    10. public static final String serviceTemplate = "templates/Service.ftl";
    11. //service实现类模版
    12. public static final String serviceImplTemplate = "templates/ServiceImpl.ftl";
    13. //controller模版
    14. public static final String controllerTemplate = "templates/Controller.ftl";
    15. //vo模版
    16. public static final String entityVoTemplate = "templates/EntityVo.ftl";
    17. //dto模版
    18. public static final String entityDtoTemplate = "templates/EntityDto.ftl";
    19. //pom模版
    20. public static final String pomTemplate = "templates/pom.ftl";
    21. //application.yml模版
    22. public static final String applicationTemplate = "templates/application.ftl";
    23. }

      4.2.2 工具类
     

      (1)DbUtil数据库工具类

    1. package freemarker.util;
    2. import freemarker.param.ColumnClass;
    3. import freemarker.param.TableClass;
    4. import lombok.Getter;
    5. import lombok.Setter;
    6. import java.sql.*;
    7. import java.util.ArrayList;
    8. import java.util.List;
    9. import java.util.Properties;
    10. /**
    11. * 数据库工具类
    12. */
    13. @Setter
    14. @Getter
    15. public class DbUtil {
    16. //数据库连接地址
    17. private String url = "jdbc:mysql://localhost:3306/heima_leadnews_wemedia?useSSL=false&nullCatalogMeansCurrent=true&serverTimezone=UTC";
    18. //数据库用户名
    19. private String username = "root";
    20. //数据库密码
    21. private String password = "123456";
    22. //数据库驱动
    23. private String driver = "com.mysql.jdbc.Driver";
    24. //数据库名称
    25. private String dbName = null;
    26. private Connection connection =null;
    27. /**
    28. * 获取jdbc链接
    29. * @return
    30. * @throws Exception
    31. */
    32. public Connection getConnection() throws Exception{
    33. Properties pro = new Properties();
    34. pro.setProperty("user", username);
    35. pro.setProperty("password", password);
    36. pro.put("useInformationSchema", "true");//获取mysql表注释
    37. //pro.setProperty("remarksReporting","true");//获取oracle表注释
    38. Class.forName(driver);
    39. connection = DriverManager.getConnection(url, pro);
    40. return connection;
    41. }
    42. /**
    43. * 获取当前数据库下的所有表名称及注释
    44. * @return
    45. * @throws Exception
    46. */
    47. public List<TableClass> getAllTables() throws Exception {
    48. List<TableClass> list = new ArrayList<>();
    49. //获取链接
    50. Connection conn = getConnection();
    51. //获取元数据
    52. DatabaseMetaData metaData = conn.getMetaData();
    53. //获取所有的数据库表信息
    54. ResultSet rs = metaData.getTables(dbName!=null?dbName:conn.getCatalog(), "%", "%", new String[]{"TABLE"});
    55. while (rs.next()) {
    56. TableClass tableClass = new TableClass();
    57. tableClass.setTableName(rs.getString(3));
    58. tableClass.setTableComment(rs.getString(5));
    59. list.add(tableClass);
    60. }
    61. return list;
    62. }
    63. /**
    64. * 获取某张表的所有列
    65. * @param tableName
    66. * @return
    67. * @throws Exception
    68. */
    69. public List<ColumnClass> getAllColumns(String tableName) throws Exception {
    70. List<ColumnClass> list = new ArrayList<>();
    71. //获取链接
    72. Connection conn = getConnection();
    73. //获取元数据
    74. DatabaseMetaData metaData = conn.getMetaData();
    75. //获取所有的数据库某张表所有列信息
    76. ResultSet rs = metaData.getColumns(dbName!=null?dbName:conn.getCatalog(), "%", tableName,"%");
    77. while(rs.next()) {
    78. ColumnClass columnClass = new ColumnClass();
    79. columnClass.setColumnName(rs.getString("COLUMN_NAME"));
    80. columnClass.setColumnType(rs.getString("TYPE_NAME"));
    81. columnClass.setColumnComment(rs.getString("REMARKS"));
    82. columnClass.setChangeColumnName(StrUtil.changeColumnStr(rs.getString("COLUMN_NAME")));
    83. list.add(columnClass);
    84. }
    85. return list;
    86. }
    87. /**
    88. * 关闭链接
    89. */
    90. public void closeConnection(){
    91. try {
    92. connection.close();
    93. } catch (SQLException e) {
    94. e.printStackTrace();
    95. }
    96. };
    97. }

      (2)字符串处理工具类

    1. package freemarker.util;
    2. /**
    3. * 字符串处理工具类
    4. */
    5. public class StrUtil {
    6. /**
    7. * 去掉下划线转驼峰 user_name -> userName
    8. * @param str
    9. * @return
    10. */
    11. public static String changeColumnStr(String str) {
    12. String name = str;
    13. if (name.indexOf("_") > 0 && name.length() != name.indexOf("_") + 1) {
    14. int lengthPlace = name.indexOf("_");
    15. name = name.replaceFirst("_", "");
    16. String s = name.substring(lengthPlace, lengthPlace + 1);
    17. s = s.toUpperCase();
    18. str = name.substring(0, lengthPlace) + s + name.substring(lengthPlace + 1);
    19. } else {
    20. return str;
    21. }
    22. return changeColumnStr(str);
    23. }
    24. /**
    25. * 去掉下划线转驼峰 tb_user -> TbUser
    26. * @param str
    27. * @return
    28. */
    29. public static String changeTableStr(String str) {
    30. String s = changeColumnStr(str);
    31. return s.substring(0,1).toUpperCase()+s.substring(1);
    32. }
    33. }

      (3)FreeMarker模版工具类

    1. package freemarker.util;
    2. import freemarker.cache.FileTemplateLoader;
    3. import freemarker.cache.NullCacheStorage;
    4. import freemarker.template.Configuration;
    5. import freemarker.template.Template;
    6. import freemarker.template.TemplateExceptionHandler;
    7. import java.io.File;
    8. import java.io.IOException;
    9. import java.io.UnsupportedEncodingException;
    10. /**
    11. * FreeMarker模版工具类
    12. */
    13. public class FreeMarkerTemplateUtils {
    14. private FreeMarkerTemplateUtils(){}
    15. private static final Configuration CONFIGURATION = new Configuration(Configuration.VERSION_2_3_22);
    16. static{
    17. //ClassTemplateLoader方式:需要将模版放在FreeMarkerTemplateUtils类所在的包,加载模版时会从该包下加载
    18. //CONFIGURATION.setTemplateLoader(new ClassTemplateLoader(FreeMarkerTemplateUtils.class,""));
    19. try {
    20. String path = java.net.URLDecoder.decode(FreeMarkerTemplateUtils.class.getClassLoader().getResource("").getPath(),"utf-8");
    21. //FileTemplateLoader方式:需要将模版放置在classpath目录下 目录有中文也可以
    22. CONFIGURATION.setTemplateLoader(new FileTemplateLoader(new File(path)));
    23. } catch (UnsupportedEncodingException e) {
    24. e.printStackTrace();
    25. } catch (IOException e) {
    26. e.printStackTrace();
    27. }
    28. CONFIGURATION.setDefaultEncoding("UTF-8");
    29. CONFIGURATION.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
    30. CONFIGURATION.setCacheStorage(NullCacheStorage.INSTANCE);
    31. }
    32. public static Template getTemplate(String templateName) throws IOException {
    33. try {
    34. return CONFIGURATION.getTemplate(templateName);
    35. } catch (IOException e) {
    36. throw e;
    37. }
    38. }
    39. public static void clearCache() {
    40. CONFIGURATION.clearTemplateCache();
    41. }
    42. }

      4.2.3 实体类
     

      (1)表实体类

    1. package freemarker.param;
    2. import lombok.Data;
    3. @Data
    4. public class TableClass {
    5. /**
    6. * 表名 tb_user
    7. **/
    8. private String tableName;
    9. /**
    10. * 表注释
    11. **/
    12. private String tableComment;
    13. }

      (2)列实体类

    1. package freemarker.param;
    2. import lombok.Data;
    3. @Data
    4. public class ColumnClass {
    5. /**
    6. * 数据库字段名称 user_name
    7. **/
    8. private String columnName;
    9. /**
    10. * 数据库字段类型
    11. **/
    12. private String columnType;
    13. /**
    14. * 数据库字段首字母小写且去掉下划线字符串 userName
    15. **/
    16. private String changeColumnName;
    17. /**
    18. * 数据库字段注释
    19. **/
    20. private String columnComment;
    21. }

      (3)模版相关参数类

    1. package freemarker.param;
    2. import lombok.Data;
    3. import org.apache.commons.lang3.StringUtils;
    4. import java.text.SimpleDateFormat;
    5. import java.util.Date;
    6. @Data
    7. public class TemplatePathParam {
    8. private String currentDate = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
    9. //包名 com.itheima.user
    10. private String packageName;
    11. //代码生成路径 D:\\path
    12. private String basePath;
    13. //项目名称 英文 比如itheima-user
    14. private String projectName;
    15. //作者
    16. private String author ;
    17. //实体类生成的绝对路径
    18. private String entityPath;
    19. //vo实体类生成的绝对路径
    20. private String entityVoPath;
    21. //Dto实体类生成的绝对路径
    22. private String entityDtoPath;
    23. //mapper生成绝对路径
    24. private String mapperPath;
    25. //mapper映射文件生成的绝对路径
    26. private String mapperXmlPath;
    27. //service接口生成的绝对路径
    28. private String servicePath;
    29. //service实现类生成的绝对路径
    30. private String serviceImplPath;
    31. //controller生成的绝对路径
    32. private String controllerPath;
    33. //pom文件生成的绝对路径
    34. private String pomPath;
    35. //application.yml文件生成的绝对路径
    36. private String applicationYmlPath;
    37. public TemplatePathParam(String packageName, String basePath, String projectName, String author) {
    38. if(StringUtils.isBlank(packageName)
    39. || StringUtils.isBlank(basePath)
    40. || StringUtils.isBlank(author)
    41. || StringUtils.isBlank(projectName)){
    42. throw new RuntimeException("参数不能为空");
    43. }
    44. this.packageName = packageName;
    45. this.basePath = basePath;
    46. this.author = author;
    47. this.projectName = projectName;
    48. String[] split = packageName.split("\\.");
    49. // D:\\path\\itheima-user\\src\\main\\java\\com\\itheima\\user
    50. String javaModelPath = basePath+"\\"+projectName+"\\src\\main\\java\\"+split[0]+"\\"+split[1]+"\\"+split[2];
    51. String xmlModelPath = basePath+"\\"+projectName+"\\src\\main\\resources\\"+split[0]+"\\"+split[1]+"\\"+split[2];
    52. this.setEntityPath(javaModelPath+"\\entity");
    53. this.setMapperPath(javaModelPath+"\\mapper");
    54. this.setMapperXmlPath(xmlModelPath+"\\mapper");
    55. this.setServicePath(javaModelPath+"\\service");
    56. this.setServiceImplPath(javaModelPath+"\\service\\impl");
    57. this.setControllerPath(javaModelPath+"\\http\\controller");
    58. this.setEntityVoPath(javaModelPath+"\\http\\vo");
    59. this.setEntityDtoPath(javaModelPath+"\\http\\dto");
    60. this.setEntityDtoPath(javaModelPath+"\\http\\dto");
    61. this.setPomPath(basePath+"\\"+projectName);
    62. this.setApplicationYmlPath(basePath+"\\"+projectName+"\\src\\main\\resources");
    63. }
    64. }

      4.2.4 代码生成器入口类

    1. package freemarker;
    2. import freemarker.constant.TemplateConstant;
    3. import freemarker.param.ColumnClass;
    4. import freemarker.param.TableClass;
    5. import freemarker.param.TemplatePathParam;
    6. import freemarker.template.Template;
    7. import freemarker.util.DbUtil;
    8. import freemarker.util.FreeMarkerTemplateUtils;
    9. import freemarker.util.StrUtil;
    10. import org.apache.commons.lang3.StringUtils;
    11. import java.io.*;
    12. import java.util.HashMap;
    13. import java.util.List;
    14. import java.util.Map;
    15. /**
    16. * 代码生成器入口
    17. */
    18. public class CodeGenerateUtils {
    19. private TemplatePathParam templatePathParam = null;
    20. public static void main(String[] args) throws Exception{
    21. CodeGenerateUtils codeGenerateUtils = new CodeGenerateUtils();
    22. codeGenerateUtils.generate();
    23. System.out.println("============ 全部生成完成! =============");
    24. }
    25. public void generate() throws Exception{
    26. /**
    27. * 参数1:报名
    28. * 参数2:生成代码的基础路径
    29. * 参数3:项目名称
    30. * 参数4:作者
    31. */
    32. templatePathParam = new TemplatePathParam("com.itheima.wemedia",
    33. "D:\\heima\\技术文章\\代码",
    34. "itheima-wemedia",
    35. "kdm");
    36. //数据库相关
    37. DbUtil dbUtil = new DbUtil();
    38. //获取所有表
    39. List<TableClass> allTable = dbUtil.getAllTables();
    40. for (TableClass tableClass : allTable) {
    41. //表名
    42. String table = tableClass.getTableName();
    43. //获取所有列
    44. List<ColumnClass> allColumns = dbUtil.getAllColumns(table);
    45. System.out.println("-------- 正在生成 " + table+" 表相关文件------");
    46. //生成实体类
    47. System.out.println("生成实体类");
    48. generateEntityFile(tableClass, allColumns);
    49. //生成Mapper
    50. System.out.println("生成Mapper");
    51. generateMapperFile(tableClass, allColumns);
    52. //生成Mapper.xml
    53. System.out.println("生成Mapper映射文件");
    54. generateMapperXmlFile(tableClass, allColumns);
    55. //生成service接口
    56. System.out.println("生成service接口");
    57. generateServiceFile(tableClass, allColumns);
    58. //生成service实现类
    59. System.out.println("生成service实现类");
    60. generateServiceImplFile(tableClass, allColumns);
    61. //生成Controller层文件
    62. System.out.println("生成Controller层文件");
    63. generateControllerFile(tableClass, allColumns);
    64. //生成vo类
    65. System.out.println("生成vo类");
    66. generateEntityVoFile(tableClass, allColumns);
    67. //生成dto类
    68. System.out.println("生成dto类");
    69. generateEntityDtoFile(tableClass, allColumns);
    70. //生成pom文件
    71. System.out.println("生成pom文件");
    72. generatePomFile(tableClass, allColumns);
    73. //生成application.yml文件
    74. System.out.println("生成application.yml文件");
    75. generateApplicationYmlFile(tableClass, allColumns);
    76. }
    77. dbUtil.closeConnection();
    78. }
    79. /**
    80. * 生成实体文件
    81. */
    82. private void generateEntityFile(TableClass tableClass, List<ColumnClass> allColumns) throws Exception{
    83. String suffix = ".java";
    84. String filePath = templatePathParam.getEntityPath();
    85. String file = templatePathParam.getEntityPath() + "\\"+ StrUtil.changeTableStr(tableClass.getTableName()) + suffix;
    86. Map<String,Object> dataMap = new HashMap<String,Object>();
    87. dataMap.put("model_column",allColumns);
    88. dataMap = getCommonModel(dataMap, tableClass);
    89. generateFileByTemplate(TemplateConstant.entityTemplate, filePath, file, dataMap);
    90. }
    91. /**
    92. * 生成mapper文件
    93. */
    94. private void generateMapperFile(TableClass tableClass, List<ColumnClass> allColumns) throws Exception{
    95. String suffix = "Mapper.java";
    96. String filePath = templatePathParam.getMapperPath();
    97. String file = templatePathParam.getMapperPath() + "\\"+ StrUtil.changeTableStr(tableClass.getTableName()) + suffix;
    98. Map<String,Object> dataMap = new HashMap<String,Object>();
    99. dataMap = getCommonModel(dataMap, tableClass);
    100. generateFileByTemplate(TemplateConstant.mapperTemplate, filePath, file, dataMap);
    101. }
    102. /**
    103. * 生成xml映射文件
    104. */
    105. private void generateMapperXmlFile(TableClass tableClass, List<ColumnClass> allColumns) throws Exception{
    106. String suffix = "Mapper.xml";
    107. String filePath = templatePathParam.getMapperXmlPath();
    108. String file = templatePathParam.getMapperXmlPath() + "\\"+ StrUtil.changeTableStr(tableClass.getTableName()) + suffix;
    109. Map<String,Object> dataMap = new HashMap<String,Object>();
    110. dataMap = getCommonModel(dataMap, tableClass);
    111. generateFileByTemplate(TemplateConstant.mapperXmlTemplate, filePath, file, dataMap);
    112. }
    113. /**
    114. * 生成业务接口层
    115. */
    116. private void generateServiceFile(TableClass tableClass, List<ColumnClass> allColumns) throws Exception{
    117. String suffix = "Service.java";
    118. String filePath = templatePathParam.getServicePath();
    119. String file = templatePathParam.getServicePath() + "\\"+ StrUtil.changeTableStr(tableClass.getTableName()) + suffix;
    120. Map<String,Object> dataMap = new HashMap<String,Object>();
    121. dataMap = getCommonModel(dataMap, tableClass);
    122. generateFileByTemplate(TemplateConstant.serviceTemplate, filePath, file, dataMap);
    123. }
    124. /**
    125. * 生成业务实现层
    126. */
    127. private void generateServiceImplFile(TableClass tableClass, List<ColumnClass> allColumns) throws Exception{
    128. String suffix = "ServiceImpl.java";
    129. String filePath = templatePathParam.getServiceImplPath();
    130. String file = templatePathParam.getServiceImplPath() + "\\"+ StrUtil.changeTableStr(tableClass.getTableName()) + suffix;
    131. Map<String,Object> dataMap = new HashMap<String,Object>();
    132. dataMap = getCommonModel(dataMap, tableClass);
    133. generateFileByTemplate(TemplateConstant.serviceImplTemplate, filePath, file, dataMap);
    134. }
    135. /**
    136. * 生成控制层
    137. */
    138. private void generateControllerFile(TableClass tableClass, List<ColumnClass> allColumns) throws Exception{
    139. String suffix = "Controller.java";
    140. String filePath = templatePathParam.getControllerPath();
    141. String file = templatePathParam.getControllerPath() + "\\"+ StrUtil.changeTableStr(tableClass.getTableName()) + suffix;
    142. Map<String,Object> dataMap = new HashMap<String,Object>();
    143. dataMap = getCommonModel(dataMap, tableClass);
    144. generateFileByTemplate(TemplateConstant.controllerTemplate, filePath, file, dataMap);
    145. }
    146. /**
    147. * 生成Vo类
    148. */
    149. private void generateEntityVoFile(TableClass tableClass, List<ColumnClass> allColumns) throws Exception{
    150. String suffix = "Vo.java";
    151. String filePath = templatePathParam.getEntityVoPath();
    152. String file = templatePathParam.getEntityVoPath() + "\\"+ StrUtil.changeTableStr(tableClass.getTableName()) + suffix;
    153. Map<String,Object> dataMap = new HashMap<String,Object>();
    154. dataMap.put("model_column",allColumns);
    155. dataMap = getCommonModel(dataMap, tableClass);
    156. generateFileByTemplate(TemplateConstant.entityVoTemplate, filePath, file, dataMap);
    157. }
    158. /**
    159. * 生成Dto类
    160. */
    161. private void generateEntityDtoFile(TableClass tableClass, List<ColumnClass> allColumns) throws Exception{
    162. String suffix = "Dto.java";
    163. String filePath = templatePathParam.getEntityDtoPath();
    164. String file = templatePathParam.getEntityDtoPath() + "\\"+ StrUtil.changeTableStr(tableClass.getTableName()) + suffix;
    165. Map<String,Object> dataMap = new HashMap<String,Object>();
    166. dataMap.put("model_column",allColumns);
    167. dataMap = getCommonModel(dataMap, tableClass);
    168. generateFileByTemplate(TemplateConstant.entityDtoTemplate, filePath, file, dataMap);
    169. }
    170. /**
    171. * 生成Pom文件
    172. */
    173. private void generatePomFile(TableClass tableClass, List<ColumnClass> allColumns) throws Exception{
    174. String suffix = "pom.xml";
    175. String filePath = templatePathParam.getPomPath();
    176. String file = templatePathParam.getPomPath() + "\\" + suffix;
    177. Map<String,Object> dataMap = new HashMap<String,Object>();
    178. dataMap = getCommonModel(dataMap, tableClass);
    179. generateFileByTemplate(TemplateConstant.pomTemplate, filePath, file, dataMap);
    180. }
    181. /**
    182. * 生成application.yml文件
    183. */
    184. private void generateApplicationYmlFile(TableClass tableClass, List<ColumnClass> allColumns) throws Exception{
    185. String suffix = "application.yml";
    186. String filePath = templatePathParam.getApplicationYmlPath();
    187. String file = templatePathParam.getApplicationYmlPath() + "\\" + suffix;
    188. Map<String,Object> dataMap = new HashMap<String,Object>();
    189. dataMap = getCommonModel(dataMap, tableClass);
    190. generateFileByTemplate(TemplateConstant.applicationTemplate, filePath, file, dataMap);
    191. }
    192. /**
    193. * 模版通用参数
    194. * @param dataMap 模型map
    195. * @param tableClass 表名和表注释参数
    196. * @return
    197. */
    198. public Map<String,Object> getCommonModel(Map<String,Object> dataMap, TableClass tableClass){
    199. dataMap.put("table_name", StrUtil.changeTableStr(tableClass.getTableName()));//TbUser
    200. dataMap.put("table_name_small",StrUtil.changeColumnStr(tableClass.getTableName()));//tbUser
    201. dataMap.put("table",tableClass.getTableName());//tb_user
    202. dataMap.put("author",templatePathParam.getAuthor());
    203. dataMap.put("date",templatePathParam.getCurrentDate());
    204. dataMap.put("package_name",templatePathParam.getPackageName());
    205. dataMap.put("project_name",templatePathParam.getProjectName());
    206. dataMap.put("table_annotation", StringUtils.isNotBlank(tableClass.getTableComment()) ? tableClass.getTableComment() : null);
    207. return dataMap;
    208. }
    209. /**
    210. * 静态化方法
    211. * @param templateName 模版名称
    212. * @param filePathParam 文件所在目录 绝对路径
    213. * @param fileParam 文件 绝对路径
    214. * @param dataMap 数据模型
    215. * @throws Exception
    216. */
    217. private void generateFileByTemplate(final String templateName,
    218. String filePathParam,
    219. String fileParam,
    220. Map<String,Object> dataMap) throws Exception{
    221. Template template = FreeMarkerTemplateUtils.getTemplate(templateName);
    222. System.out.println(fileParam);
    223. //文件夹不存在创建文件夹
    224. File filePath = new File(filePathParam);
    225. if (!filePath.exists() && !filePath.isDirectory())
    226. {
    227. filePath.mkdirs();
    228. }
    229. //文件不存在创建文件夹
    230. File file = new File(fileParam);
    231. if(!file.exists())
    232. {
    233. try {
    234. file.createNewFile();
    235. } catch (IOException e) {
    236. e.printStackTrace();
    237. }
    238. }
    239. FileOutputStream fos = new FileOutputStream(file);
    240. Writer out = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"),10240);
    241. template.process(dataMap,out);
    242. }
    243. }

      5 制作通用模版
     

      在 resources/templates 目录下创建模版类
     

      5.1 实体类模版

    1. package ${package_name}.entity;
    2. import com.baomidou.mybatisplus.annotation.TableField;
    3. import com.baomidou.mybatisplus.annotation.TableId;
    4. import com.baomidou.mybatisplus.annotation.TableName;
    5. import lombok.Data;
    6. import lombok.ToString;
    7. import java.util.Date;
    8. import java.math.BigDecimal;
    9. import com.fasterxml.jackson.annotation.JsonFormat;
    10. import java.io.Serializable;
    11. /**
    12. * 描述:<#if table_annotation??>${table_annotation}模型</#if>
    13. * @author ${author}
    14. * @date ${date}
    15. */
    16. @Data
    17. @ToString(callSuper = true)
    18. @TableName("${table}")
    19. public class ${table_name} implements Serializable {
    20. <#if model_column?exists>
    21. <#list model_column as model>
    22. /**
    23. * ${model.columnComment!}
    24. */
    25. <#if (model.columnType = 'BIGINT' && model.columnName = 'id')>
    26. @TableId("${model.columnName?uncap_first}")
    27. private Long ${model.changeColumnName?uncap_first};
    28. </#if>
    29. <#if (model.columnType = 'BIGINT' && model.columnName != 'id')>
    30. @TableField("${model.columnName?uncap_first}")
    31. private Long ${model.changeColumnName?uncap_first};
    32. </#if>
    33. <#if (model.columnType = 'INT' || model.columnType = 'INT UNSIGNED' || model.columnType = 'TINYINT' || model.columnType = 'TINYINT UNSIGNED')>
    34. @TableField("${model.columnName?uncap_first}")
    35. private Integer ${model.changeColumnName?uncap_first};
    36. </#if>
    37. <#if (model.columnType = 'DECIMAL')>
    38. @TableField("${model.columnName?uncap_first}")
    39. private BigDecimal ${model.changeColumnName?uncap_first};
    40. </#if>
    41. <#if (model.columnType = 'VARCHAR' || model.columnType = 'TEXT' || model.columnType = 'CHAR')>
    42. @TableField("${model.columnName?uncap_first}")
    43. private String ${model.changeColumnName?uncap_first};
    44. </#if>
    45. <#if model.columnType = 'TIMESTAMP' || model.columnType = 'YEAR' || model.columnType = 'DATE' || model.columnType = 'DATETIME' >
    46. @TableField("${model.columnName?uncap_first}")
    47. @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
    48. private Date ${model.changeColumnName?uncap_first};
    49. </#if>
    50. <#if (model.columnType != 'BIGINT'
    51. && model.columnType != 'INT'
    52. && model.columnType != 'DECIMAL'
    53. && model.columnType != 'VARCHAR'
    54. && model.columnType != 'TEXT'
    55. && model.columnType != 'CHAR'
    56. && model.columnType != 'TIMESTAMP'
    57. && model.columnType != 'YEAR'
    58. && model.columnType != 'DATE'
    59. && model.columnType != 'DATETIME'
    60. && model.columnType != 'INT UNSIGNED'
    61. && model.columnType != 'TINYINT'
    62. && model.columnType != 'TINYINT UNSIGNED')>
    63. @TableField("${model.columnName?uncap_first}")
    64. private MISS ${model.changeColumnName?uncap_first};
    65. </#if>
    66. </#list>
    67. </#if>
    68. }

      5.2 Mapper模版

    1. package ${package_name}.mapper;
    2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    3. import ${package_name}.entity.${table_name};
    4. import org.apache.ibatis.annotations.Mapper;
    5. /**
    6. * 描述:<#if table_annotation??>${table_annotation}数据库连接层</#if>
    7. * @author ${author}
    8. * @date ${date}
    9. */
    10. @Mapper
    11. public interface ${table_name}Mapper extends BaseMapper<${table_name}> {
    12. }

      5.3 Mapper映射文件模版

    1. "1.0" encoding="UTF-8" ?>
    2. mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    3. <mapper namespace="${package_name}.mapper.${table_name}Mapper">
    4. mapper>

      5.4 Service接口模版

    1. package ${package_name}.service;
    2. import ${package_name}.entity.${table_name};
    3. import com.baomidou.mybatisplus.extension.service.IService;
    4. /**
    5. * 描述:<#if table_annotation??>${table_annotation}服务实现层接口</#if>
    6. * @author ${author}
    7. * @date ${date}
    8. */
    9. public interface ${table_name}Service extends IService<${table_name}>{
    10. }

      5.5 Service实现类模版

    1. package ${package_name}.service.impl;
    2. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    3. import ${package_name}.entity.${table_name};
    4. import ${package_name}.service.${table_name}Service;
    5. import ${package_name}.mapper.${table_name}Mapper;
    6. import lombok.extern.slf4j.Slf4j;
    7. import org.springframework.stereotype.Service;
    8. /**
    9. * 描述:<#if table_annotation??>${table_annotation}服务实现层</#if>
    10. * @author ${author}
    11. * @date ${date}
    12. */
    13. @Slf4j
    14. @Service
    15. public class ${table_name}ServiceImpl extends ServiceImpl<${table_name}Mapper, ${table_name}> implements ${table_name}Service{
    16. }

      5.6 Controller模版

    1. package ${package_name}.http.controller;
    2. import org.springframework.web.bind.annotation.*;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.beans.BeanUtils;
    5. import org.springframework.validation.annotation.Validated;
    6. import ${package_name}.entity.${table_name};
    7. import ${package_name}.service.${table_name}Service;
    8. import ${package_name}.http.vo.${table_name}Vo;
    9. import ${package_name}.http.dto.${table_name}Dto;
    10. import java.util.List;
    11. /**
    12. * 描述:<#if table_annotation??>${table_annotation}控制层</#if>
    13. * @author ${author}
    14. * @date ${date}
    15. */
    16. @RestController
    17. @RequestMapping("/${table_name_small}")
    18. public class ${table_name}Controller {
    19. @Autowired
    20. private ${table_name}Service ${table_name_small}Service;
    21. /**
    22. * 查询所有
    23. */
    24. @GetMapping
    25. public List<${table_name}> list(){
    26. return ${table_name_small}Service.list();
    27. }
    28. /**
    29. * 查询一个
    30. */
    31. @GetMapping("/{id}")
    32. public ${table_name} get(@PathVariable Long id){
    33. return ${table_name_small}Service.getById(id);
    34. }
    35. /**
    36. * 新增
    37. */
    38. @PostMapping
    39. public boolean save(@Validated @RequestBody ${table_name}Dto ${table_name_small}Dto){
    40. ${table_name} ${table_name_small} = new ${table_name}();
    41. BeanUtils.copyProperties(${table_name_small}Dto, ${table_name_small});
    42. return ${table_name_small}Service.save(${table_name_small});
    43. }
    44. /**
    45. * 修改
    46. */
    47. @PutMapping
    48. public boolean update(@Validated @RequestBody ${table_name}Dto ${table_name_small}Dto){
    49. ${table_name} ${table_name_small} = new ${table_name}();
    50. BeanUtils.copyProperties(${table_name_small}Dto, ${table_name_small});
    51. return ${table_name_small}Service.updateById(${table_name_small});
    52. }
    53. /**
    54. * 删除
    55. * @param id
    56. * @return 是否成功
    57. */
    58. @DeleteMapping("/{id}")
    59. public boolean del(@PathVariable Long id){
    60. return ${table_name_small}Service.removeById(id);
    61. }
    62. }

      5.7 实体类Vo模版

    1. package ${package_name}.http.vo;
    2. import java.io.Serializable;
    3. import java.util.Date;
    4. import lombok.Data;
    5. import lombok.ToString;
    6. import java.math.BigDecimal;
    7. import com.fasterxml.jackson.annotation.JsonFormat;
    8. import com.fasterxml.jackson.databind.annotation.JsonSerialize;
    9. import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
    10. /**
    11. * 描述:<#if table_annotation??>${table_annotation}模型</#if>Vo类
    12. * @author ${author}
    13. * @date ${date}
    14. */
    15. @Data
    16. @ToString(callSuper = true)
    17. public class ${table_name}Vo implements Serializable {
    18. <#if model_column?exists>
    19. <#list model_column as model>
    20. <#if (model.columnType = 'BIGINT' && model.columnName = 'id')>
    21. @JsonSerialize(using = ToStringSerializer.class)
    22. private Long ${model.changeColumnName?uncap_first};
    23. </#if>
    24. <#if (model.columnType = 'BIGINT' && model.columnName != 'id')>
    25. private Long ${model.changeColumnName?uncap_first};
    26. </#if>
    27. <#if (model.columnType = 'INT' || model.columnType = 'INT UNSIGNED' || model.columnType = 'TINYINT')>
    28. private Integer ${model.changeColumnName?uncap_first};
    29. </#if>
    30. <#if (model.columnType = 'DECIMAL')>
    31. private BigDecimal ${model.changeColumnName?uncap_first};
    32. </#if>
    33. <#if (model.columnType = 'VARCHAR' || model.columnType = 'TEXT' || model.columnType = 'CHAR')>
    34. private String ${model.changeColumnName?uncap_first};
    35. </#if>
    36. <#if model.columnType = 'TIMESTAMP' || model.columnType = 'YEAR' || model.columnType = 'DATE' || model.columnType = 'DATETIME' >
    37. @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
    38. private Date ${model.changeColumnName?uncap_first};
    39. </#if>
    40. <#if (model.columnType != 'BIGINT' && model.columnType != 'INT' && model.columnType != 'VARCHAR' && model.columnType != 'DECIMAL' && model.columnType != 'TEXT' && model.columnType != 'CHAR' && model.columnType != 'TIMESTAMP' && model.columnType != 'YEAR' && model.columnType != 'DATE' && model.columnType != 'DATETIME' && model.columnType != 'INT UNSIGNED')>
    41. private MISS ${model.changeColumnName?uncap_first};
    42. </#if>
    43. </#list>
    44. </#if>
    45. }

      5.8 实体类Dto模版

    1. package ${package_name}.http.dto;
    2. import java.io.Serializable;
    3. import java.util.Date;
    4. import lombok.Data;
    5. import lombok.ToString;
    6. import java.math.BigDecimal;
    7. import com.fasterxml.jackson.annotation.JsonFormat;
    8. import com.fasterxml.jackson.databind.annotation.JsonSerialize;
    9. import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
    10. import com.fasterxml.jackson.annotation.JsonFormat;
    11. /**
    12. * 描述:<#if table_annotation??>${table_annotation}模型</#if>Dto类
    13. * @author ${author}
    14. * @date ${date}
    15. */
    16. @Data
    17. @ToString(callSuper = true)
    18. public class ${table_name}Dto implements Serializable {
    19. <#if model_column?exists>
    20. <#list model_column as model>
    21. <#if (model.columnType = 'BIGINT' && model.columnName = 'id')>
    22. @JsonSerialize(using = ToStringSerializer.class)
    23. private Long ${model.changeColumnName?uncap_first};
    24. </#if>
    25. <#if (model.columnType = 'BIGINT' && model.columnName != 'id')>
    26. private Long ${model.changeColumnName?uncap_first};
    27. </#if>
    28. <#if (model.columnType = 'INT' || model.columnType = 'INT UNSIGNED' || model.columnType = 'TINYINT')>
    29. private Integer ${model.changeColumnName?uncap_first};
    30. </#if>
    31. <#if (model.columnType = 'DECIMAL')>
    32. private BigDecimal ${model.changeColumnName?uncap_first};
    33. </#if>
    34. <#if (model.columnType = 'VARCHAR' || model.columnType = 'TEXT' || model.columnType = 'CHAR')>
    35. private String ${model.changeColumnName?uncap_first};
    36. </#if>
    37. <#if model.columnType = 'TIMESTAMP' || model.columnType = 'YEAR' || model.columnType = 'DATE' || model.columnType = 'DATETIME' >
    38. @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
    39. private Date ${model.changeColumnName?uncap_first};
    40. </#if>
    41. <#if (model.columnType != 'BIGINT' && model.columnType != 'INT' && model.columnType != 'VARCHAR' && model.columnType != 'DECIMAL' && model.columnType != 'TEXT' && model.columnType != 'CHAR' && model.columnType != 'TIMESTAMP' && model.columnType != 'YEAR' && model.columnType != 'DATE' && model.columnType != 'DATETIME' && model.columnType != 'INT UNSIGNED')>
    42. private MISS ${model.changeColumnName?uncap_first};
    43. </#if>
    44. </#list>
    45. </#if>
    46. }

      5.9 pom文件模版

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0</modelVersion>
    6. <groupId>${package_name}</groupId>
    7. <artifactId>${project_name}</artifactId>
    8. <version>1.0-SNAPSHOT</version>
    9. <!-- 继承Spring boot工程 -->
    10. <parent>
    11. <groupId>org.springframework.boot</groupId>
    12. <artifactId>spring-boot-starter-parent</artifactId>
    13. <version>2.3.9.RELEASE</version>
    14. </parent>
    15. <properties>
    16. <!-- 项目源码及编译输出的编码 -->
    17. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    18. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    19. <!-- 项目编译JDK版本 -->
    20. <maven.compiler.source>11</maven.compiler.source>
    21. <maven.compiler.target>11</maven.compiler.target>
    22. <!-- 依赖包版本管理 -->
    23. <spring.boot.version>2.3.9.RELEASE</spring.boot.version>
    24. <lombok.version>1.18.8</lombok.version>
    25. <mysql.version>5.1.46</mysql.version>
    26. <mybatis-plus.version>3.3.1</mybatis-plus.version>
    27. </properties>
    28. <dependencies>
    29. <dependency>
    30. <groupId>org.springframework.boot</groupId>
    31. <artifactId>spring-boot-starter-web</artifactId>
    32. </dependency>
    33. <dependency>
    34. <groupId>org.springframework.boot</groupId>
    35. <artifactId>spring-boot-starter-test</artifactId>
    36. </dependency>
    37. <dependency>
    38. <groupId>com.baomidou</groupId>
    39. <artifactId>mybatis-plus-boot-starter</artifactId>
    40. <version>${r"${mybatis-plus.version}"}</version>
    41. </dependency>
    42. <dependency>
    43. <groupId>mysql</groupId>
    44. <artifactId>mysql-connector-java</artifactId>
    45. <version>${r"${mysql.version}"}</version>
    46. </dependency>
    47. <dependency>
    48. <groupId>org.projectlombok</groupId>
    49. <artifactId>lombok</artifactId>
    50. <version>${r"${lombok.version}"}</version>
    51. </dependency>
    52. <dependency>
    53. <groupId>org.apache.commons</groupId>
    54. <artifactId>commons-lang3</artifactId>
    55. <version>3.10</version>
    56. </dependency>
    57. </dependencies>
    58. </project>

      5.10 application.yml文件模版

    1. server:
    2. port: ${r"${port:8888}"}
    3. spring:
    4. application:
    5. name: ${project_name}

      6 测试
     

      运行代码生成器入口类 CodeGenerateUtils
     

      输出日志如下

    1. D:\app\devs\Java\jdk-11\bin\java.exe "-javaagent:D:\app\devs\JetBrains\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=60577:D:\app\devs\JetBrains\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath D:\heima\技术文章\itheima-code\target\classes;D:\app\devs\apache-maven-3.3.9\maven_repository\org\freemarker\freemarker\2.3.23\freemarker-2.3.23.jar;D:\app\devs\apache-maven-3.3.9\maven_repository\mysql\mysql-connector-java\5.1.47\mysql-connector-java-5.1.47.jar;D:\app\devs\apache-maven-3.3.9\maven_repository\org\projectlombok\lombok\1.18.8\lombok-1.18.8.jar;D:\app\devs\apache-maven-3.3.9\maven_repository\org\apache\commons\commons-lang3\3.10\commons-lang3-3.10.jar freemarker.CodeGenerateUtils
    2. -------- 正在生成 undo_log 表相关文件------
    3. 生成实体类
    4. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\entity\UndoLog.java
    5. 生成Mapper
    6. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\mapper\UndoLogMapper.java
    7. 生成Mapper映射文件
    8. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\com\itheima\wemedia\mapper\UndoLogMapper.xml
    9. 生成service接口
    10. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\UndoLogService.java
    11. 生成service实现类
    12. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\impl\UndoLogServiceImpl.java
    13. 生成Controller层文件
    14. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\controller\UndoLogController.java
    15. 生成vo类
    16. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\vo\UndoLogVo.java
    17. 生成dto类
    18. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\dto\UndoLogDto.java
    19. 生成pom文件
    20. D:\heima\技术文章\代码\itheima-wemedia\pom.xml
    21. 生成application.yml文件
    22. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\application.yml
    23. -------- 正在生成 wm_channel 表相关文件------
    24. 生成实体类
    25. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\entity\WmChannel.java
    26. 生成Mapper
    27. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\mapper\WmChannelMapper.java
    28. 生成Mapper映射文件
    29. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\com\itheima\wemedia\mapper\WmChannelMapper.xml
    30. 生成service接口
    31. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\WmChannelService.java
    32. 生成service实现类
    33. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\impl\WmChannelServiceImpl.java
    34. 生成Controller层文件
    35. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\controller\WmChannelController.java
    36. 生成vo类
    37. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\vo\WmChannelVo.java
    38. 生成dto类
    39. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\dto\WmChannelDto.java
    40. 生成pom文件
    41. D:\heima\技术文章\代码\itheima-wemedia\pom.xml
    42. 生成application.yml文件
    43. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\application.yml
    44. -------- 正在生成 wm_fans_statistics 表相关文件------
    45. 生成实体类
    46. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\entity\WmFansStatistics.java
    47. 生成Mapper
    48. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\mapper\WmFansStatisticsMapper.java
    49. 生成Mapper映射文件
    50. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\com\itheima\wemedia\mapper\WmFansStatisticsMapper.xml
    51. 生成service接口
    52. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\WmFansStatisticsService.java
    53. 生成service实现类
    54. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\impl\WmFansStatisticsServiceImpl.java
    55. 生成Controller层文件
    56. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\controller\WmFansStatisticsController.java
    57. 生成vo类
    58. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\vo\WmFansStatisticsVo.java
    59. 生成dto类
    60. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\dto\WmFansStatisticsDto.java
    61. 生成pom文件
    62. D:\heima\技术文章\代码\itheima-wemedia\pom.xml
    63. 生成application.yml文件
    64. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\application.yml
    65. -------- 正在生成 wm_material 表相关文件------
    66. 生成实体类
    67. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\entity\WmMaterial.java
    68. 生成Mapper
    69. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\mapper\WmMaterialMapper.java
    70. 生成Mapper映射文件
    71. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\com\itheima\wemedia\mapper\WmMaterialMapper.xml
    72. 生成service接口
    73. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\WmMaterialService.java
    74. 生成service实现类
    75. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\impl\WmMaterialServiceImpl.java
    76. 生成Controller层文件
    77. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\controller\WmMaterialController.java
    78. 生成vo类
    79. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\vo\WmMaterialVo.java
    80. 生成dto类
    81. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\dto\WmMaterialDto.java
    82. 生成pom文件
    83. D:\heima\技术文章\代码\itheima-wemedia\pom.xml
    84. 生成application.yml文件
    85. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\application.yml
    86. -------- 正在生成 wm_news 表相关文件------
    87. 生成实体类
    88. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\entity\WmNews.java
    89. 生成Mapper
    90. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\mapper\WmNewsMapper.java
    91. 生成Mapper映射文件
    92. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\com\itheima\wemedia\mapper\WmNewsMapper.xml
    93. 生成service接口
    94. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\WmNewsService.java
    95. 生成service实现类
    96. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\impl\WmNewsServiceImpl.java
    97. 生成Controller层文件
    98. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\controller\WmNewsController.java
    99. 生成vo类
    100. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\vo\WmNewsVo.java
    101. 生成dto类
    102. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\dto\WmNewsDto.java
    103. 生成pom文件
    104. D:\heima\技术文章\代码\itheima-wemedia\pom.xml
    105. 生成application.yml文件
    106. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\application.yml
    107. -------- 正在生成 wm_news_material 表相关文件------
    108. 生成实体类
    109. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\entity\WmNewsMaterial.java
    110. 生成Mapper
    111. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\mapper\WmNewsMaterialMapper.java
    112. 生成Mapper映射文件
    113. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\com\itheima\wemedia\mapper\WmNewsMaterialMapper.xml
    114. 生成service接口
    115. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\WmNewsMaterialService.java
    116. 生成service实现类
    117. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\impl\WmNewsMaterialServiceImpl.java
    118. 生成Controller层文件
    119. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\controller\WmNewsMaterialController.java
    120. 生成vo类
    121. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\vo\WmNewsMaterialVo.java
    122. 生成dto类
    123. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\dto\WmNewsMaterialDto.java
    124. 生成pom文件
    125. D:\heima\技术文章\代码\itheima-wemedia\pom.xml
    126. 生成application.yml文件
    127. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\application.yml
    128. -------- 正在生成 wm_news_statistics 表相关文件------
    129. 生成实体类
    130. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\entity\WmNewsStatistics.java
    131. 生成Mapper
    132. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\mapper\WmNewsStatisticsMapper.java
    133. 生成Mapper映射文件
    134. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\com\itheima\wemedia\mapper\WmNewsStatisticsMapper.xml
    135. 生成service接口
    136. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\WmNewsStatisticsService.java
    137. 生成service实现类
    138. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\impl\WmNewsStatisticsServiceImpl.java
    139. 生成Controller层文件
    140. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\controller\WmNewsStatisticsController.java
    141. 生成vo类
    142. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\vo\WmNewsStatisticsVo.java
    143. 生成dto类
    144. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\dto\WmNewsStatisticsDto.java
    145. 生成pom文件
    146. D:\heima\技术文章\代码\itheima-wemedia\pom.xml
    147. 生成application.yml文件
    148. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\application.yml
    149. -------- 正在生成 wm_sensitive 表相关文件------
    150. 生成实体类
    151. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\entity\WmSensitive.java
    152. 生成Mapper
    153. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\mapper\WmSensitiveMapper.java
    154. 生成Mapper映射文件
    155. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\com\itheima\wemedia\mapper\WmSensitiveMapper.xml
    156. 生成service接口
    157. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\WmSensitiveService.java
    158. 生成service实现类
    159. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\impl\WmSensitiveServiceImpl.java
    160. 生成Controller层文件
    161. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\controller\WmSensitiveController.java
    162. 生成vo类
    163. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\vo\WmSensitiveVo.java
    164. 生成dto类
    165. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\dto\WmSensitiveDto.java
    166. 生成pom文件
    167. D:\heima\技术文章\代码\itheima-wemedia\pom.xml
    168. 生成application.yml文件
    169. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\application.yml
    170. -------- 正在生成 wm_user 表相关文件------
    171. 生成实体类
    172. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\entity\WmUser.java
    173. 生成Mapper
    174. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\mapper\WmUserMapper.java
    175. 生成Mapper映射文件
    176. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\com\itheima\wemedia\mapper\WmUserMapper.xml
    177. 生成service接口
    178. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\WmUserService.java
    179. 生成service实现类
    180. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\service\impl\WmUserServiceImpl.java
    181. 生成Controller层文件
    182. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\controller\WmUserController.java
    183. 生成vo类
    184. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\vo\WmUserVo.java
    185. 生成dto类
    186. D:\heima\技术文章\代码\itheima-wemedia\src\main\java\com\itheima\wemedia\http\dto\WmUserDto.java
    187. 生成pom文件
    188. D:\heima\技术文章\代码\itheima-wemedia\pom.xml
    189. 生成application.yml文件
    190. D:\heima\技术文章\代码\itheima-wemedia\src\main\resources\application.yml
    191. ============ 全部生成完成! =============
    192. Process finished with exit code 0

      在idea中点击 File > open 打开 D:\heima\技术文章\代码\itheima-wemedia
     

      

  • 相关阅读:
    Linux:进程状态和优先级
    【C++】6-19 方阵的转置 分数 10
    3dmax渲染内存不足,这样解决!
    网页JS自动化脚本(二)查找定位页面元素的方法
    如何选择一款快速可靠的文件自动同步软件?
    【Shell】进程内存过高告警脚本
    Vue2高级-axios和vue-resource、配置代理服务器(解决跨域问题)
    C生万物 | 字符串函数与内存函数解读【附英译中图解】
    【HTML】前端网页开发工具Vscode中DOCTYPE和lang以及字符集的作用
    JNA嵌套结构体,如何访问内嵌结构体的成员?
  • 原文地址:https://blog.csdn.net/Blue92120/article/details/127859577