Mybatis 面试常问问题总结(附答案)

作者阿里云代理 文章分类 分类:linux图文教程 阅读次数 已被围观 344


Hibernate 简介

什么是 Hibernate?

Hibernate 是一种 ORM(Object Relational Mapping) 结构,用于在 Java 目标和联系数据库之间建立某种映射,然后完成 Java 目标存取;


Hibernate 优缺陷

长处

Hibernate 建立在 POJO 和数据库表模型的直接映射联系之上。经过 XML 或者注解就能和数据库表进行映射。经过 POJO 直接就能操作数据库中的数据,提供的是关于全表的映射模型。首要有如下长处:


消除了代码映射规矩,被别离到 XML 或注解中装备;

装备在 XML 中后,无需再办理数据库连接;

一个会话中,不必操作多个目标,只需操作 Session 目标即可;

关闭资源只需关闭 Session;

缺陷

由于是全表映射,所以某些操作不便利,比如更新需求发送一切字段;

无法依据不同条件拼装不同的 SQL;

对多表相关和杂乱 SQL 查询支撑较差,需求自己写 SQL,回来后还需求自己将数据组成 POJO;

不能有效支撑存储进程;

MyBatis 简介

什么是 MyBatis?

MyBatis 一款支撑自界说 SQL 查询、存储进程和高级映射的耐久层结构,消除了几乎一切 JDBC 代码和参数的手动装备以及成果集的检索。只需求运用 XML 或注解进行装备和映射,MyBatis 就能将参数映射到装备的 SQL 形成最终履行的 SQL 句子,最终将履行 SQL 的成果映射为 Java 目标回来;


MyBatis 优缺陷

长处

细巧,学习成本低,会写 SQL 句子就能很快上手;

无需过多装备 JDBC,首要专注 SQL 开发;

便利保护办理,SQL 不必在 Java 代码中找,SQL 代码能够别离重用;

灵敏,支撑动态 SQL;

支撑目标与数据库 ORM 字段联系映射;

缺陷

首要作业集中在 SQL 开发,所以对 SQL 熟练度要求较高;

移植性查,SQL 依赖于数据库,切换不同数据库会因语法差异而报错;

MyBatis 和 Hibernate 的差异

相同点

均是对 JDBC 的封装,都是耐久层的结构,用于 Dao 层的开发;


不同点

映射联系 SQL优化和移植性 开发难易程度和学习成本

Hibernate 全主动映射,装备 Java 目标与数据库表的对应联系,多表相相联系装备杂乱 对 SQL 句子封装,提供了日志、缓冲、级联等特性,此外还提供 HQL 操作数据库,数据库无联系支撑好,但会多耗费功能 重量级,门槛高,合适需求安稳、中小型项目

MyBatis 半主动映射,装备 Java 目标与 SQL 句子履行成果的对应联系,多表相相联系装备简略 需求手动编写 SQL,支撑动态 SQL、处理列表、动态生成表名、支撑存储进程;开发作业量相对较大,直接运用 SQL 句子操作数据库,不支撑数据库无关性,但 SQL 句子优化容易 轻量级,门槛低,合适需求变化频频、大型项目

Hibernate 归于全主动的 ORM 映射东西,运用 Hibernate 查询相关目标或相关调集目标时,能依据目标联系模型直接获取,所以说它是全主动的;


而 MyBatis 归于半主动 ORM 映射东西,由于在查询相关目标或相关调集目标时,需求自己手动编写 SQL 来完成;


解析和运转原理

MyBatis 核心组件

结构器:SqlSessionFactoryBuilder,依据装备信息或点来生成 SqlSessionFactory;

工厂接口:SqlSessionFactory,依靠工厂来生成 SqlSession;

会话:SqlSession,是一个既能够发送 SQL 去履行回来成果,也能够获取 Mapper 接口;

SQL Mapper:新规划的组件,由一个 Java 接口和 XML 文件(或注解)构成,需求给出目标的 SQL 和映射规矩。担任发送 SQL 去履行,并回来成果;

MyBatis 编程进程

创立 SqlSessionFactory;

经过 SqlSessionFactory 创立 SqlSession;

经过 SqlSession 履行数据库操作;

调用 session.commit() 提交业务;

调用 session.close() 关闭会话;

MyBatis 作业原理


image.png首先读取 MyBatis 装备文件:mybatis-config.xml,它是 MyBatis 的大局装备文件,装备了 MyBatis 的运转环境等信息;

接着加载映射文件,即 SQL 映射文件,其中装备了操作数据库的 SQL 句子,需求在 MyBatis 装备文件 mybatis-config.xml 中加载。它能够加载多个映射文件,每个文件对应数据表中的一张表;

结构会话工厂,经过 mybatis 的环境等装备信息构建会话工厂 SqlSessionFactory;

创立会话目标,由会话工厂创立 SqlSession 目标,该目标包括履行 SQL 句子的一切办法;

Executor 履行器,MyBatis 底层界说了一个 Executor 接口来操作数据库,它依据 SqlSession 传递的参数动态生成所需履行的 SQL 句子,一起担任查询缓存的保护;

MappedStatement 目标,在 Executor 接口的履行办法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 句子的 id,参数等信息;

输入参数映射,输入参数类型能够是 Map、List 等调集类型,也能够是根本数据类型和 POJO 类型,此进程类似于 JDBC 对 preparedStatement 目标设置参数的进程;

输出成果映射,输出成果类型能够是 Map、List 等调集类型,也能够是根本数据类型和 POJO 类型,此进程类似于 JDBC 对成果集的解析进程;

映射器

${} 和 #{} 的差异

${} 是拼接符,字符串替换,无预编译处理;#{} 是占位符,预编译处理;

处理 #{} 时,传入参数以 字符串传入,会将 SQL 中的 #{} 替换为 ? ,调用 PreparedStatement 中的 set 办法来赋值;

处理 ${} 时,是 原值传入,会将 ${} 替换为变量的值,相当于 JDBC 中的 Statement 编译;

变量替换后 ,#{} 对应变量主动加上单引号 ‘’,而 ${} 对应变量不会加单引号 ‘’;

#{} 能有效避免 SQL 注入,提高体系安全性,原因在于 预编译机制,预编译完成后,SQL 的结构现已固定,即运用户输入不合法参数,也不会对 SQL 结构产生影响,然后避免潜在的安全危险;但 ${} 不能避免 SQL 注入;

#{} 的变量替换是在 DBMS 中;${} 的变量替换是在 DBMS 外;

预编译界说:预编译是提早对 SQL 句子进行编译,然后注入的参数不会再进行 SQL 编译;而一般 SQL 注入是产生在编译进程中,由于歹意注入了某些特殊字符,最终被编译为了歹意的履行操作,而预编译机制则能很好的避免 SQL 注入;


SQL 注入界说:Sql 注入进犯是经过将歹意的 Sql 查询或增加句子刺进到运用的输入参数中,再在后台 Sql 服务器上解析履行进行的进犯;首要有 广泛性、隐蔽性、危害大、操作便利 等特点;


含糊查询 like

'%{question}%' 或许引起 SQL 注入,不引荐运用;

"%{question}%",由于 #{} 在解析时会在最外侧主动加单引号,所以外层需求运用双引号,不能运用单引号,否则将查询不到任何成果;

CONCAT('%', #{question}, '%'),运用 CONCAT() 函数,引荐运用;

运用 bind 标签;

   SELECT id, sex, age, username, password from persion where username LIKE #{pattern}


mapper 中怎么传递多个参数

次序传参

#{} 中的数字代表传入参数的次序,不引荐运用,由于 SQL 层表达不直观,并且一旦次序跳转则容易出错;


public User selectUser(String name, int id);


   SELECT * FROM user WHERE user_name = #{0} and id = #{1}


@Param 注解传参

#{} 中的称号对应注解 @Param 括号中修饰的称号,是愈加引荐的一种方式;


public User selectUser(@Param("name") String name, @Param("id") int id);


   SELECT * FROM user WHERE user_name = #{name} and id = #{id}

Map 传参

#{} 中的称号对应的是 Map 中的 key 称号,合适传递多个参数,且参数易变且能灵敏传递的状况;


public User selectUser(Map params);


   SELECT * FROM user WHERE user_name = #{name} and id = #{id}


Java Bean 传参

#{} 中称号对应的是类中的成员特点,经过这种办法愈加直观,代码可读性强、业务逻辑处理便利;


public User selectUser(User user);


   SELECT * FROM user WHERE user_name = #{name} and id = #{id}


MyBatis 批量操作

运用 foreach 标签

foreach 首要用于构建 in 条件中,能够在 SQL 句子中进行迭代一个调集。foreach 标签的特点首要有 item、index、collection、open、separator、close;


标签 阐明

item 表明调集中每个元素进行迭代时的别号,随意取的变量名

index 指定一个名字,用于表明在迭代进程中,每次迭代到的方位

collection 必须指定,但在不同状况下的值不一样:

1. 若传入单参数且参数类型是 List,则其特点值为 list

2. 若传入单参数且参数类型是一个数组,则其特点置为 array

3. 若传入参数是多个时,需求将其封装为一个 Map

open 表明该句子以什么开端,常用 (

separator 表明在每次进行迭代之间以何种符号作为分隔符,常用 ,

close 表明该句子以什么完毕,常用 )

运用 ExecutorType.BATCH

MyBatis 内置的 ExecutorType 有 3 种,默认为 simple,此时它为每个句子的履行创立了一个新的预处理句子,单挑提交 SQL;而 batch 形式重复运用已预处理的句子,且批量履行一切更新数据,其功能比 batch 更优;


MyBatis 分页及原理

MyBatis 内部是经过 RowBounds 目标进行分页,它是针对 ResultSet 成果集履行的内存分页,而非物理分页,能够直接编写带物理分页的参数的 SQL 完成分页,也能够 MyBatis 的分页插件 Page-Helper;


分页插件的根本原理: 运用 MyBatis 所提供的插件接口,完成自界说插件,在插件的阻拦办法内阻拦待履行的 SQL,然后重写 SQL,依据 dialect 方言,增加对应物理分页句子和物理分页参数;


 

本公司销售:阿里云、腾讯云、百度云、天翼云、金山大米云、金山企业云盘!可签订合同,开具发票。

我有话说: