1. 什么是 Mybatis?
- Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时只需要关注 SQL 语句本身,不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。程序员直接编写原生态 sql,可以严格控制 sql 执行性能,灵活度高
- MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO 映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
- 通过 xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回(从执行 sql 到返回 result 的过程)
2. Mybaits 的优点?
- 基于 SQL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL 写在 XML 里,解除 sql 与程序代码的耦合,便于统一管理;提供 XML 标签,支持编写动态 SQL 语句,并可重用
- 与 JDBC 相比,减少了50%以上的代码量,消除了 JDBC 大量冗余的代码,不需要手动开关连接
- 很好的与各种数据库兼容(因为 MyBatis 使用 JDBC 来连接数据库,所以只要 JDBC 支持的数据库 MyBatis 都支持)
- 能够与 Spring 很好的集成
- 提供映射标签,支持对象与数据库的 ORM 字段关系映射;提供对象关系映射标签,支持对象关系组件维护-
3. MyBatis 框架的缺点?
- SQL 语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写 SQL 语句的功底有一定要求
- SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库
4. MyBatis 框架适用场合?
MyBatis 专注于 SQL 本身,是一个足够灵活的 DAO 层解决方案
对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis 将是不错的选择
5. MyBatis 与 Hibernate 有哪些不同?
- Mybatis 和 hibernate 不同,它不完全是一个 ORM 框架,因为 MyBatis 需要程序员自己编写 Sql 语句
- Mybatis 直接编写原生态 sql,可以严格控制 sql 执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成果。但是灵活的前提是 mybatis 无法做到数据库无关性 ,如果需要实现支持多种数据库的软件,则需要自定义多套 sql 映射文件,工作量大
- Hibernate 对象/关系映射能力强, 数据库无关性好 ,对于关系模型要求高的软件,如果用 hibernate 开发可以节省很多代码,提高效率
6. MyBatis和其它持久化层技术对比
- JDBC
- SQL 夹杂在Java代码中耦合度高,导致硬编码内伤
- 维护不易且实际开发需求中 SQL 有变化,频繁修改的情况多见
- 代码冗长,开发效率低
- Hibernate 和 JPA
- 操作简便,开发效率高
- 程序中的长难复杂 SQL 需要绕过框架
- 内部自动生产的 SQL,不容易做特殊优化
- 基于全映射的全自动框架,大量字段的 POJO 进行部分映射时比较困难。
- 反射操作太多,导致数据库性能下降
- MyBatis
- 轻量级,性能出色
- SQL 和 Java 编码分开,功能边界清晰。Java代码专注业务、SQL语句专注数据
- 开发效率稍逊于HIbernate,但是完全能够接受
7. 谈谈MyBatis和JPA的区别
-
ORM映射不同:
MyBatis是半自动的ORM框架,提供数据库与结果集的映射;
JPA(默认采用Hibernate实现)是全自动的ORM框架,提供对象与数据库的映射。
-
可移植性不同:
JPA通过它强大的映射结构和HQL语言,大大降低了对象与数据库的耦合性;
MyBatis由于需要写SQL,因此与数据库的耦合性直接取决于SQL的写法,如果SQL不具备通用性而用了很多数据库的特性SQL的话,移植性就会降低很多,移植时成本很高。
-
SQL优化上的区别:
由于Mybatis的SQL都是写在XML里,因此优化SQL比Hibernate方便很多。
而Hibernate的SQL很多都是自动生成的,无法直接维护SQL。虽有HQL,但功能还是不及SQL强大,见到报表等复杂需求时HQL就无能为力,也就是说HQL是有局限的Hhibernate虽然也支持原生SQL,但开发模式上却与ORM不同,需要转换思维,因此使用上不是非常方便。 总之写SQL的灵活度上Hibernate不及Mybatis。
8. MyBatis输入输出支持的类型有哪些?
parameterType:
MyBatis支持多种输入输出类型,包括:
简单的类型,如整数、小数、字符串等;
集合类型,如Map等;
自定义的JavaBean。
其中,简单的类型,其数值直接映射到参数上。对于Map或JavaBean则将其属性按照名称映射到参数上。
9. MyBatis里如何实现一对多关联查询?
MyBatis 实现一对多有 联合查询 和 嵌套查询 。联合查询是几个表联合查询,只查询一次,通过在 resultMap 里面的 collection 节点配置一对多的类就可以完成;嵌套查询是先查一个表,根据这个表里面的结果的外键 id,去再另外一个表里面查询数据,也是通过配置 collection,但另外一个表的查询通过 select 节点配置。
一对多:例如:根据部门id查找部门以及部门中的员工信息
⚠️ 需要查询一对多、多对一的关系,需要在“一”的pojo中加入List<多>属性,在“多”的pojo中加入“一”。
⚠️ 也就是说,在Dept类中,要加入 private List<Emp> emps;
;在Emp类中,要加入 private Dept dept;
。然后给他们各自添加get、set方法,重写构造器和toString()
public class Dept {
private Integer did;
private String deptName;
private List<Emp> emps;
//...构造器、get、set方法等
}
方法1:collection(联合查询)
DeptMapper接口
public interface DeptMapper {
/**
* 获取部门以及部门中所有的员工信息
*/
Dept getDeptAndEmp(@Param("did") Integer did);
}
DeptMapper.xml
<resultMap id="deptAndEmpResultMap" type="Dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
<!--
collection:处理一对多的映射关系
ofType:表示该属性对应的集合中存储数据的类型
-->
<collection property="emps" ofType="Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
</collection>
</resultMap>
<!-- Dept getDeptAndEmp(@Param("did") Integer did);-->
<select id="getDeptAndEmp" resultMap="deptAndEmpResultMap">
select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did} </select>
方法2: 分步查询(嵌套查询)
(1)查询部门信息
DeptMapper接口
public interface DeptMapper {
/**
* 分步查询 查询部门及其所有的员工信息
* 第一步 查询部门信息
*/
Dept getDeptAndEmoByStepOne(@Param("did") Integer did);
}
DeptMapper.xml
<!-- 分步查询-->
<resultMap id="deptAndEmoByStepOneMap" type="Dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
<collection property="emps"
select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"
column="did">
</collection>
</resultMap>
<!-- Dept getDeptAn