架构与源码
接口层 : 接口调用 数据处理层 : SQL解析执行 框架支撑层 : SQL配置 引导层 : 配置、启动MyBaits |
一、框架设计 4 层 |
接口层: 接口调用方式: 基于Statement ID、 基于Mapper接口 数据处理层: 参数映射、SQL解析、SQL执行、结果处理和映射 框架支撑层: SQL语句配置方式: 基于XML配置 基于注解 [ 事务管理、连接池管理、缓存机制 ] 引导层: 基于XML配置方式 基于Java API方式
扫描二维码关注公众号,回复:
3089296 查看本文章
#接口层:数据增删改查接口、配置信息维护接口 #数据处理层: ##参数映射 ParamterHandler: 参数映射配置、参数映射解析、参数类型解析 ##SQL解析 SqlSource: SQL语句配置、SQL语句解析、SQL语句动态生成 ##SQL执行 Excecutor: SimpleExecutor、BatchExecutor、ReuseExecutor ##结果处理和映射 ResultSetHandler: 结果映射配置、结果类型转换、结果类型转换 |
1.接口层--持久层与数据库交互 |
交互方式: a.使用传统的MyBatis提供的API b.使用Mapper接口 1.使用传统的MyBatis提供的API:; ##传统的传递Statement Id 和查询参数给SqlSession对象,使用SqlSession对象完成和数据库的交互;MyBatis提供的非常方便和简单的API,供用户实现对数据库的增删改查数据操作,以及对数据库连接信息和MyBatis自身配置信息的维护操作。 ## 工作模式: 2.使用Mapper接口 ##配置文件<mapper>节点抽象为Mapper接口,而这个几口声明的方法和<mapper>节点中的<select|update|delete|insert>节点对应 ### Mapper 配置文件 :Mapper接口 ### <mapper namespace=""> : interface XxxMapper ### id值 :方法名称 ### parameterTyoe : 入参类型 ### resuleMap : 返回值类型 or 返回结果集的元素类型 ### 原理: 根据MyBatis的配置规范配置好后,通过SqlSession.getMapper(XxxMapper.class)方法,MyBatis会根据相应的接口声明的方法信息,通过动态代理机制生成一个Mapper实例,我们使用Mapper接口一个方法时,MyBatis会根据方法名称和参数类型,确定Statement Id,底层通过SqlSession.select("statementId",parameterObject);实现对数据库的操作。 ### 目的:面向接口编程,即用户在接口上使用注解来配置SQL语句,脱离XML配置文件。 |
2.数据处理层 |
核心:a. 通过传入参数,构建动态SQL语句 b. SQL语句执行 c. 封装查询结果集成List<E> 1. 参数映射和动态SQL语句生成 ### <1 动态SQL: ### <2 参数映射:java数据类型与jdbc数据类型的转换 ##### 查询阶段:java类型的数据,转换成jdbc类型的数据,并设值preparedStatrment.setXxx(); ##### :resultset 查询结果集的jdbcType数据转换成java数据类型 2. SQL语句的执行以及封装查询结果集成List<E> ### 动态SQL语句生成之后,MyBatis将执行SQL语句,并将可能返回的结果集转换成List<E> 列表。MyBatis在对结果集的处理种,支持结果集一对多和多对一的转换,并且有两种支持方式 :嵌套查询语句的查询、嵌套结果集的查询。 |
3.框架支撑层 |
##1,事务管理机制 ##2,连接池管理机制 数据吞吐量、访问量、 [ 数据源与连接池 ] ##3,缓存机制 提升数据利用率 [ 服务器与数据库 ] ### [ MyBatis对一些查询提供会话级别的数据缓存,会将对某一次查询,放置到SqlSession,在允许的时间间隔内,完全相同的查询,MyBatis会直接将缓存结果返回给用户,而不再到数据库查找。] ##4,SQL语句的配置方式 ## <1 XML配置: XML配置文件 #### 高级功能:主键返回 ## <2 注解配置: 支持有限,高级功能仍需要XML配置。 #### Mapper接口+注解==>注解配置SQL语句 |
4.引导层 |
引导层:配置和启动MyBatis配置信息的方式。 ## 1. 基于XML配置文件的方式 ## 2. 基于Java API的方式 |
二、主要构件及相互关系
一、主要构件 |
SqlSession 与数据库交互,完成必要的增删改查 [ 会话, 交互 ] [ 顶层API ] Executor 生成SQL语句,维护查询缓存 [ 执行器, 调度 ] StatementHandler 操作JDBC Statement:设置参数、Statement结果集转换成List集合 [ 命令处理器,封装JDBC Statement ] ParameterHandler 转换传入参数 为 JDBC Statement 所需参数 [参数处理器] TypeHandler 映射、转换:Java数据类型与JDBC数据类型 [类型处理器] MappedStatement 维护、封装:<select|update|delete|insert>节点 [映射语句] SqlSource 根据传入的parameterObject,动态生成SQL语句, [ Sql源] 将信息封装到BoundSql对象,并返回 BoundSql 表示:动态生成的SQL语句以及相应的参数信息 [Sql绑定] Configuration 维持:MyBatis配置信息 |
二、相互关系 |
#第一步 SqlSession 会话访问:增删改查 #第二步 Executor 查询缓存↓, 传入SQL↑ , #第三步 StatementHandler 执行Java查询语句↓ 传入Java结果集↑ ##第四步 ParameterHandler ResultSetHandler 参数设值↓ 结果集转换↑ ##第五步 TypeHandler<T> Java->JDBC↓ JDBC->Java↑ #第六步 JDBC Statement ResultSet Statement ——> ResultSet ####Statement:PrepareStatement\ SimpleStatement\ CallableStatement #A BoundSql #B MappedStatement :SqlSource ResultMap #C Configuration |
三、案例
一、数据准备 |
#1. 数据库数据 DATABASE-TABLE #2. 配置配置文件 MyBatisConfig.xml #3. 创建数据对象 Bean : 创建映射文件 Mapper:<mapper namespace="BeanMapper"> [映射声明:命名空间] ### A <resultMap id="BaseResultMap"、type="Bean"> [ 结果映射:主键映射+字段映射] #####<id column="主键"、property="属性"、jdbcType> [主键映射] #####<result column="字段"、property="属性"、jdbcType> [字段映射] ### B <method id="methodType"、resultMap="BaseResultMap"、parameterType> [映射方法:结果映射+传参类型] #4. 配置项目文件 POM:<properties>\<dependencies> ###1.加载配置文件 InputStream inputStream = Resources.getResourceAsStream("配置文件"); ###2.创建会话工厂 #建造者 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder; #建造工厂 SqlSessionFactory factory = builder.build( inputStream ); ###3.创建会话 #开启会话 SqlSession sqlSession = factory.openSession(); ###4.数据操作 sqlSession.methodName(); |
二、SqlSession过程分析 |
1.开启数据库访问会话--创建SqlSession对象。 ##即:SqlSession对象,封装一次数据库会话访问—>实现事务控制和数据操作 2. SqlSession,传递配置的Sql语句 的Statement Id和params,返回结果。 ##第一步,传入statement[Java命令],通过Statement Id, 【configuration】 在mybatis配置对象,查找对应的MappedStatement [JDBC命令] [ MyBatis在初始化的时候,会将MyBatis的配置信息全部加载到内存中,使用org.apache.ibatis.session.Configuration实例来维护。使用者可以使用sqlSession.getConfiguration()方法来获取。MyBatis的配置文件中配置信息的组织格式和内存中对象的组织格式几乎完全对应的。] 3. Excutor,根据SqlSession传递的params执行query()方法。 ##Executor.query()方法几经转折,最后创建一个StatementHandler对象,然后将必要的参数传递给StatementHandler,使用StatementHandler来完成对数据库的查询,最终返回List结果集。 4. StatementHandler对象负责设置Statement对象中的查询参数、处理JDBC返回的resultSet,将resultSet加工为List 集合返回。 ## prepareStatement() 5. StatementHandler 的parameterize(statement) 方法 ##StatementHandler 的parameterize(Statement) 方法调用了 ParameterHandler的setParameters(statement) 方法, ##ParameterHandler的setParameters(Statement)方法负责 根据输入参数,对statement对象的 ? 占位符处进行赋值。 6. StatementHandler 的List<E> query(Statement statement, ResultHandler resultHandler)方法的实现: ##StatementHandler 的List<E> query(Statement statement, ResultHandler resultHandler)方法的实现,是调用了ResultSetHandler的handleResultSets(Statement) 方法。ResultSetHandler的handleResultSets(Statement) 方法会将Statement语句执行后生成的resultSet 结果集转换成List<E> 结果集。 ###query() ## 1. 调用preparedStatemnt。execute()方法,然后将resultSet交给ResultSetHandler处理 ## 2. 使用ResultHandler来处理ResultSet ###handleResultSets() |
源码: 1. 开启一个数据库访问会话---创建SqlSession对象, 2.为SqlSession传递一个配置的Sql语句 的Statement Id和参数,然后返回结果: 上述的"com.louis.mybatis.dao.EmployeesMapper.selectByMinSalary",是配置在EmployeesMapper.xml 的Statement ID,params 是传递的查询参数。 让我们来看一下sqlSession.selectList()方法的定义: MyBatis在初始化的时候,会将MyBatis的配置信息全部加载到内存中,使用org.apache.ibatis.session.Configuration实例来维护。使用者可以使用sqlSession.getConfiguration()方法来获取。MyBatis的配置文件中配置信息的组织格式和内存中对象的组织格式几乎完全对应的。上述例子中的 加载到内存中会生成一个对应的MappedStatement对象,然后会以key="com.louis.mybatis.dao.EmployeesMapper.selectByMinSalary" ,value为MappedStatement对象的形式维护到Configuration的一个Map中。当以后需要使用的时候,只需要通过Id值来获取就可以了。 从上述的代码中我们可以看到SqlSession的职能是:
3.MyBatis执行器Executor根据SqlSession传递的参数执行query()方法(由于代码过长,读者只需阅读我注释的地方即可): 上述的Executor.query()方法几经转折,最后会创建一个StatementHandler对象,然后将必要的参数传递给StatementHandler,使用StatementHandler来完成对数据库的查询,最终返回List结果集。 4. StatementHandler对象负责设置Statement对象中的查询参数、处理JDBC返回的resultSet,将resultSet加工为List 集合返回: 5. StatementHandler 的parameterize(statement) 方法的实现: 6. StatementHandler 的List<E> query(Statement statement, ResultHandler resultHandler)方法的实现: |
Executor的功能和作用: |
|
StatementHandler: |
|