AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
MyBatis-Plus 从 3.0.3
之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖
<!--mybatis-plus代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
mysql数据库连接器,连接数据库获取信息
<!--mysql数据库连接器-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
Freemarker模板引擎,自定义生成模板
<!--freemarker模板引擎-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
代码生成器代码,只生成mapper、entity、service。配置参考:https://mybatis.plus/config/generator-config.html
/**
* @author zqq
*/
public class Generator {
//工程路径
private static final String projectPath = "D:\\workspace\\mybatisplus"; //System.getProperty("user.dir")
//数据库连接信息
private static final String jdbc_url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC";
private static final String driver_name = "com.mysql.cj.jdbc.Driver";
private static final String user_name = "root";
private static final String password = "root";
//表名
private static final String[] tableNames = {
"member"};
//作者
private static final String author = "zqq";
//包路径
private static final String entity_package = "com.example.demo.core";
private static final String dao_package = "com.example.demo.mapper";
private static final String service_package = "com.example.demo.service";
private static final String service_impl_package = "com.example.demo.service.impl";
private static final String mapper_xml_pah = projectPath + "/src/main/resources/mapper/"; //自定义xml文件路径
//是否使用LomBok生成类信息
private static final Boolean useLomBok = true;
public static void main(String[] args) {
new Generator().execute();
}
public void execute(){
//代码生成器
AutoGenerator generator = new AutoGenerator();
//全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(projectPath + "/src/main/java"); //生成文件的输出目录
globalConfig.setFileOverride(true);//是否覆盖已有文件,默认false
globalConfig.setAuthor(author);//开发人员,默认null
globalConfig.setOpen(false);//是否打开输出目录,默认true
globalConfig.setEntityName("%s");//实体命名方式,%s占位符
globalConfig.setMapperName("%sMapper");
globalConfig.setXmlName("%sMapper");
globalConfig.setServiceName("%sService");
globalConfig.setServiceImplName("%sServiceImpl");
generator.setGlobalConfig(globalConfig);
//数据源配置
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setUrl(jdbc_url);
dataSourceConfig.setDriverName(driver_name);
dataSourceConfig.setUsername(user_name);
dataSourceConfig.setPassword(password);
generator.setDataSource(dataSourceConfig);
//包配置
PackageConfig packageConfig = new PackageConfig();
packageConfig.setParent(null); //父包名,如果为空,将下面子包名必须写全部, 否则就只需写子包名
packageConfig.setEntity(entity_package);//实体报名
packageConfig.setMapper(dao_package);//mapper包名
packageConfig.setService(service_package);//service接口包名
packageConfig.setServiceImpl(service_impl_package);//service实现类包名
generator.setPackageInfo(packageConfig);
//自定义配置,生成默认方法,在 resources下Freemarker模板判断生成
InjectionConfig injectionConfig = new InjectionConfig() {
@Override
public void initMap() {
//在.ftl模板中,通过${cfg.findById}获取属性
//自定义默认方法,改为false不生成
Map<String,Object> map = new HashMap<String,Object>(6);
map.put("findById",true);
map.put("deleteById",true);
map.put("updateById",true);
map.put("insert",true);
map.put("insertBatch",true);
map.put("updateBatch",true);
this.setMap(map);
}
};
//freemarker模板引擎
String mapperXml = "/templates/mapper.xml.ftl";
//自定义配置会被优先输出
List<FileOutConfig> fileOutConfigs = new ArrayList<FileOutConfig>();
fileOutConfigs.add(new FileOutConfig(mapperXml) {
@Override
public String outputFile(TableInfo tableInfo) {
return mapper_xml_pah + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
injectionConfig.setFileOutConfigList(fileOutConfigs);
generator.setCfg(injectionConfig);
//模板配置
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setXml(null); //设置成null则不生成
templateConfig.setController(null);
//templateConfig.setEntity(null);
//templateConfig.setService(null);
//templateConfig.setServiceImpl(null);
//templateConfig.setMapper(null);
generator.setTemplate(templateConfig);
//策略配置
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig.setNaming(NamingStrategy.underline_to_camel);// 数据库表映射到实体的命名策略
strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略, 未指定按照 naming 执行
//strategyConfig.setSuperEntityClass(null); // 自定义继承的Entity类全称,带包名
strategyConfig.setInclude(tableNames);//表明,多个用逗号隔开
strategyConfig.setControllerMappingHyphenStyle(true); //驼峰转连字符
strategyConfig.setEntityLombokModel(useLomBok);//是否使用Lombok
strategyConfig.setEntitySerialVersionUID(false);
generator.setStrategy(strategyConfig);
generator.setTemplateEngine(new FreemarkerTemplateEngine()); //设置模板
generator.execute();//执行
}
自定义Freemarker模板(放在项目resources/templates下默认生效),默认的模板可去FreemarkerTemplateEngine类引入的jar包下,templates文件夹下
实体类模板entity.java.ftl(几乎没改动,与默认模板差不多)
package ${package.Entity};
<#list table.importPackages as pkg>
import ${pkg};
</#list>
<#if swagger2>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.Data;
import lombok.EqualsAndHashCode;
<#if chainModel>
import lombok.experimental.Accessors;
</#if>
</#if>
/**
* <p>
* ${table.comment!}
* </p>
*
* @author ${author}
* @since ${date}
*/
<#if entityLombokModel>
@Data
<#if superEntityClass??>
@EqualsAndHashCode(callSuper = true)
<#else>
@EqualsAndHashCode(callSuper = false)
</#if>
<#if chainModel>
@Accessors(chain = true)
</#if>
</#if>
<#if table.convert>
@TableName("${table.name}")
</#if>
<#if swagger2>
@ApiModel(value="${entity}对象", description="${table.comment!}")
</#if>
<#if superEntityClass??>
public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> {
<#elseif activeRecord>
public class ${entity} extends Model<${entity}> {
<#else>
public class ${entity} implements Serializable {
</#if>
<#if entitySerialVersionUID>
private static final long serialVersionUID = 1L;
</#if>
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field>
<#if field.keyFlag>
<#assign keyPropertyName="${field.propertyName}"/>
</#if>
<#if field.comment!?length gt 0>
<#if swagger2>
@ApiModelProperty(value = "${field.comment}")
<#else>
/**
* ${field.comment}
*/
</#if>
</#if>
<#if field.keyFlag>
<#-- 主键 -->
<#if field.keyIdentityFlag>
@TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
<#elseif idType??>
@TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
<#elseif field.convert>
@TableId("${field.annotationColumnName}")
</#if>
<#-- 普通字段 -->
<#elseif field.fill??>
<#-- ----- 存在字段填充设置 ----->
<#if field.convert>
@TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
<#else>
@TableField(fill = FieldFill.${field.fill})
</#if>
<#elseif field.convert>
@TableField("${field.annotationColumnName}")
</#if>
<#-- 乐观锁注解 -->
<#if (versionFieldName!"") == field.name>
@Version
</#if>
<#-- 逻辑删除注解 -->
<#if (logicDeleteFieldName!"") == field.name>
@TableLogic
</#if>
private ${field.propertyType} ${field.propertyName};
</#list>
<#------------ END 字段循环遍历 ---------->
<#if !entityLombokModel>
<#list table.fields as field>
<#if field.propertyType == "boolean">
<#assign getprefix="is"/>
<#else>
<#assign getprefix="get"/>
</#if>
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}
<#if chainModel>
public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
<#else>
public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
</#if>
this.${field.propertyName} = ${field.propertyName};
<#if chainModel>
return this;
</#if>
}
</#list>
</#if>
<#if entityColumnConstant>
<#list table.fields as field>
public static final String ${field.name?upper_case} = "${field.name}";
</#list>
</#if>
<#if activeRecord>
@Override
protected Serializable pkVal() {
<#if keyPropertyName??>
return this.${keyPropertyName};
<#else>
return null;
</#if>
}
</#if>
<#if !entityLombokModel>
@Override
public String toString() {
return "${entity}{" +
<#list table.fields as field>
<#if field_index==0>
"${field.propertyName}=" + ${field.propertyName} +
<#else>
", ${field.propertyName}=" + ${field.propertyName} +
</#if>
</#list>
"}";
}
</#if>
}
mapper.xml模板mapper.xml.ftl,自己的默认增删改查方法。
<?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}">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
<#--设置主键字段名默认为id,后续id取值取primary_key-->
<#assign primary_key = "id"/>
<#--实体里对应的id主键-->
<#assign property_id = "id"/>
<#list table.fields as field>
<#--生成主键-->
<#if field.keyFlag>
<#--设置主键-->
<#assign primary_key = "${field.name}"/>
<#assign property_id = "${field.propertyName}"/>
<id column="${field.name}" property="${field.propertyName}" />
</#if>
</#list>
<#list table.fields as field>
<#--生成字段 -->
<#if !field.keyFlag>
<#--${field.name} 数据库字段,${field.propertyName} 实体类字段(数据库字段驼峰命名)-->
<result column="${field.name}" property="${field.propertyName}" />
</#if>
</#list>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
${table.fieldNames}
</sql>
<#--根据id查询-->
<#if cfg.findById>
<select id="findById" resultMap="BaseResultMap" parameterType="java.lang.String">
select
<include refid="Base_Column_List"/>
<#--<#noparse>,FreeMarker 不会在这个指令体中间寻找FTL标签-->
from ${table.name} where ${primary_key} = #<#noparse>{
</#noparse>id}
</select>
</#if>
<#--根据id删除-->
<#if cfg.deleteById>
<delete id="deleteById" parameterType="java.lang.String">
delete from ${table.name} where ${primary_key} = #<#noparse>{
</#noparse>id}
</delete>
</#if>
<#--根据id修改-->
<#if cfg.updateById>
<update id="updateById" parameterType="${package.Entity}.${entity}">
update ${table.name}
<set>
<#list table.fields as field>
<#if !field.keyFlag>
<if test="${field.propertyName} != null<#if field.propertyType == 'String'> and ${field.propertyName} != ''</#if>">
${field.name} = #<#noparse>{
</#noparse>${field.name}},
</if>
</#if>
</#list>
</set>
where ${primary_key} = #<#noparse>{
</#noparse>id}
</update>
</#if>
<#--插入-->
<#if cfg.insert>
<insert id="insert" parameterType="${package.Entity}.${entity}">
insert into ${table.name}
(
<#list table.fields as field>
${field.name}<#if field_has_next>,</#if>
</#list>
) values
(
<#list table.fields as field>
#<#noparse>{
</#noparse>${field.propertyName}}<#if field_has_next>,</#if>
</#list>
)
</insert>
</#if>
<#if cfg.insertBatch>
<insert id="insertBatch">
insert into ${table.name}
(
<#list table.fields as field>
${field.name}<#if field_has_next>,</#if>
</#list>
) values
<foreach collection="list" item="item" separator=",">
(
<#list table.fields as field>
#<#noparse>{item.</#noparse>${field.propertyName}}<#if field_has_next>,</#if>
</#list>
)
</foreach>
</insert>
</#if>
<#--批量修改-->
<#if cfg.updateBatch>
<update id="updateBatch">
update ${table.name}
<set>
<#list table.fields as field>
<#if !field.keyFlag>
<foreach collection="list" item="item" open="${field.name} = ( case" close="end)<#if field_has_next>,</#if>">
when ${primary_key} = #<#noparse>{item.</#noparse>${property_id}} then
<choose>
<when test="item.${field.propertyName} == null">
${field.name}
</when>
<otherwise>
#<#noparse>{item.</#noparse>${field.propertyName}}
</otherwise>
</choose>
</foreach>
</#if>
</#list>
</set>
where ${primary_key} in
<foreach collection="list" item="item" open="(" close=")" separator=",">
#<#noparse>{item.</#noparse>${property_id}}
</foreach>
</update>
</#if>
</mapper>
mapper模板mapper.java.ftl
package ${package.Mapper};
import ${package.Entity}.${entity};
import ${superMapperClassPackage};
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author ${author}
* @since ${date}
*/
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
<#if cfg.findById>
/**
* 根据id查询
* @param id
* @return ${entity}
*/
${entity} findById(@Param("id")String id);
</#if>
<#if cfg.deleteById>
/**
* 根据id删除
* @param id
*/
int deleteById(@Param("id")String id);
</#if>
<#if cfg.updateById>
/**
* 修改
* @param ${entity?uncap_first}
*/
int updateById(${entity} ${entity?uncap_first});
</#if>
<#if cfg.insert>
/**
* 插入
* @param ${entity?uncap_first}
*/
int insert(${entity} ${entity?uncap_first});
</#if>
<#if cfg.insertBatch>
/**
* 批量插入
* @param list
*/
int insertBatch(@Param("list")List<${entity}> list);
</#if>
<#if cfg.updateBatch>
/**
* 批量修改
* @param list
*/
void updateBatch(@Param("list")List<${entity}> list);
</#if>
}
service模板service.java.ftl
package ${package.Service};
import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import java.util.List;
/**
* @author ${author}
* @since ${date}
*/
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
<#if cfg.findById>
/**
* 根据id查询
* @param id
* @return ${entity}
*/
${entity} findById(String id);
</#if>
<#if cfg.deleteById>
/**
* 根据id删除
* @param id
*/
void deleteById(String id);
</#if>
<#if cfg.updateById>
/**
* 修改
* @param ${entity?uncap_first}
*/
void update${entity}(${entity} ${entity?uncap_first});
</#if>
<#if cfg.insert>
/**
* 插入
* @param ${entity?uncap_first}
*/
void insert(${entity} ${entity?uncap_first});
</#if>
<#if cfg.insertBatch>
/**
* 批量插入
* @param list
*/
void insertBatch(List<${entity}> list);
</#if>
<#if cfg.updateBatch>
/**
* 批量修改
* @param list
*/
void updateBatch(List<${entity}> list);
</#if>
}
serviceImpl模板serviceImpl.java.ftl
扫描二维码关注公众号,回复:
12646682 查看本文章

package ${package.ServiceImpl};
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author ${author}
* @since ${date}
*/
@Service
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
<#if cfg.findById>
@Override
public ${entity} findById(String id) {
return getBaseMapper().findById(id);
}
</#if>
<#if cfg.findById>
@Override
public void deleteById(String id) {
getBaseMapper().deleteById(id);
}
</#if>
<#if cfg.updateById>
@Override
public void update${entity}(${entity} ${entity?uncap_first}) {
getBaseMapper().updateById(${entity?uncap_first});
}
</#if>
<#if cfg.insert>
@Override
public void insert(${entity} ${entity?uncap_first}) {
getBaseMapper().insert(${entity?uncap_first});
}
</#if>
<#if cfg.insertBatch>
@Override
public void insertBatch(List<${entity}> list) {
getBaseMapper().insertBatch(list);
}
</#if>
<#if cfg.updateBatch>
@Override
public void updateBatch(List<${entity}> list) {
getBaseMapper().updateBatch(list);
}
</#if>
}
代码生成器执行输出mapper.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="com.example.demo.mapper.MemberMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.example.demo.core.Member">
<id column="id" property="id" />
<result column="name" property="name" />
<result column="code" property="code" />
<result column="amount" property="amount" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, name, code, amount
</sql>
<select id="findById" resultMap="BaseResultMap" parameterType="java.lang.String">
select
<include refid="Base_Column_List"/>
from member where id = #{id}
</select>
<delete id="deleteById" parameterType="java.lang.String">
delete from member where id = #{id}
</delete>
<update id="updateById" parameterType="com.example.demo.core.Member">
update member
<set>
<if test="name != null and name != ''">
name = #{name},
</if>
<if test="code != null and code != ''">
code = #{code},
</if>
<if test="amount != null">
amount = #{amount},
</if>
</set>
where id = #{id}
</update>
<insert id="insert" parameterType="com.example.demo.core.Member">
insert into member
(
id,
name,
code,
amount
) values
(
#{id},
#{name},
#{code},
#{amount}
)
</insert>
<insert id="insertBatch">
insert into member
(
id,
name,
code,
amount
) values
<foreach collection="list" item="item" separator=",">
(
#{item.id},
#{item.name},
#{item.code},
#{item.amount}
)
</foreach>
</insert>
<update id="updateBatch">
update member
<set>
<foreach collection="list" item="item" open="name = ( case" close="end),">
when id = #{item.id} then
<choose>
<when test="item.name == null">
name
</when>
<otherwise>
#{item.name}
</otherwise>
</choose>
</foreach>
<foreach collection="list" item="item" open="code = ( case" close="end),">
when id = #{item.id} then
<choose>
<when test="item.code == null">
code
</when>
<otherwise>
#{item.code}
</otherwise>
</choose>
</foreach>
<foreach collection="list" item="item" open="amount = ( case" close="end)">
when id = #{item.id} then
<choose>
<when test="item.amount == null">
amount
</when>
<otherwise>
#{item.amount}
</otherwise>
</choose>
</foreach>
</set>
where id in
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item.id}
</foreach>
</update>
</mapper>
增删改查测试
/**
* @author zqq
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class GeneratorTest {
@Autowired
private MemberService memberService;
@Test
public void insert(){
Member member = new Member();
member.setAmount(BigDecimal.TEN);
member.setCode("AUD");
member.setName("jom");
memberService.insert(member);
}
@Test
public void insertBatch(){
List<Member> list = new ArrayList<>();
list.add(new Member("tom","HKD",BigDecimal.ONE));
list.add(new Member("jack","GBP",BigDecimal.ZERO));
list.add(new Member("jams","UFO",BigDecimal.TEN));
memberService.insertBatch(list);
}
@Test
public void update(){
Member member = new Member();
member.setId(17);
member.setName("name17");
member.setAmount(new BigDecimal(17));
member.setCode("code17");
memberService.updateMember(member);
}
@Test
public void updateBatch(){
List<Member> list = new ArrayList<>();
list.add(new Member(18,"name18","code18",new BigDecimal(18)));
list.add(new Member(19,"name19","code19",new BigDecimal(19)));
list.add(new Member(20,"name20","code20",new BigDecimal(20)));
memberService.updateBatch(list);
}
@Test
public void findById(){
Member member = memberService.findById("18");
System.out.println(member.toString());
}
@Test
public void deleteById(){
memberService.deleteById("18");
}
}
代码地址:https://github.com/zqq441412318/generator/archive/master.zip