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