Springboot+mybatis项目-通过数据库表、实体类 自动创建 DaoMapper类、mapper.xml

最近练习springboot项目,发现mybatis框架的mapper.xml和DaoMapper接口类方法实现太费劲了,所以找了一下如何能够通过自动化工具创建。

    首先我们需要在pom.xml文件中加入插件

    <plugins>
        <!-- mybatis generator 自动生成代码插件 -->
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.5</version>
            <configuration>
                <!--配置文件的位置-->
                <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
                <overwrite>true</overwrite>
                <verbose>true</verbose>
            </configuration>
        </plugin>
    </plugins>
    
    在对应的目录下创建generatorConfig.xml文件,内容如下

<?xml version="1.0" encoding="UTF-8"?>

<!-- 数据库驱动:选择你的本地硬盘上面的数据库驱动包-->
<classPathEntry location="C:/Users/fox/.m2/repository/mysql/mysql-connector-java/8.0.18/mysql-connector-java-8.0.18.jar" />

<!-- 配置数据源和生成的代码所存放的位置 -->
<context id="default" targetRuntime="MyBatis3">

    <!-- 指定生成的java文件的编码,没有直接生成到项目时中文可能会乱码 -->
    <property name="javaFileEncoding" value="UTF-8"/>

    <!-- 生成的实体Bean,将实现Serializable -->
    <plugin type="org.mybatis.generator.plugins.SerializablePlugin" />

    <!-- optional,旨在创建class时,对注释进行控制 -->
    <commentGenerator>
        <property name="suppressDate" value="true"/>
        <property name="suppressAllComments" value="true"/>
    </commentGenerator>

    <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
    <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                    connectionURL="jdbc:mysql://localhost:3306/robo?serverTimezone=UTC"
                    userId="root"
                    password="root">
        <property name="nullCatalogMeansCurrent" value="true"/>
        <property name="characterEncoding" value="utf-8" />
    </jdbcConnection>

    <!--java类型解析-->
    <javaTypeResolver>
        <!--默认false,把JDBC DECIMAL和NUMERIC 类型解析为 Integer
            若为true,把JDBC DECIMAL和NUMERIC 类型解析为java.math.BigDecimal -->
        <property name="forceBigDecimals" value="false"/>
    </javaTypeResolver>

    <!-- 生成entity类的包名和位置-->
    <javaModelGenerator targetPackage="com.yobotics.springboot_demo.entity"
                        targetProject="src/main/java">
        <property name="enableSubPackages" value="true"/>
        <property name="trimStrings" value="true"/>
    </javaModelGenerator>

    <!-- 生成对应的mapper.xml文件的包名和位置-->
    <sqlMapGenerator targetPackage="mapper"
                     targetProject="src/main/resources">
        <property name="enableSubPackages" value="true"/>
    </sqlMapGenerator>

    <!--生成对应的Mapper接口类文件的包名和位置,配置文件的类型为xml-->
    <javaClientGenerator type="XMLMAPPER"
                         targetPackage="com.yobotics.springboot_demo.dao"
                         targetProject="src/main/java">
        <property name="enableSubPackages" value="true"/>
    </javaClientGenerator>

    <!-- 数据表或视图与实体类Bean的映射 -->
    <table schema="" tableName="t_user" domainObjectName="User"
           enableCountByExample="false" enableUpdateByExample="false"
           enableDeleteByExample="false" enableSelectByExample="false"
           selectByExampleQueryId="false">
    </table>
    <table schema="" tableName="t_user_infomation" domainObjectName="UserInfomation"
           enableCountByExample="false" enableUpdateByExample="false"
           enableDeleteByExample="false" enableSelectByExample="false"
           selectByExampleQueryId="false">
    </table>

</context>

然后执行下边的配置文件就可以创建DaoMapper接口类和mapper.xml文件。

本篇文章讲解的Mybatis generator在Spring Boot上的实现

因为在一些小型企业,Mybatis相比Hibernate越来越流行,所以我觉得很有必要写一篇更加简单易懂的文章,来教会大家如何在Spring Boot上整合Mybatis并使用它的逆向工程

前提准备:
使用的工具:JDK1.8、IntelliJ IDEA、Mysql

首先:我们来看一下基本的目录结构:

数据库创建的表结构:

maven依赖的包与插件:

<?xml version="1.0" encoding="UTF-8"?> 
 4.0.0

 org.springframework.boot
 spring-boot-starter-parent
 2.1.6.RELEASE


 com.example
 app
 0.0.1-SNAPSHOT
 app
 Demo project for Spring Boot
