ibatis
Introduce
ibatis是非常流行的一种ORM框架。ORM指的是Object Relational Mapping,它用于实现面向对象语言里不同类型系统的数据之间的转换。用过Hibernate框架的同学可能会对这个比较熟悉,ibatis与hibernate类似,不过更加灵活,不像hibernate的“全自动”,ibatis更加半自动化。作为访问数据库的工具,ibatis必须是基于JDBC的,目的解决是JDBC程序开发的繁琐性和代码的冗余性(如加载驱动,建立连接,初始化语句对象,执行数据库操作,返回结果,关闭各个对象这一重复且无技术含量的过程)。 在我们平时使用时,ibatis是通过 SQL Map 将 Java 对象映射成 SQL 语句和将结果集再转化成 Java 对象,既解决了 Java 对象与输入参数和结果集的映射,又能够让用户方便的手写使用 SQL 语句。
iBATIS 框架主要的类层次结构
总体来说 iBATIS 的系统结构还是比较简单的,它主要完成两件事情:
- 根据 JDBC 规范建立与数据库的连接
- 通过反射打通 Java 对象与数据库参数交互之间相互转化关系
iBATIS 的框架结构也是按照这种思想来组织类层次结构的,其实它是一种典型的交互式框架。先期准备好交互的必要条件,然后构建一个交互的环境,交互环境中还划分成会话,每次的会话也有一个环境。当这些环境都准备好了以后,剩下的就是交换数据了。其实涉及到网络通信,一般都会是类似的处理方式。
上图中左边SqlMapClient 接口主要定义了客户端的操作行为包括 select、insert、update、delete,右边主要是定义了当前客户端在当前线程的执行环境。SqlMapSession 可以共享使用,也可以自己创建,如果是自己创建在结束时必须要调用关闭接口关闭。 当使用者持有了 SqlMapClientImpl 对象就可以使用 iBATIS 来工作了。SqlMapExecutorDelegate 类是个执行代理类,他耦合了用户端的执行操作行为和执行的环境,持有执行操作的所需要的数据,同时提供管理着执行操作依赖的环境。
iBATIS 框架的运行原理
具体的工作顺序,类是怎么串起来的见下图。
SqlMapSession 对象的创建和释放根据不同情况会有些不同。因为 SqlMapSession 负责创建数据库的连接,对事务的管理:iBATIS 对管理事务既可以自己管理也可以由外部管理,iBATIS 自己管理是通过共享 SqlMapSession 对象实现的,多个 Statement 的执行时共享一个 SqlMapSession 实例,而且都是线程安全的。如果是外部程序管理就要自己控制 SqlMapSession 对象的生命周期。
iBATIS 对 SQL 语句的解析
在ibatis的SQL中,参数的赋值是“#“包裹的变量名。如何解析这个变量就是 iBATIS 要完成的工作。当然 SQL 的表达形式还有很多其他的形式如动态 SQL 等。 iBATIS 会把 SqlMap 配置文件解析成一个个 Statement,其中包括 ParameterMap、ResultMap,以及解析后的 SQL。当 iBATIS 构建好 RequestScope 执行环境后,要做的工作就是把传过来的对象数据结合 ParameterMap 中信息提取出一个参数数组,这个数组的顺序就是对应于 SQL 中参数的顺序,然后会调用 preparedStatement.setXXX(i, parameter) 提交参数。
数据库字段映射到 Java 对象
数据库执行完 SQL 后会返回执行结果然后对映射到java对象中。和 ParameterMap 类似,填充返回信息需要的资源都已经包含在 ResultMap 中。当有了保存返回结果的 ResultSet 对象后,就是要把列名映射到 account 对象的对应属性中。这个过程大体如下:
- 根据 ResultMap 中定义的 ResultClass 创建返回对象。获取这个对象的所有可写的也就是 setter 方法的属性数组,接着根据返回 ResultSet 中的列名去匹配前面的属性数组,把匹配结果构造成一个集合(resultMappingList),后面是选择 DataExchange 类型、AccessPlan 类型为后面的真正的数据交换提供支持。
- 根据 resultMappingList 集合从 ResultSet 中取出列对应的值,构成值数组(columnValues),这个数组的顺序就是 SQL 中对应列名的顺序。最后把 columnValues 值调用 account 对象的属性的 setter 方法设置到对象中。这