大数跨境
0
0

Mybatis代码生成器接口的继承实现

Mybatis代码生成器接口的继承实现 外贸队长JOJO
2025-10-24
8
导读:MyBatis-Generator 帮我们自动生成了基础的增删改查SQL,这解决了大部分简单操作
       MyBatis-Generator 帮我们自动生成了基础的增删改查SQL,这解决了大部分简单操作。但对于复杂的查询(比如多条件动态查询、多表关联),它就无法满足了。这时,我们如何在自动生成的 Mapper.xml 文件基础上,安全、高效地添加我们自定义的SQL,而不与自动生成的代码冲突?下面是我总结的方法。
1.修改generatorConfig.xml配置文件
        在文件生成表的地方加一行,这样生成的mapper接口可以继承指定的拓展类。
<!-- 指定生成的基础Mapper接口要继承的父接口 -->            <property name="rootInterface" value="com.sf.lams.portal.core.mapper.GoodMapperExt"/>
       <table tableName="good"               domainObjectName="Good"               enableCountByExample="false" enableUpdateByExample="false"               enableDeleteByExample="false" enableSelectByExample="false"               selectByExampleQueryId="false">            <!-- 指定生成的基础Mapper接口要继承的父接口 -->            <property name="rootInterface"            value="com.sf.lams.portal.core.mapper.GoodMapperExt"/>        </table>
总体配置如下:
<?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="application.properties"/>    <context id="MallTables" targetRuntime="MyBatis3">        <!-- 配置属性 -->        <property name="javaFileEncoding" value="UTF-8"/>        <property name="beginningDelimiter" value="`"/>        <property name="endingDelimiter" value="`"/>        <!--可以自定义生成model的代码注释-->        <commentGenerator>            <!-- 是否去除自动生成的注释 true:是 :false:否 -->            <property name="suppressAllComments" value="true"/>            <property name="suppressDate" value="true"/>            <property name="addRemarkComments" value="true"/>        </commentGenerator>
        <!-- 数据库连接,直接通过${}读取application.properties里的配置 -->        <jdbcConnection                driverClass="${spring.datasource.driver-class-name}"                connectionURL="${spring.datasource.url}"                userId="${spring.datasource.username}"                password="${spring.datasource.password}"/>
        <!-- Java类型解析 -->        <javaTypeResolver>            <property name="forceBigDecimals" value="false"/>            <property name="useJSR310Types" value="true"/>        </javaTypeResolver>
        <!-- 实体类生成配置 -->        <javaModelGenerator                targetPackage="com.sf.lams.olcp.dao.domain"                targetProject="src/main/java">            <property name="enableSubPackages" value="true"/>            <property name="trimStrings" value="true"/>        </javaModelGenerator>
        <!-- XML映射文件生成配置 -->        <sqlMapGenerator                targetPackage="mapper"                targetProject="src/main/resources">            <property name="enableSubPackages" value="true"/>        </sqlMapGenerator>
        <!-- Mapper接口生成配置 -->        <javaClientGenerator                type="XMLMAPPER"                targetPackage="com.sf.lams.olcp.dao.mapper"                targetProject="src/main/java">            <property name="enableSubPackages" value="true"/>        </javaClientGenerator>
        <!--生成对应表及类名,domainObjectName是设置实体类的名字的-->        <!--           tableName:数据库表名           domainObjectName:实体类名           enableCountByExample(默认true):MyBatis3Simple为false,               指定是否生成动态查询总条数语句(用于分页的总条数查询);           enableUpdateByExample:(默认true):MyBatis3Simple为false,               指定是否生成动态修改语句(只修改对象中不为空的属性);           enableDeleteByExample:enableDeleteByExample(默认true):               MyBatis3Simple为false,指定是否生成动态删除语句;           enableSelectByExample:enableSelectByExample(默认true):               MyBatis3Simple为false,指定是否生成动态查询语句;           selectByExampleQueryId:           enableInsert(默认true):指定是否生成insert语句;           enableSelectByPrimaryKey(默认true):指定是否生成按照主键查询对象的语句(就是getById或get);           enableUpdateByPrimaryKey(默认true):指定是否生成按照主键修改对象的语句(即update);           enableDeleteByPrimaryKey(默认true):指定是否生成按照主键删除对象的语句(即delete);           modelType:参考context元素的defaultModelType,相当于覆盖;       -->        <table tableName="good"               domainObjectName="Good"               enableCountByExample="false"               enableUpdateByExample="false"               enableDeleteByExample="false"               enableSelectByExample="false"               selectByExampleQueryId="false">            <!-- 指定生成的基础Mapper接口要继承的父接口 -->            <property name="rootInterface" value="com.sf.lams.olcp.dao.mapper.GoodMapperExt"/>
        </table>    </context></generatorConfiguration>

