且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

SpringBoot中Mybatis反向生成Java代码

更新时间:2022-06-07 03:09:38

在上节课中我们介绍了在SpringBoot中如何集成Mybatis,当完成集成工作之后,便可进行正常的使用。

如果数据库表结构以及创建完成,手动去写对应的mapper接口和mapper xml配置以及实体类等会显得非常麻烦。那么此时,如果能够通过插件完成数据库表结构到代码的生成,那将是一件非常爽的事。

本篇文章就为大家介绍这么一款插件。

插件集成

关于Spring Boot集成Mybatis的部分,我们就不再这里赘述了,直接进入插件集成部分。

默认情况下,在pom.xml中默认的构建插件配置如下:









<build>    <plugins>        <plugin>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-maven-plugin</artifactId>        </plugin>    </plugins></build>

我们要使用的插件便是基于build中的插件进行配置,配置之后,对应build中的代码如下:



























<build>    <plugins>        <plugin>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-maven-plugin</artifactId>        </plugin>        <!-- mybatis generator 自动生成代码插件 -->        <plugin>            <groupId>org.mybatis.generator</groupId>            <artifactId>mybatis-generator-maven-plugin</artifactId>            <version>1.4.0</version>            <configuration>                <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>                <overwrite>true</overwrite>                <verbose>true</verbose>            </configuration>            <dependencies>                <dependency>                    <groupId>mysql</groupId>                    <artifactId>mysql-connector-java</artifactId>                    <version>8.0.18</version>                </dependency>            </dependencies>        </plugin>    </plugins></build>

这里我们新增了mybatis-generator-maven-plugin插件。插件因为要连接数据库,所以依赖了数据库的jar包mysql-connector-java。

在插件的configuration节点中指定了反向生成的相关配置。overwrite节点指定如果生成的代码已经存在,则进行覆盖。

反向生成配置

下面来看看在插件Configuration中配置的generatorConfig.xml。很明显,该文件放在了resource目录下,当然你也可以放在其他地方。

该文件的内容如下:




































<?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>
    <context id="MySql" targetRuntime="MyBatis3">
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
        <!--数据库连接配置-->        <jdbcConnection                driverClass="com.mysql.jdbc.Driver"                connectionURL="jdbc:mysql://localhost:3306/spring"                userId="root"                password="root" />
        <!--指定自动生成的POJO位置-->        <javaModelGenerator targetPackage="com.secbro.model" targetProject="src/main/java"></javaModelGenerator>
        <!--指定自动生成的mapper.xml位置-->        <sqlMapGenerator targetPackage="mappers"  targetProject="src/main/resources"></sqlMapGenerator>
        <!--指定自动生成的Mapper接口位置-->        <javaClientGenerator targetPackage="com.secbro.mapper" targetProject="src/main/java" type="XMLMAPPER"></javaClientGenerator>
        <!--要生成的表名称-->        <table tableName="tb_order" domainObjectName="Order">            <generatedKey column="id" sqlStatement="MySql" identity="true"></generatedKey>        </table>
    </context>
</generatorConfiguration>

在该配置文件中,通过context的targetRuntime指定了生成mybatis的标准,这里为MyBatis3。生成的相应代码会提供Mapper接口、实体类、用于编程方式传参的XXXExample以及Mapper对应的xml文件。

在jdbcConnection中指定了数据库配置的基本信息。

javaModelGenerator节点指定自动生成的POJO位置,这里是在src/main/java下面的com.secbro.model包中。

sqlMapGenerator节点指定自动生成的mapper.xml位置,这里放在了src/main/resources目录下的mappers文件夹下。

javaClientGenerator节点指定自动生成的Mapper接口位置,这里放在了src/main/java下的com.secbro.mapper包下。

最后table节点,指定要反向生成的表的信息与实体类信息直接的对应关系。这里以tb_order为例。其中还配置了id的生成策略。另外此处还可配置相关操作的example是否使用。

反向生成

完成上述配置之后,打开idea的maven管理窗口,找到plugins下面的mybatis-generator插件。SpringBoot中Mybatis反向生成Java代码双击generate,便会在对应的目录下生成对应类和文件。

