> 文章列表 > Mybatis(四)------Mybatis的核心框架

Mybatis(四)------Mybatis的核心框架

Mybatis(四)------Mybatis的核心框架

一、使用Mybatis操作数据库

下面是单纯使用mybatis操作数据库的流程:

MyBatis的环境搭建+入门案例_性质:综合型 目的: 掌握mybatis 内容与要求: 内容01:数据环境准备 内容02:创建并_IT女喵的博客-CSDN博客

我们可以来看看mybatis的主配置xml的一些作用:

useGeneratedKeys表示支持返回自动生成的主键

<environment>标签用于配置环境信息,包括事务管理器、数据源等信息,我们可以根据开发环境、测试环境、生产环境等来配置不同的信息,然后通过default属性来指定激活相应的环境,例如:

当然mybatis还有其他的功能,例如注册类型别名、自定义TypeHandler、plugin等 

 我们看完主配置xml,再来看看怎么执行我们定义的mapper的:

 如上面所示,SqlSession是mybatis中提供的与数据库交互的接口,该对象通过工厂模式创建,所以需要先创建SqlSessionFactory对象(通过SqlSessionFactoryBuilder类提供的系列重载方法获取),获取到工厂对象后调用该openSession方法获取一个与数据库建立连接的SqlSession实例,

到这里我们就可以通过getMapper方法来创建一个动态代理对象,然后通过该代理对象调用对应的方法实现与数据库的交互。(还可以用SqlSessionManager的方式去操作)

二、Mybatis的核心组件

我们上面讲了SqlSession是Mybatis操作数据库的一个接口,那么Mybatis底层是如何去工作的?在解析之前,我们需要先简单的了解Mybatis中其他几个比较核心的组件,以及这些组件的作用:

这些组件的大概作用:

Configuration:用于描述Mybatis的主配置信息、Mapper配置信息(mapper.xml配置文件信息,例如<resultMaps>标签配置等)、类型别名、TypeHandler等信息,其他组件主要这些信息时,可以从该对象进行获取

MapperStatement:用于描述Mapper中的sql配置信息(对<select|update|delete|insert>、@Select、@Update、@Delete、@Insert等的配置信息的封装)(例如<select id="aaa" parameterType="int">标签中的id属性、parameterType属性等等)

SqlSession:Mybatis提供的面向用户的API,表示与数据库交互时的会话对象,用于完成数据库的增删改查功能,SqlSession是Executor组件的外观,目的是对外提供易于理解和使用的数据库操作接口。

Executor:是Mybatis的sql执行器(SqlSession是Executor封装的对外的API,真正的执行器是Executor组件),完成对数据库的增删改查操作。

StatementHandler:封装了对JDBC的Statement对象的操作

ParameterHandler:封装了使用Statement的类型为CallableStatement、PreparedStatement时,对于Satement对象参数占位符设置值。

ResultSetHandler:对JDBC的ResultSet对象的封装(执行Sql类型为查询时,会将查询结果转换为Java对象)

TypeHandler:是Mybatis的类型转换器,负责处理Java类型和JDBC类型之间的映射

(根据Java类型调用setXXX方法(例如是String则调用setString方法)为Statement对象(PreParedStatement、CallableStatement类型)设置值, 根据java类型调用ResultSet对象对应的getXXX方法获取Sql执行结果等)

 

--------------------------------------------三、Configuration类

Mybatis中的配置信有两种,一种是主配置信息(包括Mapper配置信息、类型别名、TypeHandler等信息)(保存在Configuration中),一种是执行SQL语句的的Mapper的sql配置信息(保存在MapperStatement中)。(前者关于mapper保存的是Mapper.xml中的除了<select|update|insert|delete>外其他标签的配置信息,而后者是保存关于<select|update|insert|delete>这几个标签的配置信息)

Configuration中有一系列的属性来控制Mybatis运行时的行为,具体如下:

这些属性可以通过Mybatis的主配置文件中的<setting>标签来指定,例如:

 

对应属性的含义:

 

 

 

 

Configuration对象除了提供保存上表的属性外,还作为容器存放TypeHandler(类型转换器)、TypeAlias(类型别名)、Mapper接口配置信息等,例如:

这些含义如下:

 

 除此之外,Configuration对象还作为Executor、StatementHandler、ResultSetHandler、ParameterHandler组件的工厂类,用于创建这些组件的实例,Configuration累着提供了这些组件的工厂方法,具体如下:

 这些工厂会根据Mybatis不同的配置创建对应的实现类,例如Executor组件有4中不同的实现,分别是BatchExecutor、ReuseExecutor、SimpleExecutor、CachingExecutor,会有一个属性defaultExecutorType来描述这个类型,当属性只为Reuse时,newExecutor方法会返回ReuseExecutor实例,参数为Simple时返回SimpleExecutor实例(这就是典型的工厂模式的应用)。

