Mybatis
2021-11-18 19:58:15 24 举报
AI智能生成
MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的过程。MyBatis可以使用简单的XML或注解来配置和映射原生信息,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。 MyBatis的主要特点包括:简单易用、灵活、高效、解耦、可维护性高。通过MyBatis,我们可以实现数据库操作的自动化,大大提高了开发效率。同时,MyBatis还具有良好的移植性,可以在不同的数据库之间轻松切换。
作者其他创作
大纲/内容
配置使用连接池简单
SQL语句写在配置文件中与java代码分离,支持态SQL
自动映射java对象和sql语句
与JDBC比较代码量减少
优点
SQL编写工作量大
sql语句依赖数据库,项目移植性降低,不能随意变更数据库
缺点
优缺点
需要自己实现连接池
PreparedStatement使用占位符传参,存在硬编码
对结果集的处理存在大量重复代码
jdbc
集成连接池简单
在xml配置文件中写SQL,实现与java代码分离
自动映射java对象与SQL语句
mybatis
与jdbc比较
全变映射框架
提供了日志、缓存、级联(更强大)等特性,数据库无关性更好(但会消耗更多的性能)
重量级框架,学习成本高,适合需求相对稳定的项目
Hibernate 是一个强大、方便、高效、复杂、间接、全自动化的持久层框架。
hibernate
半自动映射框架
支持动态SQL,处理列表,动态生成表名,支持存储过程,但工作量相对大些
不支持数据库无关,但SQL优化相对简单
MyBatis 是一个小巧、方便、高效、简单、直接、半自动化的持久层框架
与hibernate比较
与其他方式比较
简介
仅支持关联类型(嵌套查询)的延迟加载
使用CGLIB创建对象的代理对象
原理
延迟加载
1.接口实现类继承 SqlSessionDaoSupport:使用此种方法需要编写mapper 接口,mapper 接口实现类、mapper.xml 文件。
2.使用 org.mybatis.spring.mapper.MapperFactoryBean
3.使用 mapper 扫描器
Mapper编写方式
关联查询
嵌套查询
一对一一对多查询方式
自定义实现TypeHandler实现类型映射
枚举(Enum)支持
trim|where|set|foreach|if|choose|when|otherwise|bind
动态SQL
使用RowBounds对象进行内存分页(假分页)
分页方式
用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
分页原理
分页
可以编写针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件
mybatis支持插件
对其他session对数据的CUD操作无法感知
会话级缓存,会话结束即清空
基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session
是一个粗粒度的缓存,没有更新缓存和缓存过期的概念,同时只是使用了默认的hashmap,也没有做容量上的限定
对统一SQL的认定Key为:Statement Id + Offset + Limmit + Sql + Params
有多个SqlSession或者分布式的环境下,有操作数据库写的话,会引起脏数据,建议是把一级缓存的默认级别设定为Statement,即不使用一级缓存
一级缓存
存储作用域为 Mapper(Namespace)
默认不打开二级缓存
使用font color=\"#c41230\
多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用的条件比较苛刻
分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将Mybatis的Cache接口实现,有一定的开发成本,不如直接用Redis,Memcache实现业务上的缓存就好了。
由于二级缓存基于namespace缓存,如果在另外一个namespace更改了数据是无法感知的,因此建议在同一个namespace下处理CRUD。解决办法:<cache-ref namespace=\"*。*。*Mapper\"/>cache-ref代表引用别的命名空间的Cache配置,两个命名空间的操作使用的是同一个Cache。不过这样做会使缓存粒度变粗,如果关联较多就失去了缓存的意义。
注意事项及解决办法
二级缓存
当某一作用于进行CUD操作后,其下所有select缓存清空
更新机制
数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。
缓存
高级查询
你真的会用Mybatis的缓存么,不知道原理的话,容易踩坑哦
参考文献:u style=\
每次使用开启Statement对象,用完即关闭
SimpleExecutor(Mybatis默认使用)
以SQL id为键查找Statement对象,没有才创建。使用后不关闭
ReuseExecutor
将所有语句添加到批处理中,统一执行
不足:在insert时,事务未提交之前不能获取自增长ID
不支持select的批处理(JDBC批处理不支持select)
严格限制在sqlSession生命周期范围内
BatchExecutor
三种基本执行器
严格限制在SQL Session生命周期返回内
作用范围
在mybatis配置文件中可以单独指定使用的执行器,在开启用session会话的时候配置
可以在全局配置中设置执行器,但不建议这么做
概述
BaseExecutor
和缓存相关,二级缓存会先从这获取数据,未命中才去数据库查询
CachingExecutor
参考:https://blog.csdn.net/zongf0504/article/details/100104029
执行器(Executor)
占位符预编译阶段处理
变量替换在DBMS中进行
#{}
字符串替换,不需要预编译处理
变量替换在DBMS之前进行
${}
#{}与${}传参的区别
会有SQL注入风险不推荐
’%${question}%’
\"%\"#{question}\"%\"
1.直接编码硬拼接
2.CONCAT()函数
<select id=\"listUserLikeUsername\" resultType=\"com.jourwon.pojo.User\"><bind name=\"pattern\" value=\"'%' + username + '%'\
3.bind标签
Like语句查询
1.顺序传参
2.@Param注解
3.Map对象
4.Java Bean
传递多个参数
<foreach>
使用ExecutorType.BATCH
批量操作
1.<insert id=\"insertUser\" useGeneratedKeys=\"true\" keyProperty=\"userId\" >***</insert>
2.<selectKey keyColumn=\"id\" resultType=\"long\" keyProperty=\"id\" order=\"BEFORE\">***</selectKey>
主键生成方式
映射器
1.创建SqlSessionFactory
2.通过SqlSessionFactory创建SqlSession
3.通过SqlSession执行数据库操作
4.调用session.commit()提交事务
5.调用session.close()关闭session
编程步骤
如:数据库连接信息等
1.读取mybatis全局配置文件(mybatis-config.xml),其中包含了运行环境等信息
2.加载全局配置文件中配置的SQL映射文件
3.通过运行环境等配置构建会话工厂(SqlSessionFactory)
包含了执行SQL语句的所有方法
4.通过会话工厂创建会话对象
通过session传递的参数动态的生成要执行的SQL语句,同时负责查询缓存的维护
5.执行器(Executor)操作数据库
执行器接口中有一个MappedStatement参数,该参数是对映射信息的封装,用于存储要映射sql的Id和参数等信息
每一个<select> 、<insert> 、<update> 、<delete> 标签,都会被解析为一个MappedStatement对象。
6.MappedStatement
7.输入参数映射
8.输出参数映射
工作原理
对外提供使用;已接收到请求就转发给数据处理层处理
数据增加接口
数据查询接口
数据修改接口
数据删除接口
主要接口
基于Statement ID
基于Mapper接口
接口调用方式
API接口层
负责Sql的查找,解析,执行和结果映射,主要完成一次数据库操作
1.参数映射
2.SQL解析
3.SQL执行
4.结果集映射
主要操作
数据处理层
事务管理
连接池管理
缓存机制
负责基础功能支持
注解
xml
SQL配置方式
基础支持层
基于xml配置方式
基于java API 方式
引导层
架构功能
在发送语句在DBMS之前对sql进行编译,不需要SBMS进行编译
预编译阶段可以合并多次SQL操作为一次
编译语句对象可以重复利用,把一个SQL语句编译产生的PreparedStatment对象缓存下来,下次可以直接使用
mybatis默认对所有SQL进行预编译
防止SQL注入
预编译
运行原理
在接口方法上加@select @Update等注解
通过xml方式,指定namespace与接口类关联
接口绑定方式
Mapper接口方法名和mapper.xml中定义的每个sql的id相同。
Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同。
Mapper.xml文件中的namespace即是mapper接口的类路径。
Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement
接口方法不能重载
接口调用时注意事项
1.Mybatis将所有Xml配置信息都封装到All-In-One重量级对象Configuration内部。在Xml映射文件中,2.<parameterMap> 标签会被解析为ParameterMap对象,其每个子元素会被解析为ParameterMapping对象。3.<resultMap> 标签会被解析为ResultMap对象,其每个子元素会被解析为ResultMapping对象。每一个4.<select> 、<insert> 、<update> 、<delete> 标签均会被解析为MappedStatement对象,5.标签内的sql会被解析为BoundSql对象。
XML文件与Mybatis内部对象对应关系
其他
Mybatis
0 条评论
回复 删除
下一页