1.JDBC 有几个步骤?

JDBC 大致可以分为六个步骤:

  1. 加载驱动程序

  2. 获得数据库连接

  3. 创建一个 Statement 对象

  4. 操作数据库,实现增删改查

  5. 获取结果集

  6. 关闭资源

2.什么是 Mybatis?

如果在面试的时候被问到,只要你说出下面三种即可:

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。

MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。

MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

——来自官网。推荐大家按照官方的来回答。

3.什么是 ORM?

全称为 Object Relational Mapping。对象-映射-关系型数据库。对象关系映射(简称 ORM,或 O/RM,或 O/R mapping),用于实现面向对象编程语言里不同类型系统的数据之间的转换。简单的说,ORM 是通过使用描述对象和数据库之间映射的元数据,将程序中的对象与关系数据库相互映射。

ORM 提供了实现持久化层的另一种模式,它采用映射元数据来描述对象关系的映射,使得 ORM 中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁。

4.说说 ORM 的优缺点

「优点」1.提高了开发效率。由于 ORM 可以自动对 Entity 对象与数据库中的 Table 进行字段与属性的映射,所以我们实际可能已经不需要一个专用的、庞大的数据访问层。2.ORM 提供了对数据库的映射,不用 sql 直接编码,能够像操作对象一样从数据库获取数据。

「缺点」牺牲程序的执行效率和会固定思维模式,降低了开发的灵活性。

从系统结构上来看,采用 ORM 的系统一般都是多层系统,系统的层次多了,效率就会降低。ORM 是一种完全的面向对象的做法,而面向对象的做法也会对性能产生一定的影响。

在我们开发系统时,一般都有性能问题。性能问题主要产生在算法不正确和与数据库不正确的使用上。

ORM 所生成的代码一般不太可能写出很高效的算法,在数据库应用上更有可能会被误用,主要体现在对持久对象的提取和和数据的加工处理上,如果用上了 ORM,程序员很有可能将全部的数据提取到内存对象中,然后再进行过滤和加工处理,这样就容易产生性能问题。

在对对象做持久化时,ORM 一般会持久化所有的属性,有时,这是不希望的。但 ORM 是一种工具,工具确实能解决一些重复,简单的劳动。这是不可否认的。但我们不能指望工具能一劳永逸的解决所有问题,有些问题还是需要特殊处理的,但需要特殊处理的部分对绝大多数的系统,应该是很少的。

5.说说 Mybaits 的优缺点

优点

① 基于 SQL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL 写在 XML 里,解除 sql 与程序代码的耦合,便于统一管理;提供 XML 标签,支持编写动态 SQL 语句,并可重用。

② 与 JDBC 相比,减少了 50%以上的代码量,消除了 JDBC 大量冗余的代码,不需要手动开关连接;

③ 很好的与各种数据库兼容(因为 MyBatis 使用 JDBC 来连接数据库,所以只要 JDBC 支持的数据库 MyBatis 都支持)。

④ 能够与 Spring 很好的集成;

⑤ 提供映射标签,支持对象与数据库的 ORM 字段关系映射;提供对象关系映射标签,支持对象关系组件维护。

缺点

① SQL 语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写 SQL 语句的功底有一定要求。

② SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

MyBatis 框架适用场合:

(1)MyBatis 专注于 SQL 本身,是一个足够灵活的 DAO 层解决方案。

(2)对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis 将是不错的选择。

6.Mybatis 是如何进行分页的?

Mybatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页,先把数据都查出来,然后再做分页。

可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

7.分页插件的基本原理是什么?

分页插件的基本原理是使用 Mybatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql(SQL 拼接 limit),根据 dialect 方言,添加对应的物理分页语句和物理分页参数,用到了技术 JDK 动态代理,用到了责任链设计模式。

8.简述 Mybatis 的插件运行原理?

Mybatis 仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler、Executor 这 4 种接口的插件,Mybatis 使用 JDK 的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是 InvocationHandler 的 invoke()方法,当然,只会拦截那些你指定需要拦截的方法。

9.如何编写一个插件?


编写插件:实现 Mybatis 的 Interceptor 接口并复写 intercept()方法,然后再给插件编写注解,指定要拦截哪一个接口的哪些方法即可,最后在配置文件中配置你编写的插件。

10.Mybatis 动态 sql 有什么用?

Mybatis 动态 sql 可以在 Xml 映射文件内,以标签的形式编写动态 sql,执行原理是根据表达式的值完成逻辑判断 并动态调整 sql 的功能。

Mybatis 提供了 9 种动态 sql 标签:trim | where | set | foreach | if | choose | when | otherwise | bind

11.Xml 映射文件中有哪些标签?

除了常见的 select|insert|updae|delete 标签之外,还有:

<resultMap><parameterMap><sql><include><selectKey>,加上动态 sql 的 9 个标签,其中<sql>为 sql 片段标签,通过<include>标签引入 sql 片段,<selectKey>为不支持自增的主键生成策略标签。

