实战:一键生成前后端代码,Mybatis-Plus代码生成器

前言

在日常的软件开发中,程序员往往需要花费大量的时间写CRUD,不仅枯燥效率低,而且每个人的代码风格不统一。MyBatis-Plus 代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块及前端页面的代码,极大的提升了开发效率。

项目介绍

本项目将以springboot用演示,前端使用freemaker,数据库持久层用mybatis(考虑到mybatis的使用还是最普遍的,就没有用jpa和mybatisplus),通过Velocity模板引擎配置各模块的文件模板,通过mybatis-plus代码生成器连接mysql,用商品表为例生成各模块的代码和前端页面。(本项目只演示分页查询和导出功能)。

本项目所有代码和脚本都能都文末找到地址。

实战

数据库脚本

创建一张商品表test_goods

1
2
3
4
5
6
7
8
9
10
11
sql复制代码CREATE TABLE `test_goods` (
`id` bigint(20) DEFAULT NULL COMMENT 'id',
`goods_sn` varchar(45) DEFAULT NULL COMMENT '商品编码',
`name` varchar(255) DEFAULT NULL COMMENT '商品名称',
`title` varchar(80) DEFAULT NULL COMMENT '标题',
`price` decimal(10,2) DEFAULT NULL COMMENT '售价',
`status` int(2) DEFAULT NULL COMMENT '商品状态',
`sale_count` int(11) DEFAULT NULL COMMENT '销量',
`create_date` datetime DEFAULT NULL COMMENT '创建时间',
`modify_date` datetime DEFAULT NULL COMMENT '修改时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8

maven依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
xml复制代码  <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.1.4</version>
</dependency>

<!-- aspectj -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<scope>provided</scope>
</dependency>
<!--es-->

<!-- lombok 简化get/set 方法 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--csv导出用到-->
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>3.8</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
</dependencies>

配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
yml复制代码mybatis:
mapper-locations: classpath:mybatis/*Mapper.xml
type-aliases-package: com.lzn.mybatisplus.codegenerator.entity

spring:
datasource:
username: root
password: 123qwe
url: jdbc:mysql://192.168.0.1:3306/myProject?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
redis:
host: 192.168.0.1
password: 1234qwer
port: 6379
freemarker:
template-loader-path: classpath:/templates/pages/
cache: false
charset: UTF-8
check-template-location: true
content-type: text/html
expose-request-attributes: true
expose-session-attributes: true
suffix: .ftl

模板文件

本项目中,所有模块的文件都是用Velocity模板引擎生成,这里简单介绍下Velocity的语法,在Velocity中用表示变量,例如:{}表示变量,例如:表示变量,例如:{table.entityName} 表示实体名,field.name表示字段名,我们在AutoGenerator代码生成器里定义的全局变量{field.name} 表示字段名,我们在AutoGenerator代码生成器里定义的全局变量 field.name表示字段名,我们在AutoGenerator代码生成器里定义的全局变量{author}、{date} 表示作者,日期等。在Velocity中用#表示语法,例如 #foreach(field in ${table.fields}) #end遍历表字段。下面演示几个类、前端文件、xml文件的模板文件

实体类模板(entity.java.vm)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
java复制代码package ${package.Entity};

import java.math.BigDecimal;
import java.util.Date;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
* 数据库表名 ${table.name}
*
* @author ${author}
* @date ${date}
*/
@Getter
@Setter
@ToString
public class ${table.entityName} {

#foreach($field in ${table.fields})
/**
* 数据库字段名 ${field.name} 类型 ${field.type}
*/
private ${field.propertyType} ${field.propertyName};

#end

}

Controller模板(controller.java.vm)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
java复制代码package ${package.Controller};

import ${package.Entity}.${entity};
import ${package.Service}.${table.serviceName};
import com.lzn.mybatisplus.codegenerator.export.${table.entityName}VO;
import com.lzn.mybatisplus.codegenerator.export.${table.entityName}ExportService;
import com.lzn.mybatisplus.codegenerator.utils.entity.*;
import com.lzn.mybatisplus.codegenerator.utils.export.*;
import org.apache.commons.beanutils.ConvertUtils;
import com.lzn.mybatisplus.codegenerator.utils.ParameterUtil;
import com.lzn.mybatisplus.codegenerator.utils.entity.GridDataModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
* <p>
* ${tablecomment} 前端控制器
* </p>
*
* @author ${author}
* @since ${date}
*/
@Controller
@RequestMapping(value="/admin/${table.entityPath}")
public class ${table.controllerName}{
private static Logger logger = LoggerFactory.getLogger(${table.controllerName}.class);

@Resource
private ${entity}Service ${table.entityPath}Service;



@RequestMapping(value = "list", method = RequestMethod.GET)
public String list(Model model){
return "/admin/${cfg.pageDirName}/list";
}

@RequestMapping(value = "searchList", method = RequestMethod.POST)
@ResponseBody
@ExportMethod(serviceClass = ${entity}ExportService.class, memo = "明细导出")
public String searchList(ServletRequest request,@ModelAttribute("page") OmuiPage page){
try {
Map<String,Object> searchParam = ParameterUtil.getParametersStartingWith(request, "filter_");
GridDataModel<${entity}VO> gd =${table.entityPath}Service.findByPage(searchParam, page);
return JsonMapper.nonDefaultMapper().toJson(gd);
} catch (Exception e) {
logger.error("查询出错了",e);
return JsonMapper.nonDefaultMapper().toJson(new Resp("false", e.getMessage()));
}
}


}

Service类模板(service.java.vm)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
java复制代码package ${package.Service};



import org.springframework.stereotype.Service;
import com.lzn.mybatisplus.codegenerator.dao.${table.mapperName};
import com.lzn.mybatisplus.codegenerator.utils.entity.GridDataModel;
import com.lzn.mybatisplus.codegenerator.utils.entity.OmuiPage;
import com.lzn.mybatisplus.codegenerator.export.${table.entityName}VO;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
* <p>
* $!{tablecomment} 服务类
* </p>
*
* @author ${author}
* @since ${date}
*/
@Service
public class ${table.serviceName} {

@Resource
private ${table.mapperName} ${table.entityPath}Dao;

/**
* 分页查询
* */
public GridDataModel<${table.entityName}VO> findByPage(Map<String, Object> searchParams, OmuiPage page){
GridDataModel<${table.entityName}VO> gm = new GridDataModel<${table.entityName}VO>();
searchParams.put("start", page.getStart());
searchParams.put("limit", page.getLimit());
long count = ${table.entityPath}Dao.countForPage(searchParams);
List<${table.entityName}VO> list = ${table.entityPath}Dao.listForPage(searchParams);
gm.setTotal(count);
gm.setRows(list);
return gm;
}



}

Dao类模板(dao.java.vm)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
java复制代码package ${package.Mapper};

import com.lzn.mybatisplus.codegenerator.entity.${table.entityName};
import com.lzn.mybatisplus.codegenerator.export.${table.entityName}VO;
import java.util.List;
import java.util.Map;

public interface ${table.mapperName} {
/**
* 根据主键删除数据库的记录, ${table.name}
*/
int deleteByPrimaryKey(Long id);

/**
* 新写入数据库记录, ${table.name}
*/
int insert(${table.entityName} record);

/**
* 根据指定主键获取一条数据库记录, ${table.name}
*/
${table.entityName} selectByPrimaryKey(Long id);

/**
* 根据主键来更新符合条件的数据库记录, ${table.name}
*/
int updateByPrimaryKey(${table.entityName} record);

/**
* 根据条件分页查询
* */
List<${table.entityName}VO> listForPage(Map<String,Object> searchMap);

/**
* 根据条件分页查询(计数)
* */
long countForPage(Map<String,Object> searchMap);

}

Mapper.xml模板(mapper.xml.vm)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
xml复制代码<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.${table.mapperName}">
#if(${baseResultMap})
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
#foreach($field in ${table.fields})
#if(${field.keyFlag})##生成主键排在第一位
<id column="${field.name}" property="${field.propertyName}" />
#end
#end
#foreach($field in ${table.commonFields})##生成公共字段
<result column="${field.name}" property="${field.propertyName}" />
#end
#foreach($field in ${table.fields})
#if(!${field.keyFlag})##生成普通字段
<result column="${field.name}" property="${field.propertyName}" />
#end
#end
</resultMap>
#end

#if(${baseColumnList})
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
#foreach($field in ${table.commonFields})
#if(${field.name} == ${field.propertyName})${field.name}#else${field.name} AS ${field.propertyName}#end,
#end
${table.fieldNames}
</sql>
#end

<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
<!-- -->
delete from ${table.name}
where
#foreach($field in ${table.fields})
#if(${field.keyFlag})## 主键
${field.name} = #{ ${field.propertyName} }
#end
#end
</delete>

<insert id="insert" parameterType="${package.Entity}.${entity}">
<!-- -->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
SELECT LAST_INSERT_ID()
</selectKey>
insert into ${table.name} (
#foreach($field in ${table.fields})
#if(!${field.keyFlag})##生成普通字段
${field.name}#if($foreach.hasNext),#end
#end
#end
)
values (
#foreach($field in ${table.fields})
#if(!${field.keyFlag})##生成普通字段
#{ ${field.propertyName}}#if($foreach.hasNext),#end
#end
#end
)
</insert>

<update id="updateByPrimaryKey" parameterType="${package.Entity}.${entity}">
<!-- -->
update ${table.name}
set
#foreach($field in ${table.fields})
#if(!${field.keyFlag})##生成普通字段
${field.name} = #{ ${field.propertyName}} #if($foreach.hasNext),#end
#end
#end
where
#foreach($field in ${table.fields})
#if(${field.keyFlag})
id = #{ ${field.name} }
#end
#end
</update>


<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
<!-- -->
select
<include refid="Base_Column_List" />
from ${table.name}
where id = #{ id }
</select>

<select id="countForPage" parameterType="map" resultType="Long">
<!-- -->
select
count(*)
from
${table.name}
where 1=1
<if test="beginDate != null and beginDate != ''">
and create_date <![CDATA[>=]]> #{beginDate}
</if>
<if test="endDate != null and endDate != ''">
and create_date <![CDATA[<=]]> #{endDate}
</if>
</select>

<select id="listForPage" parameterType="map" resultType="com.lzn.mybatisplus.codegenerator.export.${table.entityName}VO">
<!-- -->
select
<include refid="Base_Column_List" />
from
${table.name}
where 1=1
<if test="beginDate != null and beginDate != ''">
and create_date <![CDATA[>=]]> #{beginDate}
</if>
<if test="endDate != null and endDate != ''">
and create_date <![CDATA[<=]]> #{endDate}
</if>
limit #{start}, #{limit}
</select>
</mapper>

前端页面list.ftl模板(list.ftl.vm)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
html复制代码<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<#assign base=request.contextPath>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>$!{tablecomment}</title>
<link href="${base}/static/omui/css/elegant/om-all.css" rel="stylesheet" type="text/css" />
<link href="${base}/static/admin/css/admin.css" rel="stylesheet" type="text/css" />

<script type="text/javascript" src="${base}/static/js/jquery-1.7.1.js"></script>
<script type="text/javascript" src="${base}/static/js/HForm.js"></script>
<script type="text/javascript" src="${base}/static/My97DatePicker/WdatePicker.js"></script>
<script type="text/javascript" src="${base}/static/omui/js/operamasks-ui.min.js"></script>
<script type="text/javascript" src="${base}/static/omui/js/common.js"></script>
<script type="text/javascript" src="${base}/static/bui/js/common.js"></script>
<script type="text/javascript" src="${base}/static/admin/js/export.js"></script>

<script type="text/javascript">


$().ready(function(){

//初始化控件
$("#search-panel").omPanel({
title : "条件搜索",collapsible:false
});

//搜索
$('#searchButton').bind('click', function(e) {
var data = $("#listForm").HForm('form2json');
$('#listGrid').omGrid({extraData:data});
});

$("#start-time").omCalendar();
$("#time-end").omCalendar();

$('#searchButton').omButton({
icons : {left : '${base}/static/omui/images/search.png'},width : 70
});

$(".input-select").change(function(){
$('#searchButton').click();
});

$('#buttonbar').omButtonbar({
btns : [{label:"导出Excel",
id:"addbutton" ,
icons : {left : '${base}/static/omui/images/export.png'},
onClick:function()
{
exportUtil({
title : "列表导出",
exportUrl : "${base}/admin/${table.entityPath}/searchList",
extraParam : $("#listForm").HForm('form2json')
});
}
}
]
});


//初始化列表
var height=$(document).height() -$('#search-panel').outerHeight()-$('#buttonbar').outerHeight()-40;
$('#listGrid').omGrid({
height:height,
limit:20,
method:'post',
singleSelect:false,
extraData:$("#listForm").HForm('form2json'),
dataSource : '${base}/admin/${table.entityPath}/searchList',
colModel : [
{header : 'ID', name : 'id', width : 30, align : 'left',sort:'serverSide'},
{header : '创建时间', name : 'createDate', width : 150, align : 'left',sort:'serverSide',renderer :dataFormat1},
{header : '修改时间', name : 'modifyDate', width : 150, align : 'left',sort:'serverSide',renderer :dataFormat1},
#foreach($field in ${table.fields})

#set($comment = "")
#set($type = "")
#set($isNullAble = true)
#set($defaultValue = false)
#set($listIsShow = true)
#set($listIsSearch = false)

#foreach( $e in $field.comment.split(","))
#if( $foreach.count == 1 )
#set($comment = $e)
#elseif( $foreach.count == 2 )
#set($type = $e)
#elseif( $foreach.count == 3)
#if($e == "YES")
#set($isNullAble = true)
#else
#set($isNullAble = false)
#end
#elseif( $foreach.count == 4)
#if($e == "true")
#set($defaultValue = true)
#else
#set($defaultValue = false)
#end
#elseif( $foreach.count == 5)
#if($e == "true")
#set($listIsShow = true)
#else
#set($listIsShow = false)
#end
#elseif( $foreach.count == 6)
#if($e == "true")
#set($listIsSearch = true)
#else
#set($listIsSearch = false)
#end
#end
#end
{header : '#if("$!comment" != "")${comment}#end', name : '${field.propertyName}',width : 90, align : 'left',sort:'serverSide'#if($type == "timer"),renderer :dataFormat1 #end},
#end
],
rowDetailsProvider:function(rowData){
}
});

//初始化控件 end
function getIds(datas) {
var str = "";
for (var i = 0; i < datas.length; i++) {
str += datas[i].id + ",";
}
//去掉最后一个逗号(如果不需要去掉,就不用写)
if (str.length > 0) {
str = str.substr(0, str.length - 1);
}
return str;
}

$('#searchButton').click();
});



</script>
</head>
<body >

<div id="search-panel">
<form id="listForm">
<div>
<span class="label">状态:</span>
<select class="js-example-basic-single input-select" name="filter_EQS_status">
<option value="0" selected>待处理</option>
<option value="1">已处理</option>
<option value="">全部</option>
</select>
<span class="label">手机号:</span>
<input type="text" class="input-text" name="filter_LIKES_mobile" />
<span class="label">联系人:</span>
<input type="text" class="input-text" name="filter_LIKES_name" />
<span class="label">创建时间:</span>
<input id="start-time" style="width: 118px" name="filter_GTED_createDate"/>
-
<input id="time-end" style="width: 118px" name="filter_LTED_createDate"/>
<span id="searchButton">查询</span>
</div>
</form>
</div>

<div id="buttonbar"></div><!-- 工具栏位置 -->
<table id="listGrid"></table> <!-- 主列表位置 -->

</body>
</html>

代码生成器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
java复制代码package com.lzn.mybatisplus.codegenerator;

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
* 辅助生产后台开发相关代码 开发时只在自己本地代码修改,不要提交
* 生成ddao service controller entity java代码 和前端 flt文件。
* 只演示list场景
*/
public class MpGenerator {

//注意:开发时只在自己本地代码修改,不要提交、不要提交 不要提交
//第一步修改 javaSrcDir 修改成自己项目存放java源代码的根路径
static String javaSrcDir = "D:/Git_space/lunzijihua/codegenerator/src/main/java";
static String resourceDir = "D:/Git_space/lunzijihua/codegenerator/src/main/resources";
//第二步修改 pageRootDir 修改成你要开发的模块的名称 存放ftl文件的文件夹的根路径
static String pageRootDir ="D:/Git_space/lunzijihua/codegenerator/src/main/resources/templates/pages/";


//第三步修改 packageName 修改成你要开发的模块的名称 包名 要小写 生产的entity service dao action文件夹和java代码会在下面
static String packageName = "user";//模块文件夹包名称
//第四步修改 pageDirName 修改成你要开发的模块的名称 存放ftl文件的文件夹 要小写
static String pageDirName = "user";//模块页面文件夹名
//第五步骤 表的前缀 填写了 生成文件时会去除掉
static String tablePrefix="test_";
//第六步 数据库里面对应的表的全名
static String tableName="test_goods";

/**
* <p>
* 代码自动生成
* </p>
*/
public static void main(String[] args) {

AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
gc.setOutputDir(javaSrcDir);
gc.setFileOverride(true);
gc.setActiveRecord(true);// 不需要ActiveRecord特性的请改为false
gc.setEnableCache(false);// XML 二级缓存
gc.setBaseResultMap(true);// XML ResultMap
gc.setBaseColumnList(true);// XML columList
// .setKotlin(true) 是否生成 kotlin 代码
gc.setAuthor("liuzhinan");

// 自定义文件命名,注意 %s 会自动填充表实体属性!
gc.setMapperName("%sMybatisDao");
// gc.setXmlName("%sDao");
gc.setServiceName("%sService");
// gc.setServiceImplName("%sService");
// gc.setControllerName("%sAction");
mpg.setGlobalConfig(gc);

// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDbType(DbType.MYSQL);


dsc.setTypeConvert(new MySqlTypeConvert(){
// 自定义数据库表字段类型转换【可选】
@Override
public DbColumnType processTypeConvert(String fieldType) {
System.out.println("转换类型:" + fieldType);
// 注意!!processTypeConvert 存在默认类型转换,如果不是你要的效果请自定义返回、非如下直接返回。
return super.processTypeConvert(fieldType);
}
});
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("test");
dsc.setPassword("123456");
dsc.setUrl("jdbc:mysql://192.168.0.1:3306/myProject?useSSL=false");
mpg.setDataSource(dsc);

// 策略配置
StrategyConfig strategy = new StrategyConfig();
// strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意
strategy.setTablePrefix(new String[] { tablePrefix });// 此处可以修改为您的表前缀
strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
strategy.setInclude(new String[] { tableName }); // 需要生成的表
// strategy.setExclude(new String[]{"test"}); // 排除生成的表
// 自定义实体父类
strategy.setSuperEntityClass("com.lzn.mybatisplus.codegenerator.entity.IdEntity");
// 自定义实体,公共字段
// strategy.setSuperEntityColumns(new String[] { "id", "create_date","modify_date" });
// 自定义 mapper 父类
// strategy.setSuperMapperClass("com.baomidou.demo.TestMapper");
// 自定义 service 父类
// strategy.setSuperServiceClass("com.baomidou.demo.TestService");
// 自定义 service 实现类父类
// strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl");
// 自定义 controller 父类
// strategy.setSuperControllerClass("com.baomidou.demo.TestController");
// 【实体】是否生成字段常量(默认 false)
// public static final String ID = "test_id";
// strategy.setEntityColumnConstant(true);
// 【实体】是否为构建者模型(默认 false)
// public User setName(String name) {this.name = name; return this;}
// strategy.setEntityBuilderModel(true);
mpg.setStrategy(strategy);

// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.lzn.mybatisplus.codegenerator");
pc.setModuleName(null);
pc.setMapper("dao");
pc.setEntity("entity");
pc.setService("service");
pc.setServiceImpl("service.impl");
pc.setController("controller");
mpg.setPackageInfo(pc);

// 注入自定义配置,可以在 VM 中使用 cfg.abc 【可无】
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
map.put("pageDirName",pageDirName);
map.put("packageName",packageName);
this.setMap(map);
}
};

List<FileOutConfig> focList = new ArrayList<FileOutConfig>();

// cfg.setFileOutConfigList(focList);
// mpg.setCfg(cfg);

//生成导出视图对象
focList.add(new FileOutConfig("/templates/vm/vo.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return javaSrcDir+"/com/lzn/mybatisplus/codegenerator/export/"+tableInfo.getEntityName()+"VO.java";
}
});
//生成excel导出的服务类,
focList.add(new FileOutConfig("/templates/vm/exportservice.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return javaSrcDir+"/com/lzn/mybatisplus/codegenerator/export/"+tableInfo.getEntityName()+"ExportService.java";
}
});
//生成mybatisDao文件到指定目录
focList.add(new FileOutConfig("/templates/vm/mybatisdao.java.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return javaSrcDir+"/com/lzn/mybatisplus/codegenerator/dao/"+tableInfo.getEntityName()+"MybatisDao.java";
}
});

