Mybatis学习笔记——selectByExample方法和selectByExampleWithBLOBs方法区别

在使用MyBatis的selectByExample方法时,发现长字段获取结果为null。文章详细解析了原因,涉及到BaseResultMap与ResultMapWithBLOBs的区别,以及如何正确配置以解决长字段问题。

使用 MyBatis,通常会使用 MyBatis Generator 插件逆向生成一套接口和.xml映射文件, 来简化数据库SQL操作。在使用 selectByExample(RecordExample example) 进行数据库的查找时,发现长字段(实践时为 description varchar(256))获取结果为 null 。而其他字段则正常,查看该方法对应的xml配置文件如下:

<select id="selectByExample" parameterType="cn.novalue.community.model.QuestionExample" resultMap="BaseResultMap">
    <!--
        WARNING - @mbg.generated
        This element is automatically generated by MyBatis Generator, do not modify.
        This element was generated on Sun Dec 01 15:04:56 CST 2019.
    -->
    select
    <if test="distinct">
        distinct
    </if>
    <include refid="Base_Column_List" />
    from QUESTION
    <if test="_parameter != null">
        <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null">
        order by ${orderByClause}
    </if>
</select>

可以看到 selectByExample 方法返回的是 BaseResultMap,查看 BaseResultMap,如下:

  <resultMap id="BaseResultMap" type="cn.novalue.community.model.Question">
    <!--
      WARNING - @mbg.generated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Sun Dec 01 15:04:56 CST 2019.
    -->
    <id column="ID" jdbcType="INTEGER" property="id" />
    <result column="TITLE" jdbcType="VARCHAR" property="title" />
    <result column="GMT_CREATE" jdbcType="BIGINT" property="gmtCreate" />
    <result column="GMT_MODIFIED" jdbcType="BIGINT" property="gmtModified" />
    <result column="CREATOR" jdbcType="INTEGER" property="creator" />
    <result column="COMMENT_COUNT" jdbcType="INTEGER" property="commentCount" />
    <result column="VIEW_COUNT" jdbcType="INTEGER" property="viewCount" />
    <result column="LIKE_COUNT" jdbcType="INTEGER" property="likeCount" />
    <result column="TAG" jdbcType="VARCHAR" property="tag" />
  </resultMap>

发现其中缺少 description 的映射,在浏览xml文件时,查看 selectByExampleWithBLOBs 对应的xml文件,如下:

<select id="selectByExampleWithBLOBs" parameterType="cn.novalue.community.model.QuestionExample" resultMap="ResultMapWithBLOBs">
    select
    <if test="distinct">
        distinct
    </if>
    <include refid="Base_Column_List" />
    ,
    <include refid="Blob_Column_List" />
    from QUESTION
    <if test="_parameter != null">
        <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null">
        order by ${orderByClause}
    </if>
</select>

这个方法返回的是的 ResultMapWithBLOBs,查看 ResultMapWithBLOBs 的定义:

  <resultMap id="ResultMapWithBLOBs" type="cn.novalue.community.model.Question" extends="BaseResultMap">
    <result column="param_data" property="paramData" jdbcType="LONGVARCHAR"/>
  </resultMap>

ResultMapWithBLOBs 继承自 BaseResultMap,不过它有额外的 paramData 属性,并且指定的jdbcType为 LONGVARCHAR 类型,jdbcType是 JDBC 所需要的。

总结:

  1. Mybatis 使用 ResultMapWithBLOBs 来接收有长字段的查询结果,所以如果数据库有长字段,要用 selectByExampleWithBLOBs 方法查询,没有长字段时,使用 selectByExample 方法即可。
  2. 如果不需要在使用 Mybatis Generator 逆向时针对长字段类型生成 ResultMapWithBLOBs,可以在配置文件中指明映射类型:
<table  tableName="question" domainObjectName="Question" >
    <columnOverride column="param_data" javaType="java.lang.String" jdbcType="VARCHAR" />
</table>
MyBatis 本身并没有提供默认的 `selectByExample` 方法,这是因为 MyBatis 作为一款轻量级的持久层框架,其设计理念是提供灵活的 SQL 映射能力,而不是强制提供某种固定的方法。在实际开发中,不同的业务场景对查询条件的要求差异较大,因此 MyBatis 更倾向于让开发者根据具体需求自定义查询逻辑。 在反向工程(如 MyBatis Generator)生成的代码中,`selectByExample` `selectByExampleWithBLOBs` 方法是通过动态 SQL 实现的,并且依赖 `Example` 类来构建查询条件。例如,`selectByExample` 方法通常用于查询非 BLOB 类型的字段,而 `selectByExampleWithBLOBs` 方法则用于包含 BLOB 类型字段的查询,其 `resultMap` 会继承 `BaseResultMap` 并额外包含 BLOB 字段的映射 [^3]。 此外,`selectByExample` 方法在实现模糊查询时也存在一定的局限性,因为它无法自动添加 `%` 等通配符来实现模糊匹配,开发者需要手动构造查询条件来满足需求 [^2]。 因此,MyBatis 没有默认提供 `selectByExample` 方法的原因可以总结为以下几点: 1. **灵活性优先**:MyBatis 的设计原则是提供灵活的 SQL 映射机制,而不是封装过多的业务逻辑。这样可以确保开发者能够根据具体需求编写高效的 SQL。 2. **动态查询需求多样**:不同业务场景下的查询条件差异较大,使用统一的 `selectByExample` 方法可能无法满足所有需求。 3. **BLOB 字段处理复杂**:对于包含大文本字段(如 `TEXT` 或 `BLOB` 类型)的查询,需要额外的 `resultMap` 配置,这进一步说明了为何不能简单地提供一个通用的 `selectByExample` 方法 [^3]。 综上所述,MyBatis 没有默认的 `selectByExample` 方法是为了保持框架的灵活性可扩展性,同时适应不同业务场景下的多样化查询需求。 ```xml <select id="selectByExampleWithBLOBs" parameterType="cn.novalue.community.model.QuestionExample" resultMap="ResultMapWithBLOBs"> select <if test="distinct"> distinct </if> <include refid="Base_Column_List" /> , <include refid="Blob_Column_List" /> from QUESTION <if test="_parameter != null"> <include refid="Example_Where_Clause" /> </if> <if test="orderByClause != null"> order by ${orderByClause} </if> </select> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值