MyBatis深入总结

        之前写过两篇关于MyBatis的文章,旨在探讨基于MyBatis开发时如何精简和加快后端的开发,分别是: MaBatis 的 Mapper 模板通用书写 分享 和 只是加个字段而已——如何解决程序员之痛 ,有兴趣有时间的不妨先看这两篇文章。

        两篇文章显得过于分散,并且存在某些地方描述得不够清楚的问题,所以本文主要是做一个更深入的总结和阐述,还有花点文字说一下写这些文章的意义——毕竟没有意义的东西做得再好也只能是0。

        首先要说就是写这些文字的用意,众所周知,MyBatis有很多好用的工具或插件,比如自动生成这些东西早已烂大街,我也使用过,虽然我对它们嗤之以鼻。甚至还有MyBatis Plus增强工具——这个工具是我发现的MyBatis体系中最好用的了,热衷于使用这些工具进行快速开发的朋友建议直接使用它,可以少走很多弯路。MyBatis Plus虽然很好用,甚至于它的设计其实打动了我了,但是我还是决定不去使用它,原因如下:

        一、我认为手写SQL能够锻炼一个人的能力,写多了,潜移默化中就得到了积累。而使用工具,虽然获得了眼前的甜头,却失去了更大的好处。

        二、MyBatis为自由而生。MyBatis Plus这些增强性工具,难道MyBatis官方开发不出来吗?它为什么不在框架中直接集成?私以为那不是MyBatis的初衷,它的初衷是让大家更好的管理数据层代码。这些工具跟MyBatis的初衷是背道而驰的。

        三、我发现了开发速度不亚于这些工具的开发方式,直接基于MyBatis,兼具手写SQL的自由与速度,只要你学会了它,不仅不再被速度拖累,而且能够大大锻炼你的能力。这个方式唯一的缺点就是:它不是一个让你随手拿来就能用的东西,它更像是一种思想,你需要理解它,然后才能掌握它。我坚信的是:“技术就是思想,思想就是技术”,如果你也是这样的人,那么请往下看,否则,便不必浪费时间往下看了。

        再来说说那些工具做的是什么事?帮助你快速解决单表操作的问题。也就是一些简单的crud的事情,其他的还是需要自己动手——那么不使用那些工具能不能解决crud问题呢?当然可以。

        之所以需要解决这个问题,很大程度上是因为需求经常变动,增加字段无可避免,而使用实体映射库表字段的方式,添加一个字段需要更改实体、库表、resultMap映射和具体SQL等,这里面最大的问题就是——大家都习惯了使用实体来映射库表字段,MyBatis官方也提倡这样的做法。

        思考一个问题如果无法解决,那么很有可能那个问题本身就是不存在的,于是我往前一步思考,去掉实体后会是什么样的?——直到这时候我才打开了新世界的大门,一个实体里的成员变量和setter、getter完全没有必要存在。那么使用什么来承装数据呢?Map或JSON。

        于是我的Mapper.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.xxx.mapper.Mapper">
    <sql id="table_name">
        serviceStatistics
    </sql>


    <sql id="column">
        id, `type`, `count`, createTime
    </sql>
    <sql id="values">
        #{id}, #{type}, #{count}, #{createTime}
    </sql>

    <sql id="set_values">
        id=#{id}, `type`=#{type}, `count`=#{count}, createTime=#{createTime}
    </sql>

    <sql id="condition">
        <if test="id != null and id != ''">
            AND id = #{id}
        </if>
        <if test="type != null and type != ''">
            AND `type` = #{type}
        </if>
        <if test="from != null and from != '' and to != null and to != ''">
            AND createTime BETWEEN #{from} AND #{to}
        </if>
    </sql>

    <insert id="add">
        INSERT INTO <include refid="table_name"/>
        (
        <include refid="column"/>
        )VALUES(
        <include refid="values"/>
        )
    </insert>

    <select id="query" resultType="Map">
        SELECT `count`
        FROM <include refid="table_name"/>
        WHERE 1=1 <include refid="condition"/>
    </select>

</mapper>

        对应的Mapper接口则是这样的:

public interface Mapper {

    int add(Map<String, Object> entityMap);

    List<Map<String, Object>> query(Map<String, Object> parameter);

}

        这里面的代码作了很大的删减,但是足以具备代表性。

        首先注意到在Mapper接口中的add方法中,直接使用Map传递参数,可以把它看作一个适配所有实体的“抽象实体”,但其实就是一个简单的Map而已,我什么都没做。接着,查询方法的参数是Map,返回的参数是一个Map的List。

        然后,重点在于xml文件中的设计:使用<sql></sql>标签自定义一些重复性高的代码:表名、新增修改的设值字段和查询条件。

        为了达到简化的目标,我去掉了jdbcType这个属性,去掉的理由是:它仅仅是定义了空值时MyBatis如何提供默认值而已。比如说,int类型和date类型的默认值是不一样的。也许有的人认为这个属性非常重要,但我依然决定去掉,因为只要开发者在代码中做了正确的空值处理就不会有问题,而且我有一个疑惑:空真的重要吗?空的东西我不想处理它,如果空值导致了错误,我觉得代码已经存在问题了,最好的处理方式是:如果空值:返回错误给调用方,必须传值,如果是非必传的值,那么应该设值默认值,如果默认值也没有,那么数据库应该放开检验,不要让sql出现错误。

        常用的curd,每次只需要复制粘贴这个模板的代码(有缺少,自行补充即可)就over了,那些字段全部都是数据库里的字段,自行更改即可。以后产品姐姐跑过来跟你说要加字段的话,你再也不会像以前那样惊慌失措了(脑海里冒出所有需要添加的地方),只需要淡定地说:OK!我这就加上去!

        这个方式比MyBatis的代码生成工具好用得多,需要添加字段时,重复生成一遍可能行不通,因为你已经在里面加过其他的代码了,不能直接覆盖。

        同时,这种方式比MyBatis Plus要慢一点点,因为它直接用注解来映射,crud封装起来了,不需要手写这部分的代码,加字段时只需要在实体中加上即可。我们这里需要加以下三个地方:

    <sql id="column">
        id, `type`, `count`, createTime
    </sql>
    <sql id="values">
        #{id}, #{type}, #{count}, #{createTime}
    </sql>

    <sql id="set_values">
        id=#{id}, `type`=#{type}, `count`=#{count}, createTime=#{createTime}
    </sql>

        而在crud以外的sql中,我们跟MyBatis Plus相同,同时也跟JFinal的相同,但是——需要再次强调一次但是:我们是完全的手写SQL,便于维护。同时这种方式更加简洁明了,便于理解。

        所以,这么做的意义还有最后的这一点:我觉得有更好的或者相近的解决方案的话,尽量不使用工具,这不仅是锻炼自己的问题,而且还是项目管理的问题——使用的插件越多,未知的问题就越多。老子说,大道至简。好用的东西不一定好用,好用的思想一定好用。

        以上为此次总结,在这方面的探讨也告一段落了,希望能够帮助到志同道合的朋友。

转载于:https://my.oschina.net/watsonos/blog/1618304

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值