//生成mapper文件到指定目录
focList.add(new FileOutConfig("/templates/vm/mapper.xml.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
return resourceDir+"/mybatis/"+tableInfo.getEntityName()+"Mapper.xml";
}
});

// 自定义 xxList.ftl 生成
focList.add(new FileOutConfig("/templates/vm/list.ftl.vm") {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输入文件名称
return pageRootDir+pageDirName+"/list.ftl";
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);

// 关闭默认 xml 生成,调整生成 至 根目录
TemplateConfig tc = new TemplateConfig();
tc.setEntity("/templates/vm/entity.java.vm");
tc.setService("/templates/vm/service.java.vm");
tc.setServiceImpl(null);//设成null才会不生产
tc.setController("/templates/vm/controller.java.vm");
tc.setMapper(null);
tc.setXml(null);
mpg.setTemplate(tc);

// 自定义模板配置,可以 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改,
// 放置自己项目的 src/main/resources/templates 目录下, 默认名称一下可以不配置,也可以自定义模板名称
// TemplateConfig tc = new TemplateConfig();
// tc.setController("...");
// tc.setEntity("...");
// tc.setMapper("...");
// tc.setXml("...");
// tc.setService("...");
// tc.setServiceImpl("...");
// 如上任何一个模块如果设置 空 OR Null 将不生成该模块。
// mpg.setTemplate(tc);

// 执行生成
mpg.execute();

// 打印注入设置【可无】
System.err.println(mpg.getCfg().getMap().get("abc"));
}

}

执行代码生成器的Main方法

执行代码后,在对应的目录自动生成了文件

启动项目

并访问列表页路径 http://localhost:8080/admin/goods/list

点击导出按钮(由于篇幅有限,导出的视图对象,导出service类和aop切面实现本文没有阐述,各位可自行下载代码查看)

总结

本文为项目自动生成前后端代码提供了思路:我们可以为项目的增删改查业务编写一套规范的代码,以此编写代码模板,后续通过代码生成器,通过数据库的一张表可快速生成前后端代码,提高项目组的开发效率。

代码

github.com/pengziliu/G…

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%