mybatis开发,你用 xml 还是注解?我 pick ... (1)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: mybatis开发,你用 xml 还是注解?我 pick ... (1)

最近在看公司项目时发现有的项目mybatis是基于注解开发的,而我个人的习惯是基于xml文件开发。


对于mybatis注解开发的原理理解不够,于是翻阅了部分源码,写下此文。主要介绍了mybatis开发的两种形式、三种写法。还有一点瞎思考,介绍了一处骚代码、还有一个坑。


原创不易,感谢阅读,感谢关注,感谢点赞,感谢转发。


荒腔走板


大家好,我是 why 。老规矩,在技术分享开始之前,先荒腔走板,聊点别的。


上周我写的这篇文章《我告诉你这书的第 3 版到底值不值得买?》居然被《深入理解Java虚拟机》的作者周志明先生看到了,还给我赞赏并留言给我说:作者表示感谢,真心的。


说实话,我看到这个赞赏的时候我都震惊了。有一种和大神产生了交集的感觉。


其实上周这篇文章是出版社找到我说送我一本第三版,让我看看,然后写个观后感就行。

恰好,在他们没有找到我之前我也是有这样的打算的。


我不是为了白嫖出版社几本书,而是我早在去年年底打算买第三版后,这篇文章就一直在着手准备了。


在机缘巧合之下,即完成了自己的计划,又获得了出版社的几本书,通过出版社,又勾搭上了本书作者,不仅获得了作者的赞赏还得到一本签名版。


哎,这疯狂而又操蛋的人生呀。


所以你问我写了这么久的文章收获了什么?


说实在的,我没有通过写文章挣到几个钱。但是我收获的是与一群志同道合的原创作者同行的机会、是读者读完文章后对我的文章的指点与赞扬、是偶尔与几位业界大佬之间互动的惊喜。


仅此而已。


好了,说回文章。


两种形式,三种写法


最近在看公司的一些项目的时候发现有的项目里面的 mybatis 是基于注解开发的。而我个人的习惯是基于 xml 文件开发。


所以对于基于注解开发的原理不太了解,于是去翻看了一下相关源码,形成此文。

本文主要介绍基于 mybatis 开发的两种形式,三种写法。


其中两种形式是指:


1.基于 xml 文件。


2.基于注解开发。


三种写法是指除了 xml 的形式外,注解又有两种不同的写法,它们的实现原理也略有不同,拿 Select 语句举例,就有两种注解 @Select、@SelectProvider 。


演示示例


先上一个演示示例给大家直观的感受一下:


首先,我们有个用户表,包含这些字段和这样一条数据:


然后我们搞个接口类,用三种方式去查询用户的年龄,具体如下:


xmlQueryAgeByName 方法是使用 xml 的方法去查询用户年龄,对应的 xml 如下:


annotationQueryAgeByName 方法是使用 @Select 注解去查询用户的年龄,SQL 就写在注解里面:


classQueryAgeByName 方法是使用 @SelectProvider 注解去查询用户的年龄,可以看到注解里面有个 type 字段,对应一个 class 类。一个 method 字段,对应 class 类中的一个方法:


其中 UserInfoSql 类如下:


然后,再来一个测试用例,把三个方法都测试一下:


最后的输出结果如下:


xmlQueryAgeByName whyAge = 18
annotationQueryAgeByName whyAge = 18
classQueryAgeByName whyAge = 18


测试用例就演示完成了,是一个极简的用例。


我就是基于这个案例去分析源码的,在分析之前,其实有点经验的老哥也能看出来了,我们先撇开常规的 xml 文件的形式不谈。


基于 @Select 注解的接口, SQL 就在注解里面,所以我们只需要通过反射取出注解里面的 SQL 进行分析就行了。


基于 @SelectProvider 注解的接口,SQL 虽然在一个类的方法中,但是注解上都告诉你是哪个类的哪个方法了,所以,一定是基于反射去取出方法里面的 SQL 的。


接下来,我们就是去验证一下。


好,准备发车。


小心求证


关于 mybatis 我之前写过这篇文章《很开心,在使用mybatis的过程中我踩到一个坑》,其中提到了一个逆向排查法。有兴趣的可以去看一下。


在这篇文章中我们还是来个常规分析吧。本文分析源码为 mybatis 3.4.0 版本。


首先,我先问你一个问题。SpringBoot 是怎么加载 mybatis 的?


熟悉 SpringBoot 启动过程的朋友知道,SpringBoot 会去加载mybatis-spring-boot-autoconfigure-x.x.x.jar下 META-INF 中的spring.factories文件:


所以,下面的 sqlSessionFactory 方法就是我们的入口处:


入口给你找到了,你可以直接在这里加上断点开始 debug 了。


我知道,虽然是刚刚开始,但是可能有些读者觉得已经超纲了。但是没有关系的,继续看下去,我这里只是给你说个入口在哪而已。


