MyBatis学习笔记(4)-MyBatis经典问题

本文介绍了MyBatis框架的基础知识,包括其优点、与Hibernate的区别、常见的使用问题及解决方案。此外,还深入探讨了MyBatis的缓存机制、执行过程等高级特性。

一.什么是MyBatis

MyBatis是一款半ORM(对象关系映射)框架, 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。它内部集成了JDBC和连接池,能够让我们专注于持久化的业务逻辑,编写SQL语句,而无需关注与数据库的连接、关闭等繁琐的非业务过程。

1.MyBatis框架的优点

  1. 相较于传统的JDBC编程,MyBatis能够大幅度地减少项目中的JDBC开启连接关闭等冗余代码的书写,提高开发效率。
  2. 支持注解配置的方式和XML配置的方式,能够轻松与Spring集成。
  3. 拥有逆向工程插件,可以根据数据库表生成POJO类,我们可以直接通过这些类来完成简单的单表操作;而需要多表操作时,可以自己书写SQL,十分地灵活。
  4. 拥有动态SQL配置,可以让我们更好地调整各种情况下的SQL语句。

2.MyBatis与Hibernate的不同和优缺点

  1. MyBatis是半ORM的,而Hibernate是完全ORM的,所以MyBatis的使用场景更偏向于简单的单表查询(逆向工程)或复杂的需要手写SQL的多表查询;而Hibernate由于完全面向对象,它的所有操作都需要基于POJO类来完成,适合于比较复杂的大型系统。
  2. MyBatis更擅长从数据库生成实体类,而Hibernate更擅长于从实体类生成数据库表。
  3. 在使用MyBatis的过程中,往往所有的需求都是直接从SQL语句层面出发来实现,即SQL->MyBatis->数据库,而在使用Hibernate的过程中,往往需求都需要从POJO类开始设计实现,然后再将POJO类转化为SQL来执行,这里有一个转化的过程POJO->Hibernate->数据库
  4. 由于MyBatis面向SQL开发,所以当数据库变更时,SQL可能需要根据不同的数据库来改动,但Hibernate是面向POJO类开发,所以无论换到什么数据库,都可以由Hibernate来自动选择SQL。
  5. 由于Hibernate需要通过POJO生成SQL,当对象关系复杂时,Hibernate进行的优化不一定比手动写的SQL优化得好,所以对于有性能要求的项目,通常会使用MyBatis。

二.常见问题

1.#{}和${}的区别是什么

#{}是JDBC的预编译处理后再填入缺省值,而${}是直接将输入直接填入缺省值。使用#{}能够很好地避免SQL注入。

2.当实体类中的属性名和表中的字段名不一样时如何处理

在配置文件中,为实体类的属性名起一个别名来匹配到表名。

3.通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?

Mybatis运行时会使用JDK动态代理为Mapper接口生成代理对象proxy,代理对象会拦截接口方法,转而执行MapperStatement所代表的sql,然后将sql执行结果返回。Mapper接口中的方法不可重载,因为在mapper.xml映射文件中,需要通过类全限定名+接口名来确定唯一的一个命名空间,所以不能够区分出重载的方法。

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

第一种是使用 <resultMap> 标签,逐一定义数据库列名和对象属性名之间的映射关系。

第二种是使用sql列的别名功能,将列的别名书写为对象属性名。

原理:有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

5.如何执行大量的插入?

和SQL的批量插入一样原理一样。首先在Java代码中创建好数据集List集合,在通过配置文件读取到List中的数据,使用foreach标签进行数据的遍历解析,然后批量插入。这样做的好处是只需要和数据库建立一次连接即可插入大量的数据,而不需要重复打开大量的连接,导致资源的浪费。

 <insert id ="insertCodeBatch" parameterType="java.util.List" >
 3             <selectKey resultType ="java.lang.Integer" keyProperty= "id"
 4                  order= "AFTER">
 5                 SELECT LAST_INSERT_ID()
 6             </selectKey >
 7            insert into redeem_code
 8            (bach_id, code, type, facevalue,create_user,create_time)
 9            values
10             <foreach collection ="list" item="reddemCode" index= "index" separator =",">
11                 (
12                 #{reddemCode.batchId}, #{reddemCode.code},
13                 #{reddemCode.type},
14                 #{reddemCode.facevalue},
15                 #{reddemCode.createUser}, #{reddemCode.createTime}
16                 )
17             </foreach >
18      </insert >

6.如何获取自动生成的(主)键值?

在插入语句中,添加useGeneratedKeys属性,即可在插入元素后在POJO类中获取到生成的id。

7.Mybatis动态sql有什么用?执行原理?有哪些动态sql?

动态SQL是指在配置文件执行的过程中,通过特定的条件去判断需要执行的SQL,常用的动态SQL有以下9种: trim|where|set|foreach|if|choose|when|otherwise|bind

8.哪里体现了MyBatis是半自动ORM而Hibernate是全自动ORM

Hibernate可以通过POJO类之间的关系,在获取返回结果时全自动地根据对象关系封装数据,而MyBatis不可以根据对象关系封装多个POJO类。

三.进阶问题

1.MyBatis的一级缓存和二级缓存是什么

  1. 一级缓存的作用域是SqlSession对象,在使用完成后不对其进行销毁
  2. 二级缓存的作用域是配置文件中的SQL语句和对象映射关系。

2.MyBatis存在像Hibernate一样的懒加载吗

MyBatis在使一对一或一对多查询时,可以启用懒加载。所谓的懒加载,即一开始查询封装结果集时不进行完全的查询,而是当需要使用到的时候在进行查询和封装。

使用CGLIB动态代理,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。

3.MyBatis的执行过程

 

  1. 根据XML配置文件创建SqlSessionFactory
  2. SqlSessionFactory根据配置生成或获取一个SqlSession。
  3. 通过SqlSession来执行操作。
  4. 如果配置文件中存在mapper接口,通过SqlSession.getMapper(XXXMapper.class) 方法,MyBatis会根据相应的接口声明的方法信息,通过动态代理机制生成一个Mapper实例来执行SqlSession的操作。

所以大致的工作流程为: 1.读取xml配置文件 -> 生成SqlSessionFactory -> 2.通过Factory获取SqlSession -> 3.如果不存在mapper接口,则使用SqlSession执行操作 -> 4.若存在mapper接口,则sqlSession.getMapper方法,使用动态代理技术生成mapper的代理实例来完成SqlSession的操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值