Mybatis

Mybatis 的好处

把 Sql 语句从 Java 中独立出来。
封装了底层的 JDBC,API 的调用,并且能够将结果集自动转换成 JavaBean 对象,简化了
Java 数据库编程的重复工作。
自己编写 Sql 语句,更加的灵活。因此能够实现比 hibernate 等全自动 orm 框架更高的查询效率,能够完成复杂查询。
入参无需用对象封装(或者 map 封装),使用@Param 注解

MyBatis 的优缺点

优点
易于上手和掌握
Sql 写在 xml 里面,便于统一管理和优化
减少 Sql 与程序代码的耦合
提供 xml 标签,支持动态 Sql 编写
缺点
Sql 工作量大,尤其是字段多,关联表多时,更是如此
Sql 依赖于数据库,导致数据库移植性差
由于 xml 里面标签 id 必须唯一,导致 DAO 中方法不支持方法重载。所以 dao 层必须是接口

MyBatis 应用中#与$有什么异同点

相同点:都是通过 get 来获取值的
不同点:$传进去的字符串不带引号 #号带引号

  1. #{}是预编译处理,${}是字符串替换。
  2. Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement
    的 set 方法来赋值;
  3. Mybatis 在处理 时 , 就 是 把 {}时,就是把 {}替换成变量的值,相当于字符串拼接
  4. 使用#{}可以有效的防止 SQL 注入,提高系统安全性。

MyBatis 应用动态 SQL 解决了什么问题

有时候,固定的 sql 语句不能够满足我们的应用需求。这个时候需要在 标准的
基础上建立动态的查询语句。
Mybatis 提供了多种注解,可以提供动态查询语言。
比如说在开发的时候,遇到这样的场景,界面提供了多种查询,但是都是非 必填写,
在选择查询条件时可以选中任意几种组合作为查询条件,如果在使 用 jdbc 的时候,需要
判断参数为空,自己组装 sql,
但是 mybatis 提供动态 sql 机制,依靠标签。

mybatis 的缓存机制,一级,二级

一级缓存
默认开启
SqlSession 级别的缓存,实现在同一个会话中数据的共享
一级缓存的生命周期和 SqlSession 一致
当有多个 SqlSession 或者分布式环境下,数据库写操作会引起脏数据。
二级缓存
默认不开启,需手动开启
SqlSessionFactory 级别的缓存,实现不同会话中数据的共享,是一个全局变量
可自定义存储源,如 Ehcache
当开启缓存后,数据查询的执行的流程是:二级缓存>一级缓存>数据库
不同于一级缓存,二级缓存可设置是否允许刷新和刷新频率实现
实体类实现序列化,在 mapper 文件中开启cache
在配置文件中设置 cacheEnabled 为 true

mybatis 的基本工作流程

1.读取配置文件,配置文件包含数据库连接信息和 Mapper 映射文件或者 Mapper 包路径。
2.有了这些信息就能创建 SqlSessionFactory,SqlSessionFactory 的生命周期是程序级,
程序运行的时候建立起来,程序结束的时候消亡
3.SqlSessionFactory 建立 SqlSession,目的执行 sql 语句,SqlSession 是过程级,一个方
法中建立,方法结束应该关闭
4.当用户使用 mapper.xml 文件中配置的的方法时,mybatis 首先会解析 sql 动态标签为对
应数据库 sql 语句的形式,并将其封装进 MapperStatement 对象,然后通过 executor 将 sql
注入数据库执行,并返回结果。
5将返回的结果通过映射,包装成 java 对象。

Configs(xml) :配置文件&映射文件(mapper)
SqlSessionFactoryBuilder :加载配置文件,创建SQLSessionFactory对象
SqlSessionFactory :负责创建session对象
SqlSession :负责执行SQL操作

MyBatis 的编程步骤

创建 SqlSessionFactory
通过 SqlSessionFactory 创建 SqlSession
通过 SqlSession 执行数据库操作
调用 session.commit()提交事务
调用 session.close()关闭事务

