使用mybatis-generator生成自动代码
2019-02-22
配置文件:
pom.xml 添加 dependency plugin 基于mybatis-plus
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.6</version>
<scope>compile</scope>
</dependency>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.6</version>
<configuration>
<!--配置文件的位置-->
<configurationFile>generator.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
<executions>
<execution>
<id>Generate MyBatis Artifacts</id>
<phase>deploy</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.6</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency> <dependency>
<groupId>my.base.project</groupId>
<artifactId>base-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency> </dependencies>
</plugin>
generatorConfiguration.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 引入配置文件 -->
<properties resource="generator.properties" /> <context id="default" targetRuntime="MyBatis3">
<!-- 生成的Java文件的编码 -->
<property name="javaFileEncoding" value="UTF-8" />
<!-- 格式化java代码 -->
<property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter" /> <!-- 使用自定义的插件 -->
<!-- 整合lombok -->
<plugin type="*.support.GeneratorPlugin"/> <commentGenerator>
<!-- 关闭自动生成的注释 -->
<property name="suppressAllComments" value="true"/>
<!--生成的注释包含时间戳-->
<property name="suppressDate" value="true"/>
</commentGenerator> <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="${jdbc.driver}"
connectionURL="${jdbc.url}"
userId="${jdbc.username}"
password="${jdbc.password}">
<!-- 字段注解 针对oracle数据库 -->
<property name="remarksReporting" value="true" />
<!-- 字段注解 针对mysql数据库 -->
<property name="useInformationSchema" value="true"/>
</jdbcConnection> <!-- 类型转换 -->
<javaTypeResolver>
<!-- 是否使用bigDecimal
默认false:把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,
为 true时:把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal
-->
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver> <!-- 生成实体类 -->
<!-- targetPackage:生成实体类的包名 -->
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="${model.package}"
targetProject="${target.project}/java">
<!--所有实体类继承BasePojo类-->
<property name="rootClass" value="*.base.BaseModel"/>
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="false"/>
</javaModelGenerator> <!-- 生成XxxMapper.xml文件 -->
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="${xml.mapper.package}"
targetProject="${target.project}/resources">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator> <!-- 生成XxxMapper.java文件 -->
<!--ANNOTATEDMAPPER: 生成java类文件,基于注解的Mapper接口,不会有对应的XML映射文件
MIXEDMAPPER:XML和注解的混合形式
XMLMAPPER:所有的方法都在XML中,接口调用依赖XML文件 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="${mapper.package}"
targetProject="${target.project}/java">
<property name="enableSubPackages" value="false"/>
</javaClientGenerator> <table schema="JTP"
tableName="${table.name}"
domainObjectName="${table.domainObjectName}" enableSelectByPrimaryKey="true" enableInsert="false"
enableUpdateByPrimaryKey="false"
enableDeleteByPrimaryKey="false" enableSelectByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableCountByExample="false"
selectByExampleQueryId="false">
</table>
</context>
</generatorConfiguration>
generator.properties config 使用的参数
# 数据库连接配置
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@ip:orcl
jdbc.username=name
jdbc.password=password # 文件路径配置
model.package=*.model.menu
mapper.package=*.mapper
xml.mapper.package=mapper.db
target.project=src/main # 执行的表数据
table.name=SYS_MENU_T
table.domainObjectName=Menu
自定义插件文件:
GeneratorPlugin.java Model自定义注释,Inteface 自定义基类,xml删除多余方法 支持lombok插件
import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.api.GeneratedXmlFile;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.Element; import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List; /**
* Mybatis 代码生成自定义插件
* A MyBatis Generator plugin to use Lombok's annotations.
* For example, use @Data annotation instead of getter ands setter.
*
* @className GeneratorPlugin
* @author joe
* @version V1.0.0
* @date 2019-01-16
*/
public class GeneratorPlugin extends PluginAdapter { private final Collection<Annotations> annotations; /**
* GeneratorPlugin constructor
*/
public GeneratorPlugin() {
annotations = new LinkedHashSet<>(Annotations.values().length);
} /**
* @param warnings list of warnings
* @return always true
*/
@Override
public boolean validate(List<String> warnings) {
return true;
} /**
* Intercepts base record class generation
*
* @param topLevelClass the generated base record class
* @param introspectedTable The class containing information about the table as
* introspected from the database
* @return always true
*/
@Override
public boolean modelBaseRecordClassGenerated(
TopLevelClass topLevelClass,
IntrospectedTable introspectedTable
) {
addModelClassComment(topLevelClass, introspectedTable);
return true;
} /**
* Intercepts primary key class generation
*
* @param topLevelClass the generated primary key class
* @param introspectedTable The class containing information about the table as
* introspected from the database
* @return always true
*/
@Override
public boolean modelPrimaryKeyClassGenerated(
TopLevelClass topLevelClass,
IntrospectedTable introspectedTable
) {
addModelClassComment(topLevelClass, introspectedTable);
return true;
} /**
* Intercepts "record with blob" class generation
*
* @param topLevelClass the generated record with BLOBs class
* @param introspectedTable The class containing information about the table as
* introspected from the database
* @return always true
*/
@Override
public boolean modelRecordWithBLOBsClassGenerated(
TopLevelClass topLevelClass,
IntrospectedTable introspectedTable
) {
addModelClassComment(topLevelClass, introspectedTable);
return true;
} /**
* 类属性注释
*
* @param field 属性
* @param topLevelClass 类对象
* @param introspectedColumn 列
* @param introspectedTable 表
* @param modelClassType Class类型
* @return true
*/
@Override
public boolean modelFieldGenerated(Field field,
TopLevelClass topLevelClass,
IntrospectedColumn introspectedColumn,
IntrospectedTable introspectedTable,
ModelClassType modelClassType) {
StringBuilder sb = new StringBuilder();
field.addJavaDocLine("/**");
sb.append(" * ");
// 字段注释
sb.append(columnRemarks(introspectedColumn.getRemarks()));
field.addJavaDocLine(sb.toString().replace("\n", " "));
field.addJavaDocLine(" */"); // 主键
if (introspectedTable.getPrimaryKeyColumns().stream()
.anyMatch(p -> p.equals(introspectedColumn))) {
field.addAnnotation("@TableId");
} // 字段上生成@TableField注解
field.addAnnotation("@TableField(value = \"" + introspectedColumn.getActualColumnName() + "\")");
return true;
} /**
* Prevents all getters from being generated.
* See SimpleModelGenerator
*
* @param method the getter, or accessor, method generated for the specified
* column
* @param topLevelClass the partially implemented model class
* @param introspectedColumn The class containing information about the column related
* to this field as introspected from the database
* @param introspectedTable The class containing information about the table as
* introspected from the database
* @param modelClassType the type of class that the field is generated for
*/
@Override
public boolean modelGetterMethodGenerated(
Method method,
TopLevelClass topLevelClass,
IntrospectedColumn introspectedColumn,
IntrospectedTable introspectedTable,
ModelClassType modelClassType
) {
return false;
} /**
* Prevents all setters from being generated
* See SimpleModelGenerator
*
* @param method the setter, or mutator, method generated for the specified
* column
* @param topLevelClass the partially implemented model class
* @param introspectedColumn The class containing information about the column related
* to this field as introspected from the database
* @param introspectedTable The class containing information about the table as
* introspected from the database
* @param modelClassType the type of class that the field is generated for
* @return always false
*/
@Override
public boolean modelSetterMethodGenerated(
Method method,
TopLevelClass topLevelClass,
IntrospectedColumn introspectedColumn,
IntrospectedTable introspectedTable,
ModelClassType modelClassType
) {
return false;
} /**
* 增加类注释
*
* @param topLevelClass 类
* @param introspectedTable 表数据
*/
private void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { topLevelClass.addJavaDocLine("/**");
topLevelClass.addJavaDocLine(" * " + tableRemarks(introspectedTable));
topLevelClass.addJavaDocLine(" * ");
topLevelClass.addJavaDocLine(" * @author " + System.getProperty("user.name"));
topLevelClass.addJavaDocLine(" * @date " + new Date().toString());
topLevelClass.addJavaDocLine(" *");
topLevelClass.addJavaDocLine(" */"); addAnnotations(topLevelClass); topLevelClass.addImportedType("com.baomidou.mybatisplus.annotation.TableField");
topLevelClass.addImportedType("com.baomidou.mybatisplus.annotation.TableId");
topLevelClass.addImportedType("com.baomidou.mybatisplus.annotation.TableName"); // 添加类注解
// 表名
String tableName = introspectedTable.getFullyQualifiedTable().getIntrospectedTableName();
topLevelClass.addAnnotation(String.format("@TableName(\"%s\")", tableName));
} /**
* Adds the lombok annotations' imports and annotations to the class
*
* @param topLevelClass the partially implemented model class
*/
private void addAnnotations(TopLevelClass topLevelClass) {
//@Data is default annotation
annotations.add(Annotations.DATA);
annotations.add(Annotations.EQUALS); for (Annotations annotation : annotations) {
topLevelClass.addImportedType(annotation.javaType);
topLevelClass.addAnnotation(annotation.name);
}
} /**
* 数据字典类型 mapper
*/
@Override
public boolean clientGenerated(
Interface interfaze,
TopLevelClass topLevelClass,
IntrospectedTable introspectedTable
) { interfaze.addJavaDocLine("/**");
interfaze.addJavaDocLine(" * " + tableRemarks(introspectedTable) + " Mapper");
interfaze.addJavaDocLine(" * ");
interfaze.addJavaDocLine(" * @author " + System.getProperty("user.name"));
interfaze.addJavaDocLine(" * @date " + new Date().toString());
interfaze.addJavaDocLine(" *");
interfaze.addJavaDocLine(" */"); interfaze.addImportedType(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Mapper"));
interfaze.addAnnotation("@Mapper"); interfaze.addImportedType(new FullyQualifiedJavaType("com.baomidou.mybatisplus.core.mapper.BaseMapper")); FullyQualifiedJavaType superMapper =
new FullyQualifiedJavaType(String.format("BaseMapper<%s>", introspectedTable.getBaseRecordType())); // 添加 extends MybatisPlusBaseMapper
interfaze.addSuperInterface(superMapper); // 清理方法
interfaze.getMethods().clear(); return true;
} @Override
public boolean sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) {
// 设置 xml文件时覆盖写 默认:true [mybatis generator默认采用追加方式生成]
sqlMap.setMergeable(false);
return super.sqlMapGenerated(sqlMap, introspectedTable);
} @Override
public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
// 之前 table 配置 保留了 一个SelectByPrimaryKey 设置为true 此处删除
List<Element> list = document.getRootElement().getElements();
list.remove(list.size() - 1);
return true;
} private String tableRemarks(IntrospectedTable introspectedTable) {
String remark = introspectedTable.getRemarks();
if (StringUtils.isEmpty(remark)) {
return introspectedTable.getFullyQualifiedTable().getIntrospectedTableName();
}
return remark;
} private String columnRemarks(String remark) {
if (StringUtils.isEmpty(remark)) {
return "TODO add remark";
}
return remark;
} /**
* Lombok 相关的注解
*
* @className Annotations
* @author joe
* @version V1.0.0
* @date 2019-02-21 10:35
*/
private enum Annotations {
/**
* data
*/
DATA("data", "@Data", "lombok.Data"),
BUILDER("builder", "@Builder", "lombok.Builder"),
EQUALS("equalsAndHashCode", "@EqualsAndHashCode(callSuper = false)", "lombok.EqualsAndHashCode"),
ALL_ARGS_CONSTRUCTOR("allArgsConstructor", "@AllArgsConstructor", "lombok.AllArgsConstructor"),
NO_ARGS_CONSTRUCTOR("noArgsConstructor", "@NoArgsConstructor", "lombok.NoArgsConstructor"),
ACCESSORS("accessors", "@Accessors", "lombok.experimental.Accessors"),
TO_STRING("toString", "@ToString", "lombok.ToString"); private final String paramName;
private final String name;
private final FullyQualifiedJavaType javaType; Annotations(String paramName, String name, String className) {
this.paramName = paramName;
this.name = name;
this.javaType = new FullyQualifiedJavaType(className);
} }
}
使用方式:
mvn mybatis-generator:generate
如果是在intellij 环境,直接鼠标点击即可
生成效果:
import *.base.BaseModel;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode; /**
* 系统菜单
*
* @author joe
* @date 2019-01-20
*
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("SYS_MENU_T")
public class Menu extends BaseModel {
/**
* 菜单ID
*/
@TableId
@TableField(value = "MENU_ID")
private String menuId; /**
* 菜单编码,不允许重复
*/
@TableField(value = "MENU_CODE")
private String menuCode; /**
* 菜单名称,同一个级别下不允许重复
*/
@TableField(value = "MENU_NAME")
private String menuName;
}
import *.MenuEO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; /**
* 系统菜单 Mapper
*
* @author joe
* @date 2019-01-22 16:24
*
*/
@Mapper
public interface MenuMapper extends BaseMapper<Menu> {
}
<?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="*.mapper.MenuMapper">
<resultMap id="BaseResultMap" type="*.Menu">
<id column="MENU_ID" jdbcType="VARCHAR" property="menuId" />
<result column="MENU_CODE" jdbcType="VARCHAR" property="menuCode" />
<result column="MENU_NAME" jdbcType="VARCHAR" property="menuName" />
</resultMap>
<sql id="Base_Column_List">
MENU_ID, MENU_CODE, MENU_NAME
</sql>
</mapper>
常见问题:
1、运行报错,找不到自定义的插件类[generate failed: Cannot instantiate object of type *.MyPlugin]
原因:mybatis-generator 的plugin有自己的classpath,我们在项目中直接继承的类和plugin不属于同一个classpath
解决:把插件类打基础包,再pom的plugin配置中被 mybatis-generator 的plugin 依赖。
2、报错[There are no statements enabled for table mybatis.category, this table will be ignored.]
原因:generatorConfig.xml中,<table>标签配成 所有原始的sql都是false
解决:保留一个时true的设置,再插件中处理xml时再删除。
3、获取不到数据库字段的注释
原因:mysql 和 oracle的数据库配置不同,确认配置
解决:在generatorConfiguration.xml配置文件中配置
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="${jdbc.driver}"
connectionURL="${jdbc.url}"
userId="${jdbc.username}"
password="${jdbc.password}">
<!-- 字段注解 针对oracle数据库 -->
<property name="remarksReporting" value="true" />
<!-- 字段注解 针对mysql数据库 -->
<property name="useInformationSchema" value="true"/>
</jdbcConnection>
4、xml文件再次生成时被追加
原因:mybatis generator默认采用追加方式生成
解决:重写sqlMapGenerated方法。设置sqlMap.setMergeable(false);。默认情况下isMergeable为true,所以在这里设置为false。
mybatis-generator.xml配置文件详解 参考 https://blog.csdn.net/weixin_39805338/article/details/80999186
使用mybatis-generator生成自动代码的更多相关文章
- Eclipse 使用mybatis generator插件自动生成代码
Eclipse 使用mybatis generator插件自动生成代码 标签: mybatis 2016-12-07 15:10 5247人阅读 评论(0) 收藏 举报 .embody{ paddin ...
- mybatis Generator生成代码及使用方式
本文原创,转载请注明:http://www.cnblogs.com/fengzheng/p/5889312.html 为什么要有mybatis mybatis 是一个 Java 的 ORM 框架,OR ...
- MyBatis Generator 生成的example 使用 and or 简单混合查询
MyBatis Generator 生成的example 使用 and or 简单混合查询 参考博客:https://www.cnblogs.com/kangping/p/6001519.html 简 ...
- 【记录】Mybatis Generator生成数据对象Date/TimeStamp 查询时间格式化
Mybatis Generator是很好的工具帮助我们生成表映射关联代码,最近博主遇到一个问题,找了很久才解决, 就是用Mybatis Generator生成实体类的时候,Date 时间无法格式化输出 ...
- MyBatis Generator生成DAO——序列化
MyBatis Generator生成DAO 的时候,生成的类都是没有序列化的. 还以为要手工加入(開始是手工加入的),今天遇到分页的问题,才发现生成的时候能够加入插件. 既然分页能够有插件.序列化是 ...
- 利用org.mybatis.generator生成实体类
springboot+maven+mybatis+mysql 利用org.mybatis.generator生成实体类 1.添加pom依赖: 2.编写generatorConfig.xml文件 ( ...
- Maven下用MyBatis Generator生成文件
使用Maven命令用MyBatis Generator生成MyBatis的文件步骤如下: 1.在mop文件内添加plugin <build> <finalName>KenShr ...
- JAVA入门[7]-Mybatis generator(MBG)自动生成mybatis代码
一.新建测试项目 新建Maven项目MybatisDemo2,修改pom.xml引入依赖.dependencies在上节基础上新增 <dependency> <groupId> ...
- springboot(十三):springboot结合mybatis generator逆向工程自动生成代码
错信息generate failed: Exception getting JDBC Driver: com.mysql.jdbc.Driver 上网查了一下,发现原来是generator这个插件在运 ...
- 使用Mybatis Generator插件自动生成映射文件(cmd无法进入文件,dns服务器对区域没有权威等问题)遇到问题
使用Mybatis Genertor插件自动生MyBatis所需要的DAO接口,实体模型类,Mapping映射文件,将生成的代码赋值到项目工程中即可. 有命令行,Eclipse插 ...
随机推荐
- Day 6 编码的进阶
https://blog.csdn.net/Deft_MKJing/article/details/79460485 a.ascii码:8位表示一个字符,共可以表示2**8个(即256)字符 , ...
- CentOS 7 - 安装Windows字体!
1,安装cabextract: 下载地址:http://ftp.tu-chemnitz.de/pub/linux/dag/redhat/el7/en/x86_64/rpmforge/RPMS/cabe ...
- es6中箭头函数 注意点
var aaabbb = 'kkkooo' setTimeout(()=>{ var aaaa = 'kkkk'; console.log(this) },1000); 因为据我了解,箭头函数指 ...
- [ActionScript 3.0] UDP通信
package com.controls.socket { import flash.events.DatagramSocketDataEvent; import flash.events.Event ...
- linux 服务器性能监控(一)
这篇文章主要介绍一些常用的linux服务器性能监控命令,包括命令的常用参数.指标的含义以及一些交互操作. 几个问题 命令本身并不复杂,关键是你对操作系统基础知识的掌握和理解,先来看看下面几个问题: C ...
- spring定时任务的注解实现方式
STEP 1:在spring配置文件中添加相应配置,以支持定时任务的注解实现 (一)在xml里加入task的命名空间 <!-- beans里添加:--> xmlns:task=" ...
- Python “ValueError: incomplete format” print(“a%” % ”)
解决python打印%号和%format输出问题 >>> print('%s' %'1') 1 >>> print('%s%' %'1') Traceback (m ...
- 使用git工具删除github上的文件或者文件夹
解决 使用git工具删除github上的文件或者文件夹 当我们需要从github上删除一些我们不需要的文件或者文件夹时,如果通过github来操作的话,将会很麻烦,因为github只允许删除一个仓库, ...
- 【bzoj4712】洪水 动态dp
不难发现此题是一道动态$dp$题 考虑此题没有修改怎么做,令$f[i]$表示让以$i$为根的子树被覆盖的最小花费,不难推出$f[i]=min(\sum_{j∈son[i]} f[j],val[i])$ ...
- Spring Security构建Rest服务-0200-搭建项目
一.代码结构: 二.使用Springmvc开发restful API 传统url和rest区别: 三.写代码 1,编写RestfulAPI的测试用例:使用MockMvc伪造mvc package co ...