12.Mybatis 是否支持延迟加载?

Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association 指的就是一对一,collection 指的就是一对多查询。在 Mybatis 配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false

13.延迟加载的基本原理是什么?

延迟加载的基本原理是,使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法。

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

当然了,不光是 Mybatis,几乎所有的包括 Hibernate,支持延迟加载的原理都是一样的。

14.mapper.xml 文件对应的 Dao 接口原理是?

简单说:使用了 JDK 动态代理和反射,把接口和 xml 绑定在一起而搞定的。

15.Dao 接口里的方法,参数不同时能重载吗?

不能重载。

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

${}是字符串替换,#{}是预处理;

Mybatis 在处理时,就是把{}直接替换成变量的值。而 Mybatis 在处理 #{}时,会对 sql 语句进行预处理,将 sql 中的 #{}替换为?号,调用 PreparedStatement 的 set 方法来赋值;

使用 #{}可以有效的防止 SQL 注入,提高系统安全性。

17.Mybatis 执行批量插入,能返回数据库主键列表吗?

1、对于支持生成自增主键的数据库:增加 useGenerateKeys 和 keyProperty ,<insert>标签属性。

2、不支持生成自增主键的数据库:使用<selectKey>

方式:

<insert id="insertAuthor" useGeneratedKeys="true"    keyProperty="id">  insert into Author (username, password, email, bio) values  <foreach item="item" collection="list" separator=",">    (#{item.username}, #{item.password}, #{item.email}, #{item.bio})  </foreach></insert>

注意 Mybatis 的版本,官方在这个 3.3.1 版本中加入了批量新增返回主键 id 的功能 。

18.不同的 Xml 映射文件,id 是否可以重复?

不同的 Xml 映射文件,如果配置了 namespace,那么 id 可以重复;如果没有配置 namespace,那么 id 不能重复;毕竟 namespace 不是必须的,只是最佳实践而已。

原因就是 namespace+id 是作为 Map<String, MappedStatement>的 key 使用的,如果没有 namespace,就剩下 id,那么,id 重复会导致数据互相覆盖。有了 namespace,自然 id 就可以重复,namespace 不同,namespace+id 自然也就不同。

19.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 生命周期范围内。

20.为什么说 Mybatis 是半自动 ORM 映射工具?

Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。

而 Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。

(2)Mybatis 直接编写原生态 sql,可以严格控制 sql 执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成果。但是灵活的前提是 mybatis 无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套 sql 映射文件,工作量大。

(3)Hibernate 对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用 hibernate 开发可以节省很多代码,提高效率。

其实关于常见 ORM 框架还设有 Spring 的 JPA,后期的面试可能会更倾向于问 JPA 和 Mybatis 的区别了。希望大家留意点。

21.Mybatis 全局配置文件中有哪些标签?

configuration 配置

properties 属性:可以加载

properties 配置文件的信息

settings 设置:可以设置 mybatis 的全局属性

typeAliases 类型命名

typeHandlers 类型处理器

objectFactory 对象工厂

plugins 插件

environments 环境

environment 环境变量

transactionManager 事务管理器

dataSource 数据源

mappers 映射器

22.当实体类中的属性名和表中的字段名不一样时怎么办 ?

第 1 种:通过在查询的 sql 语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。

<select id="selectById" resultMap="User">        select id, name as userName, pwd as password from m_user        <where>            <if test="id != null">                id = #{id}            </if>        </where>    </select>

第 2 种:通过<resultMap>来映射字段名和实体类属性名的一一对应的关系。

第 3 种:使用注解时候,使用 Result,和第二种类似。

23.模糊查询 like 语句该怎么写?

第 1 种:在 Java 代码中添加 sql 通配符。

String wildcardname = “%smi%”;list<name> names = mapper.selectlike(wildcardname);

<select id=”selectlike”>select * from foo where bar like #{value}</select>

第 2 种:在 sql 语句中拼接通配符,会引起 sql 注入

String wildcardname = “smi”;list<name> names = mapper.selectlike(wildcardname);

<select id=”selectlike”>select * from foo where bar like "%"#{value}"%"</select>

24.Mybatis 构建步骤?

整体步骤:

图片

25.简述一下 Mybatis 的手动编程步骤?

  1. 创建 SqlSessionFactory

  2. 通过 SqlSessionFactory 创建 SqlSession

  3. 通过 sqlsession 执行数据库操作

  4. 调用 sessionmit()提交事务

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

25.Mybatis 工作的流程是?

Mybatis 工作流程可以大致分为四个步骤:

如果本文对你有帮助,别忘记给我个3连 ,点赞,转发,评论,
,咱们下期见。
收藏 等于白嫖,点赞才是真情。

 

更多推荐

25 道 mybatis 面试题,不要说你不会