生成文件展示

Order实体类:










package com.secbro.model;
import java.io.Serializable;
public class Order implements Serializable {    private Integer id;    private String orderNo;   // 省略其他代码}

OrderExample类:


























































package com.secbro.model;
import java.util.ArrayList;import java.util.List;
public class OrderExample {      protected String orderByClause;
    protected boolean distinct;
    protected List<Criteria> oredCriteria;
    public OrderExample() {        oredCriteria = new ArrayList<>();    }
    public void setOrderByClause(String orderByClause) {        this.orderByClause = orderByClause;    }
    public String getOrderByClause() {        return orderByClause;    }
    public void setDistinct(boolean distinct) {        this.distinct = distinct;    }
    public boolean isDistinct() {        return distinct;    }
    public List<Criteria> getOredCriteria() {        return oredCriteria;    }
    public void or(Criteria criteria) {        oredCriteria.add(criteria);    }
    public Criteria or() {        Criteria criteria = createCriteriaInternal();        oredCriteria.add(criteria);        return criteria;    }
    public Criteria createCriteria() {        Criteria criteria = createCriteriaInternal();        if (oredCriteria.size() == 0) {            oredCriteria.add(criteria);        }        return criteria;    }
  // 省略其他代码}

OrderMapper类:
































package com.secbro.mapper;
import com.secbro.model.Order;import com.secbro.model.OrderExample;import java.util.List;import org.apache.ibatis.annotations.Param;
public interface OrderMapper {
    long countByExample(OrderExample example);
    int deleteByExample(OrderExample example);
    int deleteByPrimaryKey(Integer id);
    int insert(Order record);
    int insertSelective(Order record);
    List<Order> selectByExample(OrderExample example);
    Order selectByPrimaryKey(Integer id);
    int updateByExampleSelective(@Param("record") Order record, @Param("example") OrderExample example);
    int updateByExample(@Param("record") Order record, @Param("example") OrderExample example);
    int updateByPrimaryKeySelective(Order record);
    int updateByPrimaryKey(Order record);}

OrderMapper.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.secbro.mapper.OrderMapper">  <resultMap id="BaseResultMap" type="com.secbro.model.Order">    <id column="id" jdbcType="INTEGER" property="id" />    <result column="order_no" jdbcType="VARCHAR" property="orderNo" />    <result column="amount" jdbcType="INTEGER" property="amount" />  </resultMap>  <sql id="Example_Where_Clause">    <where>      <foreach collection="oredCriteria" item="criteria" separator="or">        <if test="criteria.valid">          <trim prefix="(" prefixOverrides="and" suffix=")">            <foreach collection="criteria.criteria" item="criterion">              <choose>                <when test="criterion.noValue">                  and ${criterion.condition}                </when>                <when test="criterion.singleValue">                  and ${criterion.condition} #{criterion.value}                </when>                <when test="criterion.betweenValue">                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}                </when>                <when test="criterion.listValue">                  and ${criterion.condition}                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">                    #{listItem}                  </foreach>                </when>              </choose>            </foreach>          </trim>        </if>      </foreach>    </where>  </sql>  <sql id="Update_By_Example_Where_Clause">    <where>      <foreach collection="example.oredCriteria" item="criteria" separator="or">        <if test="criteria.valid">          <trim prefix="(" prefixOverrides="and" suffix=")">            <foreach collection="criteria.criteria" item="criterion">              <choose>                <when test="criterion.noValue">                  and ${criterion.condition}                </when>                <when test="criterion.singleValue">                  and ${criterion.condition} #{criterion.value}                </when>                <when test="criterion.betweenValue">                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}                </when>                <when test="criterion.listValue">                  and ${criterion.condition}                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">                    #{listItem}                  </foreach>                </when>              </choose>            </foreach>          </trim>        </if>      </foreach>    </where>  </sql>  <sql id="Base_Column_List">    id, order_no, amount  </sql>  <select id="selectByExample" parameterType="com.secbro.model.OrderExample" resultMap="BaseResultMap">    select    <if test="distinct">      distinct    </if>    <include refid="Base_Column_List" />    from tb_order    <if test="_parameter != null">      <include refid="Example_Where_Clause" />    </if>    <if test="orderByClause != null">      order by ${orderByClause}    </if>  </select>  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">    select     <include refid="Base_Column_List" />    from tb_order    where id = #{id,jdbcType=INTEGER}  </select>  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">    delete from tb_order    where id = #{id,jdbcType=INTEGER}  </delete>  <delete id="deleteByExample" parameterType="com.secbro.model.OrderExample">    delete from tb_order    <if test="_parameter != null">      <include refid="Example_Where_Clause" />    </if>  </delete>  <insert id="insert" parameterType="com.secbro.model.Order">    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">      SELECT LAST_INSERT_ID()    </selectKey>    insert into tb_order (order_no, amount)    values (#{orderNo,jdbcType=VARCHAR}, #{amount,jdbcType=INTEGER})  </insert>  <insert id="insertSelective" parameterType="com.secbro.model.Order">    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">      SELECT LAST_INSERT_ID()    </selectKey>    insert into tb_order    <trim prefix="(" suffix=")" suffixOverrides=",">      <if test="orderNo != null">        order_no,      </if>      <if test="amount != null">        amount,      </if>    </trim>    <trim prefix="values (" suffix=")" suffixOverrides=",">      <if test="orderNo != null">        #{orderNo,jdbcType=VARCHAR},      </if>      <if test="amount != null">        #{amount,jdbcType=INTEGER},      </if>    </trim>  </insert>  <select id="countByExample" parameterType="com.secbro.model.OrderExample" resultType="java.lang.Long">    select count(*) from tb_order    <if test="_parameter != null">      <include refid="Example_Where_Clause" />    </if>  </select>  <update id="updateByExampleSelective" parameterType="map">    update tb_order    <set>      <if test="record.id != null">        id = #{record.id,jdbcType=INTEGER},      </if>      <if test="record.orderNo != null">        order_no = #{record.orderNo,jdbcType=VARCHAR},      </if>      <if test="record.amount != null">        amount = #{record.amount,jdbcType=INTEGER},      </if>    </set>    <if test="_parameter != null">      <include refid="Update_By_Example_Where_Clause" />    </if>  </update>  <update id="updateByExample" parameterType="map">    update tb_order    set id = #{record.id,jdbcType=INTEGER},      order_no = #{record.orderNo,jdbcType=VARCHAR},      amount = #{record.amount,jdbcType=INTEGER}    <if test="_parameter != null">      <include refid="Update_By_Example_Where_Clause" />    </if>  </update>  <update id="updateByPrimaryKeySelective" parameterType="com.secbro.model.Order">    update tb_order    <set>      <if test="orderNo != null">        order_no = #{orderNo,jdbcType=VARCHAR},      </if>      <if test="amount != null">        amount = #{amount,jdbcType=INTEGER},      </if>    </set>    where id = #{id,jdbcType=INTEGER}  </update>  <update id="updateByPrimaryKey" parameterType="com.secbro.model.Order">    update tb_order    set order_no = #{orderNo,jdbcType=VARCHAR},      amount = #{amount,jdbcType=INTEGER}    where id = #{id,jdbcType=INTEGER}  </update></mapper>

如何使用

由于在启动类上已经指定了@MapperScan("com.secbro.mapper"),同时上节课也完成了mybatis的集成。这里就可直接使用OrderMapper接口进行操作。

示例如下:


















@Service("orderService")public class OrderServiceImpl implements OrderService {
  @Resource  private OrderMapper orderMapper;
  @Override  public Order findByOrderNo(String orderNo){    OrderExample example = new OrderExample();    example.createCriteria().andOrderNoEqualTo(orderNo);    List<Order> list =  orderMapper.selectByExample(example);    if(list.isEmpty()){      return null;    }    return list.get(0);  }}

小结

经过上述步骤,只要创建好了数据库表结构,那么便可以快速的根据表结构生成代码。然后只用关系核心业务逻辑即可。是不是方便快捷多了?赶紧用起来吧。

如果你觉得有很多无用类,比如OrderExample,你也可以在插件中进行配置,生成你喜欢的形式。关于其他形式,大家自行研究一下。