什么是 MyBatis 的接口绑定,有什么好处

接口映射就是在 IBatis 中任意定义接口,然后把接口里面的方法和 SQL 语句绑定,我们通过
直接调用接口方法 例如:
UserMapper userMapper=sqlSession.getMapper (UserMapper.class) 就可以,这样比
起原来了 SqlSession 提供的方法,例如 List countryList =
sqlSession.selectList(“selectAll”)
;我们可以有更加灵活的选择和设置.。
注意:(1)Mapper .xml 文件的 namespace 属性必须配置为接口的全限定名称,接口方法
名与 Mapper.xml 中的id 值必须相同,且接口方法的返回值类型必须与
Mapper.xml 配置的 resultType 一致,这里后者起到决定作用

(2)select 查询通过在 Mapper.xml 中配置 ResultMap 标签,将查询结果的列名与字段名
对应。
insert 语句通过#{属性名}从接口参数获取值放到 sql 语句中。
(3)Mapper.xml 接口绑定本质是动态代理

使用 MyBatis 的 mapper 接口调用时有哪些要求?

Mapper 接口方法名和 mapper.xml 中定义的每个 sql 的 id 相同
Mapper接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的类型
相同
Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相

Mapper.xml 文件中的 namespace 即是 mapper 接口的类路径

JDBC 编程有哪些不足之处,MyBatis 是如何解决这些问

题的?

JDBC 编程的不足之处
数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可
解决此问题。
Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变
java 代码。
向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需要
和参数一一对应。
对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录
封装成 pojo 对象解析比较方便。
MyBatis 的解决方案
在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。
将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。
Mybatis 自动将 java 对象映射至 sql 语句。

Mybatis 自动将 sql 执行结果映射至 java 对象

Mybatis 的插件运行原理,以及如何编写一个插件

1)Mybatis 仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler、
Executor 这 4 种接口的插件
,Mybatis 通过动态代理,为需要拦截的接口生成代理对象以实
现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是
InvocationHandler 的 invoke()方法,当然,只会拦截那些你指定需要拦截的方法。
2)实现 Mybatis 的 Interceptor 接口并复写 intercept()方法,然后在给插件编写注解,
指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件

Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql 的执行原理

1)Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成
逻辑判断和动态拼接 sql 的功能。
2)Mybatis 提供了 9 种动态 sql 标签
trim|where|set|foreach|if|choose|when|otherwise|bind。
3)其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接
sql,以此来完成动态 sql 的功能。

Mybatis 是否支持延迟加载?如果支持,它的实现原理

是什么?

1)Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载
association 指的就是一对一,collection 指的就是一对多查询。在 Mybatis 配置文件中,
可以配置是否启用延迟加载 lazyLoadingEnabled=true|false
2)它的原理是,使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方
,比如调用 a.getB().getName(),拦截器 invoke()方法发现 a.getB()是 null 值,那么
就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 a.setB(b),
于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName()方法的调用。这就是延迟加
载的基本原理。

Mybatis 能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别

能,Mybatis 不仅可以执行一对一、一对多的关联查询,还可以执行多对一,多对多的
关联查询,多对一查询,其实就是一对一查询,只需要把 selectOne()修改为 selectList()
即可;多对多查询,其实就是一对多查询,只需要把 selectOne()修改为 selectList()即可。
关联对象查询,有两种实现方式,一种是单独发送一个 sql 去查询关联对象,赋给主对象,
然后返回主对象。另一种是使用嵌套查询,嵌套查询的含义为使用 join 查询,一部分列是
A 对象的属性值,另外一部分列是关联对象 B 的属性值,好处是只发一个 sql 查询,就可以
把主对象和其关联对象查出来

Mybatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式?

第一种是使用resultMap标签,逐一定义列名和对象属性名之间的映射关系。
第二种是使用 sql 列的别名功能,将列别名书写为对象属性名,比如 T_NAME AS NAME,对
象属性名一般是 name,小写,但是列名不区分大小写,Mybatis 会忽略列名大小写,智能找
到与之对应对象属性名,你甚至可以写成 T_NAME AS NaMe,Mybatis 一样可以正常工作

