Mybatis在工程中的槽点

工程中的mapper文件往往非常大,动则上千行,最近经常听见周围的同学们吐槽难以维护,还不如写Java代码。

最近就在思考这样一个问题,既然mapper文件太那蛋疼,为什么大家还是使用mapper文件呢,为什么不使用mybatis的注解或者使用spring-jdbc提供的JdbcTemplate(有使用JPA的)

结合自己的思考和一些实验,觉得有以下原因:

  • 有些同学被一些视频洗脑了,认为xml比java代码更好维护
  • Java中写sql实在不是一个好的sql编写方式,用java写出来的sql确实比xml中的sql更难看懂
  • 虽然mybatis提供了注解的方式,但是sql还是非常难以编写
  • ResultMap还是得用xml,否则就得重复的写多次@Results

总结起来其实就一个原因:Java的语法对长一点的字符串太不友好了,很难编写出可读性好的SQL,所以大家还是更愿意写xml来表示sql的对象的映射

不使用xml的方式

如何做到不使用xml呢?其实是有多种选择的,比如mybatis for scala,但是scala语法不熟悉,学习成本太大,实际上如果Java对string有比较好的支持,那写sql会容易得多

虽然Java对String的支持不够友好,但是groovy或者kotlin对string有非常好的支持,可以尝试用groovy或者kotlin加上mybatis的注解来写映射接口,比如kotlin:

58eb331e2ac6d9f4d35458bcbf247cb9.png

因为Java是可以和groovy或者kotlin在同一工程中混合使用的,因此使用kotlin或者groovy的方式在Java中是能正常被调用的,有了这种语法糖层面的支持,在代码中写SQL变得容易很多

解决重复SQL的问题

使用注解后,如果需要写多个查询,查询字段需要写多次,例如(本例中省略了ResultMap的使用):

5e9c27cfaf767ff0732e5c672e021741.png

这里的select之后的字段名,在多个不同的查询之中都是相同的,如何解决这个问题呢?我们可以使用mybatis插件处理,最后的效果如下:

b395834fce50c0a4225b9402ac491161.png

关键在于处理这个@Macro注解,

注解定义如下:

5938dc57f7378c8d36b487f1396f00bd.png

插件中需要处理sql,对sql做文本替换,这样我们就能够得到通过注解支持的可利用的sql片断,插件实现如下:

ba00801b2e9c3988cba89a988eddea03.png

对ResultMap的处理

在前面的例子中,映射接口中省略了@Results,加上@Results后完整的注解使用方式应该如下:

b89542486d7996d5f12e6303d9e17c58.png

可以看到,需要在每个查询方法上都加上@Results,如果多个方法上的@Result一模一样,那么重复的注解会被定义多次。

同样,我们可以通过实现mybatis插件方式支持默认的ResultMap,最终效果如下:

b089441131ab2b0168f2713c183e0e36.png

如果数据库中的字段名与Java中的属性名是标准的下划线与驼峰格式,比如数据库中的create_time对应于java中的createTime,那么可以不写@DefaultResults的results属性,例如:

1979c9bd97a711346421376c3b57ffff.png

整体代码简洁很多,使用多行字符串语法后如下:

72e11f10b56fa9de68873f4874a29b69.png

未完待续

今天太晚了,后面再继续讲述如何简化动态sql在mapper接口中的编写

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