由于 debug 的过程不是文本重点,这里就不去介绍了。debug 的时候我们会看到这个方法:


org.apache.ibatis.builder.xml.XMLMapperBuilder#parse


这个方法的第 92 行,就是我们的 xml 内容:


然后在下面这个方法中对 xml 文件进行疯狂的解析:

org.apache.ibatis.builder.xml.XMLStatementBuilder#parseStatementNode


图片可以点开看大图哦,debug 模式,可以看到一些输出:




上面的源码的第 94 行,获 取 SqlSource 很关键,要好好看看,这里调用了这个方法:

org.apache.ibatis.scripting.xmltags.XMLLanguageDriver#createSqlSource(org.apache.ibatis.session.Configuration, org.apache.ibatis.parsing.XNode, java.lang.Class<?>)


接着在下面方法的第 52 行,剥离出整个完整的 sql:


org.apache.ibatis.scripting.xmltags.XMLScriptBuilder#parseScriptNode


上面就是常规的 xml 形式的 SQL 原始语句(变量、条件表达式都还未进行替换,不可直接执行的 SQL)获取过程,不是本文重点,简单的分析一下就行。


接下来继续 debug 的时候会遇到下面这个方法,看包名你就知道,这就是我们关心的注解解析相关的方法了:


org.apache.ibatis.builder.annotation.MapperAnnotationBuilder#parse

在这个方法里面,会去循环处理 mapper 类中的方法:


接下来,就会遇到这个方法了:

org.apache.ibatis.builder.annotation.MapperAnnotationBuilder#getSqlSourceFromAnnotations


当循环到 annotationQueryAgeByName 方法的时候,下面方法的一些关键参数如下所示:


首先我们看 428 行,解析到了 sqlAnnotationType 为 Select:


所以会进入下面的 if 分支,然后运行到 435 行,通过反射获取到了 @Select 注解上的 SQL 语句:


继续往下走,通过 436 行,我们可以走到这个方法:


org.apache.ibatis.scripting.xmltags.XMLLanguageDriver#createSqlSource(org.apache.ibatis.session.Configuration, java.lang.String, java.lang.Class<?>)


这个方法就有点意思了,进来判断了 script 即 SQL 是否是以 script 脚本开头的,如果是,则走的和之前 xml 一样的解析逻辑

目录
相关文章
|
6天前
|
前端开发 Java 数据库连接
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
20 2
|
30天前
|
SQL Java 数据库连接
MyBatis-Plus高级用法:最优化持久层开发
MyBatis-Plus 通过简化常见的持久层开发任务,提高了开发效率和代码的可维护性。通过合理使用条件构造器、分页插件、逻辑删除和代码生成器等高级功能,可以进一步优化持久层开发,提升系统性能和稳定性。掌握这些高级用法和最佳实践,有助于开发者构建高效、稳定和可扩展的企业级应用。
77 13
|
2月前
|
SQL Java 数据库连接
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
MyBatis-Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。本文讲解了最新版MP的使用教程,包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段等核心功能。
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
|
2月前
|
SQL 缓存 Java
MyBatis如何关闭一级缓存(分注解和xml两种方式)
MyBatis如何关闭一级缓存(分注解和xml两种方式)
104 5
|
2月前
|
Java 数据库连接 mybatis
Mybatis使用注解方式实现批量更新、批量新增
Mybatis使用注解方式实现批量更新、批量新增
67 3
|
2月前
|
SQL 存储 数据库
深入理解@TableField注解的使用-MybatisPlus教程
`@TableField`注解在MyBatis-Plus中是一个非常灵活和强大的工具,能够帮助开发者精细控制实体类与数据库表字段之间的映射关系。通过合理使用 `@TableField`注解,可以实现字段名称映射、自动填充、条件查询以及自定义类型处理等高级功能。这些功能在实际开发中,可以显著提高代码的可读性和维护性。如果需要进一步优化和管理你的MyBatis-Plus应用程
237 3
|
2月前
|
Java 数据库连接 mybatis
Mybatis使用注解方式实现批量更新、批量新增
Mybatis使用注解方式实现批量更新、批量新增
243 1
|
4月前
|
SQL XML Java
mybatis复习02,简单的增删改查,@Param注解多个参数,resultType与resultMap的区别,#{}预编译参数
文章介绍了MyBatis的简单增删改查操作,包括创建数据表、实体类、配置文件、Mapper接口及其XML文件,并解释了`#{}`预编译参数和`@Param`注解的使用。同时,还涵盖了resultType与resultMap的区别,并提供了完整的代码实例和测试用例。
mybatis复习02,简单的增删改查,@Param注解多个参数,resultType与resultMap的区别,#{}预编译参数
|
3月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
99 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
3月前
|
XML Java 数据格式
手动开发-简单的Spring基于XML配置的程序--源码解析
手动开发-简单的Spring基于XML配置的程序--源码解析
98 0