Mybatis 映射文件中,如果 A 标签通过 include 引用了 B标签的内容,请问,B 标签能否定义在 A 标签的后面,还是说必须定义在 A 标签的前面

虽然 Mybatis 解析 Xml 映射文件是按照顺序解析的,但是,被引用的 B 标签依然可以定
义在任何地方,Mybatis 都可以正确识别
。原理是,Mybatis 解析 A 标签,发现 A 标签引用
了 B 标签,但是 B 标签尚未解析到,尚不存在,此时,Mybatis 会将 A 标签标记为未解析状
态,然后继续解析余下的标签,包含 B 标签,待所有标签解析完毕,Mybatis 会重新解析那
些被标记为未解析的标签,此时再解析 A 标签时,B 标签已经存在,A 标签也就可以正常解
析完成了。

MyBatis 里面的动态 Sql 是怎么设定的?用什么语法?

MyBatis 里面的动态 Sql 一般是通过 if 节点来实现,通过 OGNL 语法来实现,但是
如果要写的完整,必须配合 where、trim 节点,where 节点是判断包含节点有内容就插
入 where,否则不插入,trim 节点是用来判断如果动态语句是以 and 或 or 开始,那么
会自动把这个 and 或者 or 取掉

Mybatis 都有哪些 Executor 执行器?它们之间的区别是什么?

Mybatis 有三种基本的 Executor 执行器,SimpleExecutor、ReuseExecutor、
BatchExecutor。

SimpleExecutor:每执行一次 update 或 select,就开启一个 Statement 对象,用完立刻关
闭 Statement 对象。
ReuseExecutor:执行 update 或 select,以 sql 作为 key 查找 Statement 对象,存在就使
用,不存在就创建,用完后,不关闭 Statement 对象,而是放置于 Map<String, Statement>
内,供下一次使用。简言之,就是重复使用 Statement 对象。
BatchExecutor:执行 update(没有 select,JDBC 批处理不支持 select),将所有 sql 都
添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个 Statement
对象,每个 Statement 对象都是 addBatch()完毕后,等待逐一执行 executeBatch()批处理。
与 JDBC 批处理相同
作用范围:Executor 的这些特点,都严格限制在 SqlSession 生命周期范围内

为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?

Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象
时,可以根据对象关系模型直接获取,所以它是全自动的。而 Mybatis 在查询关联对象或关
联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具

对 mybatis 的理解

  1. mybatis 配置
  2. SqlMapConfig.xml,此文件作为 mybatis 的全局配置文件,配置了 mybatis 的运行环境
    等信息。
  3. mapper.xml 文件即 sql 映射文件,文件中配置了操作数据库的 sql 语句。此文件需要在
    SqlMapConfig.xml 中加载。
  4. 通过 mybatis 环境等配置信息构造 SqlSessionFactory 即会话工厂
  5. 由会话工厂创建 sqlSession 即会话,操作数据库需要通过 sqlSession 进行。
  6. mybatis 底层自定义了 Executor 执行器接口操作数据库,Executor 接口有两个实现,一
    个是基本执行器、一个是缓存执行器。
  7. Mapped Statement 也是 mybatis 一个底层封装对象,它包装了 mybatis 配置信息及 sql
    映射信息等。mapper.xml 文件中一个 sql 对应一个 Mapped Statement 对象,sql 的 id 即是
    Mapped statement 的 id。
  8. Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor
    通过 Mapped Statement 在执行 sql 前将输入的 java 对象映射至 sql 中,输入参数映射就是
    jdbc 编程中对 preparedStatement 设置参数
  9. Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor
    通过 Mapped Statement 在执行 sql 后将输出结果映射至 java 对象中,输出结果映射过程相
    当于 jdbc 编程中对结果的解析处理过程

Mybatis配置文件

驼峰规则映射

mybatis-plus:
configuration:

map-underscore-to-camel-case: true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值