2.新增GoodMapperExt接口

        这个接口是我们拓展的接口,需要手动创建。

public interface GoodMapperExt {    Good selectByPrimaryKey (Integer id);}
3.点击运行代码生成器插件
 3.1生成的Good类
public class Good {    private Integer id;
    private String name;
    private Date createdTime;
    private Date updatedTime;
    public Integer getId() {        return id;    }
    public void setId(Integer id) {        this.id = id;    }
    public String getName() {        return name;    }
    public void setName(String name) {        this.name = name == null ? null : name.trim();    }
    public Date getCreatedTime() {        return createdTime;    }
    public void setCreatedTime(Date createdTime) {        this.createdTime = createdTime;    }
    public Date getUpdatedTime() {        return updatedTime;    }
    public void setUpdatedTime(Date updatedTime) {        this.updatedTime = updatedTime;    }}
3.2生成的GoodMapper接口
public interface GoodMapper extends GoodMapperExt {    int insert(Good record);
    int insertSelective(Good record);}
  3.3生成的GoodMapper.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.sf.lams.olcp.dao.mapper.GoodMapper">  <resultMap id="BaseResultMap" type="com.sf.lams.olcp.dao.domain.Good">    <result column="id" jdbcType="INTEGER" property="id" />    <result column="name" jdbcType="VARCHAR" property="name" />    <result column="created_time" jdbcType="TIMESTAMP" property="createdTime" />    <result column="updated_time" jdbcType="TIMESTAMP" property="updatedTime" />  </resultMap>  <insert id="insert" parameterType="com.sf.lams.olcp.dao.domain.Good">    insert into good (id, name, created_time,       updated_time)    values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{createdTime,jdbcType=TIMESTAMP},       #{updatedTime,jdbcType=TIMESTAMP})  </insert>  <insert id="insertSelective" parameterType="com.sf.lams.olcp.dao.domain.Good">    insert into good    <trim prefix="(" suffix=")" suffixOverrides=",">      <if test="id != null">        id,      </if>      <if test="name != null">        name,      </if>      <if test="createdTime != null">        created_time,      </if>      <if test="updatedTime != null">        updated_time,      </if>    </trim>    <trim prefix="values (" suffix=")" suffixOverrides=",">      <if test="id != null">        #{id,jdbcType=INTEGER},      </if>      <if test="name != null">        #{name,jdbcType=VARCHAR},      </if>      <if test="createdTime != null">        #{createdTime,jdbcType=TIMESTAMP},      </if>      <if test="updatedTime != null">        #{updatedTime,jdbcType=TIMESTAMP},      </if>    </trim>  </insert></mapper>
4.自定义GoodMapperExt.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.sf.lams.olcp.dao.mapper.GoodMapper">
   <select id="selectByPrimaryKey" resultMap="BaseResultMap">       select * from good where id=#{id}  </select>
</mapper>
        需注意的是,GoodMapperExt.xml文件里面的namespace必须和GoodMapper接口的包名一致。但方法id  必须和GoodMapperExt.java里面的方法一致。这样方法的resultMap才可以使用BaseResultMap,这个是在(GoodMapper.xml文件里面定义的)。
5.测试
         创建测试类进行测试。
@SpringBootTestclass GoodMapperTest {    @Resource    private GoodMapper goodMapper;
    @Test    void insert() {        Good good = new Good();        good.setName("good");        int result = goodMapper.insert(good);        // 验证插入操作是否成功        assertEquals(1, result);       /* // 验证ID是否被正确设置        assertNotNull(good.getId());        System.out.println(good.getId());*/    }
    @Test    void selectByPrimaryKey() {        // 使用刚插入的数据ID进行查询        Good good = goodMapper.selectByPrimaryKey(1);        assertNotNull(good);        assertEquals("good", good.getName());        System.out.println(good);    }
}
      通过注入GoodMapper接口,便可以使用GoodMapperExt接口里面的方法。每次生成的代码也只会覆盖GoodMapper接口,对于拓展的接口GoodMapperExt不用改。
        我们只需要把复杂业务逻辑写在GoodMapperExt接口里,同时它又具备了GoodMapper接口生成的基本功能,当表的字段变化的时候,只需重新生成覆盖原先自动生成的文件,而拓展的功能部分不需要变动。

【声明】内容源于网络
0
0
外贸队长JOJO
跨境分享地 | 每日分享实用知识
内容 45795
粉丝 2
外贸队长JOJO 跨境分享地 | 每日分享实用知识
总阅读248.4k
粉丝2
内容45.8k