<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    <mybatis-generator.version>1.3.7</mybatis-generator.version>
</properties>

<dependencies>

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

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.10</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- SpringBoot-MyBatis -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.0.1</version>
    </dependency>
    <!--mybatis分页插件:PageHelper插件-->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper-spring-boot-starter</artifactId>
        <version>1.0.0</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-json-org</artifactId>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-envers</artifactId>
    </dependency>

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpmime</artifactId>
    </dependency>

    <!-- SpringBoot-MyBatis逆向工程 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <!--mybatis逆向工程-->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>${mybatis-generator.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <fork>true</fork>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>${mybatis-generator.version}</version>
            <configuration>
                <!--允许移动生成的文件 -->
                <verbose>true</verbose>
                <!-- 是否覆盖 -->
                <overwrite>false</overwrite>
                <!-- 自动生成的配置 -->
                <configurationFile>src/main/resources/mybatis-generator.xml</configurationFile>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>5.1.47</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

application.yml文件配置:

server:
 port: 8088
 spring:
 profiles:
 active: native
 aop:
 auto: true
 proxy-target-class: true
 jpa:
 hibernate:
 ddl-auto: update
 show-sql: true
 open-in-view: true
 http:
 multipart:
 enabled: true
 max-file-size: 20MB #(这里是限制的文件大小)
 max-request-size: 20MB #(这里是限制的文件大小)spring:
 profiles: native
 cloud:
 config:
 server:
 native:
 search-locations: classpath:/shared

spring:

profiles: test
 cloud:
 config:
 server:
 git:
 uri: https://github.com/trusause/spring-cloud-test
 search-paths: my-config-server/src/main/resources/test
 username: trusause
 password: ai181003
 default-label: develop

app.yml:

server:
 port: 8091
 spring:
 jackson:
 date-format: yyyy-MM-dd HH:mm:ss
 time-zone: GMT+8
 datasource:
 type: com.alibaba.druid.pool.DruidDataSource
 # driver-class-name: com.mysql.jdbc.Driver
 driver-class-name: com.mysql.cj.jdbc.Driver
 url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
 username: root
 password: db_password
 initialSize: 5 # 下面为连接池的补充设置,应用到上面所有数据源中
 minIdle: 5 # 初始化大小,最小,最大
 maxActive: 20
 maxWait: 60000 # 配置获取连接等待超时的时间
 timeBetweenEvictionRunsMillis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
 validationQuery: SELECT 1 FROM DUAL # 配置一个连接在池中最小生存的时间,单位是毫秒
 testWhileIdle: true
 testOnBorrow: false
 testOnReturn: false
 poolPreparedStatements: true # 打开PSCache,并且指定每个连接上PSCache的大小
 maxPoolPreparedStatementPerConnectionSiz: 20
 filters: stat,wall,log4j # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall’用于防火墙
 connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

通过connectProperties属性来打开mergeSql功能;慢SQL记录

useGlobalDataSourceStat: true # 合并多个DruidDataSource的监控数据
#showsql
 logging:
 level:
 com:
 trusause:
 app:
 mapper: debugmybatis:
 mapper-locations: classpath:mapping/*.xml
 type-aliases-package: com.trusause.app#pagehelper
 pagehelper:
 helperDialect: mysql
 reasonable: true
 supportMethodsArguments: true
 params: count=countSql
 returnPageInfo: check
 generatorConfig.xml(逆向工程配置文件,如果使用maven插件启动,请保持文件名一致): <?xml version="1.0" encoding="UTF-8"?>



<commentGenerator>
        <!-- 是否去除自动生成的注释 true:是 : false:否 -->
        <property name="suppressAllComments" value="true"/>
    </commentGenerator>
    <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
    <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                    connectionURL="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false"
                    userId="root"
                    password="db_password">
    </jdbcConnection>
    <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
       NUMERIC 类型解析为java.math.BigDecimal -->
    <javaTypeResolver>
        <property name="forceBigDecimals" value="false"/>
    </javaTypeResolver>
    <!--指定javaBean生成的位置 javaBean生成的位置-->
    <javaModelGenerator targetPackage="com.trusause.app.domain" targetProject="./src/main/java">
        <!--  for MyBatis3/MyBatis3Simple
       自动为每一个生成的类创建一个构造方法,构造方法包含了所有的field;而不是使用setter;
        -->
        <property name="constructorBased" value="false"/>
        <!-- enableSubPackages:是否让schema作为包的后缀 -->
        <property name="enableSubPackages" value="false"/>
        <!-- 是否清理从数据库中查询出的字符串左右两边的空白字符 -->
        <property name="trimStrings" value="true"/>
        <!-- for MyBatis3 / MyBatis3Simple
        是否创建一个不可变的类,如果为true,
        那么MBG会创建一个没有setter方法的类,取而代之的是类似constructorBased的类
        -->
        <property name="immutable" value="false"/>
        <!-- 设置一个根对象,
            如果设置了这个根对象,那么生成的keyClass或者recordClass会继承这个类;在Table的rootClass属性中可以覆盖该选项
            注意:如果在key class或者record class中有root class相同的属性,MBG就不会重新生成这些属性了,包括:
               1,属性名相同,类型相同,有相同的getter/setter方法;
            -->
        <!--<property name="rootClass" value="com.trusause.app.domain.GenericEntity"/>-->
    </javaModelGenerator>

    <!--sql映射文件生成的位置-->
    <sqlMapGenerator targetPackage="mapping" targetProject="./src/main/resources">
        <property name="enableSubPackages" value="true"/>
    </sqlMapGenerator>

    <!-- 对于mybatis来说,即生成Mapper接口,注意,如果没有配置该元素,那么默认不会生成Mapper接口
    targetPackage/targetProject:同javaModelGenerator
    type:选择怎么生成mapper接口(在MyBatis3/MyBatis3Simple下):
        1,ANNOTATEDMAPPER:会生成使用Mapper接口+Annotation的方式创建(SQL生成在annotation中),不会生成对应的XML;
        2,MIXEDMAPPER:使用混合配置,会生成Mapper接口,并适当添加合适的Annotation,但是XML会生成在XML中;
        3,XMLMAPPER:会生成Mapper接口,接口完全依赖XML;
    注意,如果context是MyBatis3Simple:只支持ANNOTATEDMAPPER和XMLMAPPER
    -->
    <javaClientGenerator type="XMLMAPPER" targetPackage="com.trusause.app.mapper" targetProject="./src/main/java">
        <!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
        <property name="enableSubPackages" value="true"/>
        <!-- 可以为所有生成的接口添加一个父接口,但是MBG只负责生成,不负责检查
        <propertyname="rootInterface" value=""/>
         -->
    </javaClientGenerator>

    <!--table是指定每个表的生成策略-->
    <table tableName="t_test_course" domainObjectName="Course"
           enableCountByExample="false"
           enableUpdateByExample="false"
           enableDeleteByExample="false"
           enableSelectByExample="false"
           selectByExampleQueryId="false"></table>

</context>

三、生成逆向工程

方法一:直接使用maven插件自带的功能

方法二:自己配置maven插件

启动Edit Configuartions,在跳出界面中进行如下配置,-e更加方面我们阅读报错的原因

设置插件完毕之后,就可以启动插件了

四、生成相关逆向工程

运行之后,如果成功便会在指定位置(generatorConfig.xml中可以配置,具体看注释)生成响应的POJO类,dao接口,和mapper的.xml数据库文件.

五、生成的文件

POJO类

package com.trusause.app.domain;
import java.util.Date;
/**
• 通过mybatis逆向工程生成的文件。
 */public class Course {
 private Integer id;
private String code;

private String name;

private String createPerson;

private String createPersonName;

private Boolean deleteFlag;

private Date systemCreateTime;

private Date systemUpdateTime;

private String updatePerson;

private String updatePersonName;

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public String getCode() {
    return code;
}

public void setCode(String code) {
    this.code = code == null ? null : code.trim();
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name == null ? null : name.trim();
}

public String getCreatePerson() {
    return createPerson;
}

public void setCreatePerson(String createPerson) {
    this.createPerson = createPerson == null ? null : createPerson.trim();
}

public String getCreatePersonName() {
    return createPersonName;
}

public void setCreatePersonName(String createPersonName) {
    this.createPersonName = createPersonName == null ? null : createPersonName.trim();
}

public Boolean getDeleteFlag() {
    return deleteFlag;
}

public void setDeleteFlag(Boolean deleteFlag) {
    this.deleteFlag = deleteFlag;
}

public Date getSystemCreateTime() {
    return systemCreateTime;
}

public void setSystemCreateTime(Date systemCreateTime) {
    this.systemCreateTime = systemCreateTime;
}

public Date getSystemUpdateTime() {
    return systemUpdateTime;
}

public void setSystemUpdateTime(Date systemUpdateTime) {
    this.systemUpdateTime = systemUpdateTime;
}

public String getUpdatePerson() {
    return updatePerson;
}

public void setUpdatePerson(String updatePerson) {
    this.updatePerson = updatePerson == null ? null : updatePerson.trim();
}

public String getUpdatePersonName() {
    return updatePersonName;
}

public void setUpdatePersonName(String updatePersonName) {
    this.updatePersonName = updatePersonName == null ? null : updatePersonName.trim();
}

dao:

package com.trusause.app.mapper;
import com.trusause.app.domain.Course;
public interface CourseMapper {
 int deleteByPrimaryKey(Integer id);
int insert(Course record);

int insertSelective(Course record);

Course selectByPrimaryKey(Integer id);

int updateByPrimaryKeySelective(Course record);

int updateByPrimaryKey(Course record);

xxxMapper.xml:

<?xml version="1.0" encoding="UTF-8"?> id, code, name, create_person, create_person_name, delete_flag, system_create_time, system_update_time, update_person, update_person_name select from t_test_course where id = #{id,jdbcType=INTEGER} delete from t_test_course where id = #{id,jdbcType=INTEGER} insert into t_test_course (id, code, name, create_person, create_person_name, delete_flag, system_create_time, system_update_time, update_person, update_person_name) values (#{id,jdbcType=INTEGER}, #{code,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{createPerson,jdbcType=VARCHAR}, #{createPersonName,jdbcType=VARCHAR}, #{deleteFlag,jdbcType=BIT}, #{systemCreateTime,jdbcType=TIMESTAMP}, #{systemUpdateTime,jdbcType=TIMESTAMP}, #{updatePerson,jdbcType=VARCHAR}, #{updatePersonName,jdbcType=VARCHAR}) insert into t_test_course id, code, name, create_person, create_person_name, delete_flag, system_create_time, system_update_time, update_person, update_person_name, #{id,jdbcType=INTEGER}, #{code,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{createPerson,jdbcType=VARCHAR}, #{createPersonName,jdbcType=VARCHAR}, #{deleteFlag,jdbcType=BIT}, #{systemCreateTime,jdbcType=TIMESTAMP}, #{systemUpdateTime,jdbcType=TIMESTAMP}, #{updatePerson,jdbcType=VARCHAR}, #{updatePersonName,jdbcType=VARCHAR}, update t_test_course code = #{code,jdbcType=VARCHAR}, name = #{name,jdbcType=VARCHAR}, create_person = #{createPerson,jdbcType=VARCHAR}, create_person_name = #{createPersonName,jdbcType=VARCHAR}, delete_flag = #{deleteFlag,jdbcType=BIT}, system_create_time = #{systemCreateTime,jdbcType=TIMESTAMP}, system_update_time = #{systemUpdateTime,jdbcType=TIMESTAMP}, update_person = #{updatePerson,jdbcType=VARCHAR}, update_person_name = #{updatePersonName,jdbcType=VARCHAR}, where id = #{id,jdbcType=INTEGER} update t_test_course set code = #{code,jdbcType=VARCHAR}, name = #{name,jdbcType=VARCHAR}, create_person = #{createPerson,jdbcType=VARCHAR}, create_person_name = #{createPersonName,jdbcType=VARCHAR}, delete_flag = #{deleteFlag,jdbcType=BIT}, system_create_time = #{systemCreateTime,jdbcType=TIMESTAMP}, system_update_time = #{systemUpdateTime,jdbcType=TIMESTAMP}, update_person = #{updatePerson,jdbcType=VARCHAR}, update_person_name = #{updatePersonName,jdbcType=VARCHAR} where id = #{id,jdbcType=INTEGER}

} 当然如果你的电脑上许许多多的问题(日常)导致无法使用maven插件,可以在src/main/java文件夹下创建一个test类,写下如下代码: 注意new file("")中写下自己的逆向配置文件路径!

public class GeneratorTest {
 public static void main(String[] args)throws Exception {
 List warnings = new ArrayList();
 boolean overwrite = true;
 File configFile = new File("/Users/apple/Documents/Spring-Boot/src/main/resources/generatorConfig.xml");
 ConfigurationParser cp = new ConfigurationParser(warnings);
 Configuration config = cp.parseConfiguration(configFile);
 DefaultShellCallback callback = new DefaultShellCallback(overwrite);
 MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
 myBatisGenerator.generate(null);
 }