如题所述
假如我们要自己设计一个半自动的仿 Mybatis 框架,有哪些环节是必不可少的呢?思考再三,必然有以下环节:
如果仅考虑这三点的话,其实实现一个简单的 ORM 框架就很容易了,再附加一些反射和正则表达式等等就可以搞定了.
那如果去参考 Mybatis,我们来看看它的几个环节是如何设计的:
其实大致思路一样,需要一个数据结构去存储全部的变量,通过接口代理的方式调用 Sqlsession 里面内置的方法,`` 不同的是真正的执行者又加了一层,是 Executor ``,再通过原始 JDBC 返回数据给调用者,当然, 真正的 Mybatis 包含了众多的设计模式以及数据源,缓存,动态 SQL,数据库事务,延迟加载处理 等等
为了验证 mybatis 的执行流程,采用了两种方式去调用接口,如下所示:
>
这里有个小点需要强调下,真正的执行者是`` Executor ``,我们每次在使用以下代码:
通过查看源码也可以看到,SqlSession 接口的默认实现类是`` DefaultSqlSession ``
而方法真正的执行,如 selectList 方法:
>
#{} 是预编译处理,${}是字符串替换。Mybatis 在处理 #{}时,会将 sql 中的 #{}替换为?号,调用 PreparedStatement 的
set 方法来赋值;
Mybatis 在处理时,就是把时,就是把{}替换成变量的值。
使用 #{}可以有效的防止 SQL 注入,提高系统安全性
PS:mybatis 执行的本质还是 SQL,因此回归本质可以简单理解为一个对于 PreparedStatement ,一个对应 Statement
Dao 接口即 Mapper 接口,接口的全限名,就是映射文件中的 namespace 的值;接口的方法名,就是映射文件中 Mapper 的 Statement 的 id 值;接口方法内的参数,就是传递给 sql 的参数
`` 实现原理: ` Mapper接口的工作原理是JDK动态代理,mybatis会对每一个mapper代理生成一个mapperProxy对象,代理对象会拦截接口方法,转而自动对应到sqlsession上,最终由 ` Executor ``执行
`` 参数不同,方法不可重载 ``,为什么?
上文说到 mybatis 有一个环节是解析 XML 文件或者解析接口,它会去构建一个叫做 MapperStatement 对象去存储 mapper 的相关信息,每一个 dao 接口方法在执行的时候到底是如何定位找到对应的 MapperStatement 的呢?
源码逻辑图: