mybatis
2020-05-27 14:02:04 46 举报
AI智能生成
mybatis 自定义&使用&架构分析
作者其他创作
大纲/内容
设计简易mybatis框架
设计流程
使用端
添加对自定义框架的依赖
数据配置文件
sqlMapConfig.xml
mapper.xml
实体类
dao层
测试类
自定义框架
1. pom添加基础依赖
2. 读配置文件
以javaBean形式存储
设置实体类存放查询具体信息
以javaBean形式存储
设置实体类存放查询具体信息
1. 创建资源类方法,将配置文件加载成字节输入流
2. 解析数据库配置文件&往连接池注入配置属性
(Configuration&唯一标识:namespace+"."+id)
(Configuration&唯一标识:namespace+"."+id)
3. 解析Mapper属性,存入到HashMap中
4. 设置BoundSql对象(存放sql文本&参数)
5. 数据库配置实体类
Configuration.java
Configuration.java
6. 存放 sql statement类型 java类型 java参数
MappedStatement.java
MappedStatement.java
3. 解析配置文件
1.创建SqlSessionFactroyBuilder类
dom4j 解析&将解析出来的内容封装到Configuration中
创建SqlSessionFactory实现类DefaultSqlSession
2.创建SqlSessionFactory
接口类
实现类
3. 创建SqlSession
接口
实现
*使用JDK动态代理来为Dao接口生成代理对象,并返回。
1. method.getName()
2. method.getDeclaringClass().getName()
3. method.getGenericReturnType()
1. method.getName()
2. method.getDeclaringClass().getName()
3. method.getGenericReturnType()
4. *创建sql执行器(Executor)
接口
实现
1. 注册驱动
2. 对sql进行处理
完成对#{}的解析工作:1.将#{}使用?进行代替,2.解析出#{}里面的值进行存储
完成对#{}的解析工作:1.将#{}使用?进行代替,2.解析出#{}里面的值进行存储
3. 获取预处理对象:preparedStatement
4.获取传入的参数类型
5. 获取实例类(未知类型)
6. 遍历参数,给preparedStatement setObject
7. preparedStatement.executeQuery() 执行sql 返回结果集
8. 通过内省获取属性描述器(new PropertyDescriptor)
9. 通过反射 往结果集实体类设置属性值(invoke)
10. 完成ORM映射
运用到的设计模式
构建者模式
工厂模式
代理模式
应用
概念
ORM:对持久化的对象转化成对数据库的操作
简介:半自动化化轻量级持久框架,支持自定义sql
优势:核心sql优化,sql和业务分开,功能边界清晰
基本应用
dao层实现
规范:
1、 mapper接口的全限定名要和mapper映射文件的namespace的值相同。
2、 mapper接口的方法名称要和mapper映射文件中的statement的id相同;
3、 mapper接口的方法参数只能有一个,且类型要和mapper映射文件中statement的parameterType的值保持一致。
4、 mapper接口的返回值类型要和mapper映射文件中statement的resultType值或resultMap中的type值保持一致;
1、 mapper接口的全限定名要和mapper映射文件的namespace的值相同。
2、 mapper接口的方法名称要和mapper映射文件中的statement的id相同;
3、 mapper接口的方法参数只能有一个,且类型要和mapper映射文件中statement的parameterType的值保持一致。
4、 mapper接口的返回值类型要和mapper映射文件中statement的resultType值或resultMap中的type值保持一致;
代理开发方式:省去dao层实现类,直接便携xml ,动态代理执行sql
配置文件
常用标签
environments标签,数据库环境标签支持多环境配置
mapper标签,加载映射文件
Properties标签,加载外部Properties配置文件
typeAliases标签,实体类设置别名,方便xml简写
动态sql
<if test=条件判断></if>
<where>
mapper.xml
复杂映射
一对一
一对多
多对多
注解开发
@Before 在sql执行前执行
常用注解&复杂注解
缓存
一级缓存 :SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。Mybatis默认开启一级缓存。sqlSession本身是线程不安全的,但是使用起来由工厂创建,是多例,不会共享内存。
二级缓存 :二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。
插件
简介
Mybatis插件又称拦截器MyBatis 允许使用插件来拦截的方法调用包括:
Executor拦截执行器的方法
ParameterHandler拦截参数的处理
ResultSetHandler 拦截结果集的处理
StatementHandler 拦截Sql语法构建的处理
Mybatis是通过动态代理的方式实现拦截的。
Executor拦截执行器的方法
ParameterHandler拦截参数的处理
ResultSetHandler 拦截结果集的处理
StatementHandler 拦截Sql语法构建的处理
Mybatis是通过动态代理的方式实现拦截的。
原理
Mybatis框架在创建好这四大接口对象的实例后,都会调用InterceptorChain.pluginAll()方法。并不会直接返回对象
自定义插件
MyPlugin.java
sqlMapConfig.xml
源码分析:
plugin 实现了InvocationHandler。
此时调用代理的方法,将会转到InvocationHandler的invoke方法中执行。
最后转到需要我们实现的Interceptor接口中执行代理逻辑和元逻辑。
此时调用代理的方法,将会转到InvocationHandler的invoke方法中执行。
最后转到需要我们实现的Interceptor接口中执行代理逻辑和元逻辑。
pageHelper
倒入依赖
sqlMapConfig.xml配置
测试使用
通用Mapper
简介 :基于mybatis插件机制,解决单表crud编写sql,不需要dao层,只需要实体类。
使用
引入依赖
xml配置
设置实体类
定义通用Mapper
测试使用
架构源码分析
架构设计
API接口层:接受外部请求,调用数据处理层,完成数据处理
传统api,需要实现dao层接口。
Mapper代理方式(getMapper)
数据处理层:负责sql查找、解析、执行、结果映射等处理,根据数据调用完成一次对数据的操作。
基础支撑层:负责连接数据库管理、事务管理、配置管理以及缓存处理,这些都是共通的东西,将他们提取出来。
为上层数据处理提供作为基础支撑。
为上层数据处理提供作为基础支撑。
主要构件
SqlSession:顶层API,表示和数据库交互的会话,完成crud
Executor:MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护。
StatementHandler:封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合。
ParameterHandler:对用户传递的参数转换成JDBC Statement 所需要的参数。
ResultSetHandler : 将JDBC返回的ResultSet结果集对象转换成List类型的集合。
TypeHandler : 对java数据类型和jdbc数据类型之间的映射和转换。
MappedStatement: MappedStatement维护了一条<select|update|delete|insert>节点的封装。
SqlSource :负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回。
BoundSql :表示动态生成的SQL语句以及相应的参数信息。
Configuration:MyBatis所有的配置信息都维持在Configuration对象之中。
关系图
总体流程
加载配置并初始化
触发条件:加载配置文件
处理过程:主配置文件存入到configuration。
SQL的配置信息加载成为一个个MappedStatement,放在内存中。
SQL的配置信息加载成为一个个MappedStatement,放在内存中。
接收调用请求
触发条件:调用Mybatis提供的API(sqlSession)
传入参数:为SQL的ID和传入参数对象
处理过程:将请求传递给下层的请求处理层进行处理。
处理操作请求
触发条件:API接口层传递请求过来
传入参数:为SQL的ID和传入参数对象
处理过程:
(A)根据SQL的ID查找对应的MappedStatement对象。
(B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
(C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。
(D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。
(E)释放连接资源。
(A)根据SQL的ID查找对应的MappedStatement对象。
(B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
(C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。
(D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。
(E)释放连接资源。
返回处理结果:将最终的处理结果返回
设计模式
构建者模式应用
mybatis初始化非常复杂,不是一个构造器能搞定的,所以要构造者模式
例如 SqlSessionFactoryBuilder调用 XMLConfigBuilder并创建DefaultSqlSessionFactory
例如 SqlSessionFactoryBuilder调用 XMLConfigBuilder并创建DefaultSqlSessionFactory
工厂模式
mybatis使用的简单工厂,例如 DefaultSqlSessionFactory 重载了很多 openSession() 方法,根据不同参数来产出产品。
底层的openSessionFromDataSource通过 获得 Environment 对象、创建 Transaction 对象、创建 Executor 对象、
创建 DefaultSqlSession 对象构建出sqlSession
底层的openSessionFromDataSource通过 获得 Environment 对象、创建 Transaction 对象、创建 Executor 对象、
创建 DefaultSqlSession 对象构建出sqlSession
代理模式
mybatis 核心。当调用Configuration的getMapper方法时,会调用 mapperRegistry.getMapper()
该方法又调用mapperProxyFactory.newInstance(sqlSession)生成代理对象返回。
MapperProxy 实现了InvocationHandler的invoke,调用完拦截的方法后,MapperMethod最终调用了执行的方法。
该方法又调用mapperProxyFactory.newInstance(sqlSession)生成代理对象返回。
MapperProxy 实现了InvocationHandler的invoke,调用完拦截的方法后,MapperMethod最终调用了执行的方法。
0 条评论
下一页