Mybatis中不建议使用动态sql

Mybatis是一个优秀的Java持久层框架,它通过xml的方式来管理要执行的sql语句,屏蔽了jdbc底层细节,让开发人员可以方便的操作数据库。

Mybatis中不建议使用动态sql

动态SQL

说到动态SQL,绝对是Mybatis引以为豪的东西,因为它可以使配置文件简洁,就像下面这个配置,我可以使用selectEntryByWhere来适配所有的查询语句,是不是感觉很爽

<select id="selectEntryByWhere" parameterType="Order" resultType="Order">
SELECT
<include refid="Base_Column"/>
FROM order
<include refid="Where_Clause"/>
</select>
<sql id="Where_Clause">
<where>
<if test="orderId != null">AND order_id = #{orderId}</if>
<if test="userId != null">AND user_id = #{userId}</if>
<if test="type != null">AND type = #{type}</if>
<if test="types != null">
AND type in
<foreach collection="types" item="type" open="(" separator="," close=")">
#{type}
</foreach>
</if>
<if test="startTime != null"><![CDATA[AND created >= #{startTime}]]></if>
<if test="endTime != null"><![CDATA[AND created <= #{endTime}]]></if>
</where>
</sql>

不建议使用动态SQL

这里说下我的原因,为什么不建议使用动态SQL?

(1)使用动态SQL存在内存溢出隐患。线上遇到过真实案例,就因为某个字段为null查询全表,导致OOM。写代码时很爽,一旦出了线上问题,排查起来就非常麻烦了,当时使用jmap dump出堆内存信息,慢慢才分析出来。

(2)代码可读性非常差。试想一下,如果你接手一个不熟悉的项目,一般情况下,我们都会从数据库底层开始,逐渐了解整个业务的逻辑。但是你一看到这个动态SQL,尤其是几十个查询SQL都走到这里,估计你会崩溃,因为你不知道参数是怎么传递的,所有的查询语句都走到这来了。

我的建议

强烈建议不要使用动态SQL拼接,DAO层的每个查询方法,在Mybatis的xml配置文件中都应该有对应的配置。比如我要根据订单ID查询,应该这么写而不是直接通过selectEntryByWhere方法查询。

<select id="getByOrderId" parameterType="Long" resultType="Order">
SELECT
<include refid="Base_Column"/>
FROM order
where order_id = #{orderId}
</select>

您可能还会对下面的文章感兴趣: