来源:徐郡明《Mybatis技术内幕》
为什么需要ORM框架呢?
首先看看传统的JDBC编程的操作步骤:
-
注册数据库驱动,明确指定数据库URL地址、数据库用户名、密码等连接信息
-
通过DriverManager打开数据库连接
-
通过数据库连接创建Statement对象
-
通过Statement对象执行SQL语句,得到ResultSet对象
-
通过ResultSet读取数据,并将数据转换成JavaBean对象
-
关闭ResultSet、Statement对象以及数据库连接,释放相关资源
上述步骤 l ~步骤 4 以及步骤 6 在每次查询操作中都会出现,在保存、更新、删除等其他数据库操作中也有类似的重复性代码。在实践中,为了提高代码的可维护性,可以将上述重复性代码封装到 一个类似 DBUtils 的工具类中 。 步骤 5 中完成了关系模型到对象模型的转换,要使用比较通用的方式封装这种复杂的转换是比较困难的 。
什么是ORM
ORM(Object Relational Mapping)对象关系映射,ORM框架的主要功能就是根据映射配置文件,完成数据模型与关系模型之间的映射。除此之外,ORM还提供数据库连接池、缓存等功能。
简单例子
mybatis配置文件 mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapping/userMapper.xml"/>
</mappers>
</configuration>
实体类User.java
package com.zzh.mybatis.entity;
public class User {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
映射文件 userMapper.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.zzh.mybatis.mapping.userMapper">
<select id="getUser" parameterType="int"
resultType="com.zzh.mybatis.entity.User">
select * from user where id=#{id}
</select>
</mapper>
测试类 Main
package com.zzh.mybatis;
import com.zzh.mybatis.entity.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class Main {
public static void main(String[] args) throws IOException{
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("com.zzh.mybatis.mapping.userMapper.getUser", 1);
System.out.println(user);
}
}
Mybatis整体架构
Mybatis整体架构源码中对应的目录结构:
目录结构基础支持层
反射模块
mybatis提供了反射模块,该模块对java原生反射进行了良好封装。
类型转换模块
mybatis为简化配置文件提供了别名机制,该机制是类型转换模块的主要功能之一。另一个功能是实现JDBC类型和Java类型之间的转换,该功能在为SQL语句绑定实参以及映射查询结果集时会涉及。在为sql语句绑定实参的时候,会将数据由java类型转换为JDBC类型,而在映射结果集的时候,会将数据由JDBC类型转化为Java类型。
日志模块
良好日志可以帮助开发测试人员迅速定位BUG代码,目前有很多优秀日志框架例如log4j、log4j2、slf4j等,可以集成第三方的日志框架。
资源加载模块
主要是对类加载器进行封装,确定类加载器的使用顺序,并提供加载类文件一起其他资源文件的功能
解析器模块
主要提供了两个功能:一是对XPath进行封装,为MyBatis初始化时解析mybatis-config.xml配置文件提供支持;再者就是为处理动态SQL的占位符提供支持。
数据源模块
Mybatis自身提供了相应的数据源实现,同时也提供了与第三方数据源集成的接口。
事务管理
Mybatis对数据库中的事务进行了抽象,其自身提供了相应的事务接口和简单实现。
缓存模块
Mybatis中提供了一级缓存和二级缓存,而这两级缓存都是依赖于基础支持层中的缓存实现的。Mybatis中自带的这两级缓存与Mybatis以及整个应用是运行在同一个JVM中的,共享同一块堆内存。如果这两级缓存中的数据量较大, 则可能影响系统中其他功能的运行,所以 当需要缓存大量数据时 ,优先考虑使用 Redis 、 Memcache 等缓存产品。
Binding模块
Binding模块将用户自定义的Mapper接口与映射配置文件关联起来,系统可以通过调用自定义Mapper接口中的方法执行相应的SQL语句。
核心处理层
在核心处理层中,实现了Mybatis的核心处理流程,其中包括Mybatis的初始化以及完成一次数据库操作的涉及的全部流程。
配置解析
在Mybatis初始化过程中,加载Mybatis-config.xml配置文件、映射配置文件、Mapper接口中的注解信息,解析后会形成相应的对象保存到Configuration对象中。
SQL解析与scripting模块
MyBatis 实现动态 SQL 语句的功能,提供 了多种动态 SQL 语句对应的节点。My Batis 中的 scripting 模块会根据用户传入的实参,解析映射文件中定义的动态 SQL节点,并形成数据库可执行的 SQL 语句 。之后会处理 SQL 语句中的占位符,绑定用户传入的实参。
SQL执行
SQL 语句的执行涉及多个组件 ,其中比 较重要的是 Executor 、 StatementHandler 、ParameterHandler 和 R巳sultSetHandler 。 Executor 主要负责维护 一 级缓存和 二 级缓存,并提供事务管理的相关操作 ,它会将数据库相关操作委托给 StatementHandler 完成。StatementHandler 首先通过 ParameterHandler 完成 SQL 语句的实参绑定,然后通过java.sql.Statement 对 象执行 SQL 语句并得到 结果集,最后通过 ResultSetHandler 完成结果集的映射 ,得到结果对象并返回 。
SQL执行插件
Mybatis 自身的功能虽然强大,但是并不能完美切 合所有 的应用场景,因此 My Batis提供了插件接口,我们可以通过添加用户自定义插件的方式对 MyBati s 进行扩展。
接口层
接口层相对简单,其核 心是 SqlSession 接口,该接口中定义了 MyBatis 暴露给应用程序调用的 API ,也就是上层应用与 MyBatis 交互的桥梁。接口层在接收到调用请求时,会调用核心处理层的相应模块来完成具体的数据库操 作 。
网友评论