Mybatis采用工厂模式创建Executor、StatementHandler、ResultSetHandler、ParameterHandler的另一个目的是为了实现插件拦截逻辑(这一点后面会提及)

---------------------------------------------------四、MappedStatement类

MappedStatement是用来描述<select|update|delete|insert>或者对应注解的配置信息,例如下面的<select>标签的这些属性:

 对应的含义:

MapperStatement类通过下面这些属性保存这些配置信息:

 

除此之外这个类还有一些其他的属性,这些属性的含义如下:

 

------------------------------------------五、Executor接口

SqlSession是Mybatis提供的操作数据库的API,但真正执行的SQL的是Executor组件,Executor接口有几种不同的实现类,如下:

 

BaseExecutor中定义了方法的执行流程及通用的处理逻辑,具体的实现由子类自己定义(典型的模板方法模式的应用)。

SimpleExecutor是基础的Executor,能完成基本的增删改查操作,ResueExecutor是对JDBC中的Statement对象(相当于JDBC对于sql执行的执行器)做了缓存, 如执行相同的sql语句时从缓存中获取Statement对象进行复用,避免重复创建和销毁(享元思想)。BatchExecutor会调用Statement对象的批量操作功能。

另外,Mybatis支持一级缓存和二级缓存,当开启二级缓存时,会使用这几个Executor进行装饰(装饰者模式)

下面我们看看怎么直接使用Executor操作数据库,而不是通过SqlSession

-----------------------------------六、StatementHandler接口

 StatementHandler封装了对JDBC Statement的操作,例如设置Statement对象的fetchSize摄像,设置查询超时时间,调用JDBC statement与数据库交互等,下面是StatementHandler中定义的方法:

对应方法的含义:

StatementHandler接口有几种不同的实现:

BaseStatenmentHandler是一个抽象类,封装了通用的处理逻辑和方法执行流程,具体方法实现由子类完成(模板方法)

 SimpleStatementHandler继承BaseStatementHandler,封装了对JDBC Statement对象的操作,PreparedStatementHandler封装了对JDBC prepareStatementHandler对象的操作,CallableStatementHandler封装了CallableStatement,RoutingStatementHandler会根据Mapper配置中的statementType属性(取值为statement、prepared、callable)来创建上面对应的StatementHandler实现。

------------------------------------七、TypeHandler

用JDBC API开发应用程序,其中比较繁琐的环节就是处理JDBC类型与java类型之间的转换,涉及转换有下面两个情况:

1)、PreparedStatement对象为参数占位符设置值时,需要调用一系列的setxxx方法将java类型转换为JDBC类型并为其赋值

2)、执行sql获取ResultSet对象后,需要调用ResultSet对象的getxxx方法获取字段值(此时也会将jdbc类型转换为java类型)

mybatis中使用TypeHandler解决上面两种情况,jdbc类型和java类型之间的转换的接口TypeHandler定义如下:

Mybatis中内置了很多TypeHandler,例如StringTypeHandler用于java.lang.String类型和jdbc的char、varchar、longvarchar、nchar、nvarchar、longnvarchar等类型之间的转换,StringTypeHandler的逻辑比较简单:

下表是两者之间对应关系:

这些TypeHandler是通过TypeHandlerRegister的register方法注册进类中的一个map中:

 如上图的TypeHandlerRegister中存在三个map,分别来存储jdbc类型、java类型、TypeHandler、TypeHandler类对象四者之间的关系。而调用register方法是在TypeHandlerRegister的构造方法中进行注册到map中的:

 我们也可以自定义TypeHandler,然后调用register方法注册到TypeHandlerRegister中。TypeHandlerRegister中也提供了一个getTypeHandler方法获取相应的TypeHandler对象。

------------------------------------八、ParameterHandler

当使用PreparedStatement或者CallableStatement对象时,如果Sql语句中有参数占位符,在执行sql前,需要先对参数占位符设置值,而ParameterHandler就是在PreparedStatement或者CallableStatement操作对应的Statement执行数据库交互之前为参数占位符设置值。ParameterHandler接口有两个方法,具体如下:

ParameterHandler接口只有一个实现类DefaultParameterHandler,我们重点去关注setParameters方法:

 如代码所述,Mybatis通过ParameterMapping描述参数映射的信息,在DefaultParameterHandler类的setParameters方法中,首先获取Mapper配置中的参数映射,然后遍历所有参数映射信息,根据参数名称获取对应的参数值,调用TypeHandler对象的setParameter方法为Statement对象的参数占位符设置值

-------------------------------------九、ResultSetHandler

ResultSetHandler封装了对JDBC的ResultSet,接口定义如下:

ResultSetHandler只有一个实现类DefaultResultHandler,我们主要观察handleResultSets方法的实现:

 

 

aaa