mybatis面试题

原文

根据上面博客手敲了一些面试题,加强自己理解

mybatis面试题

1.mybaits是什么?

mybatis是一款优秀的持久层框架,一个半ORM(对象关系映射)框架。它支持定制化SQL、存储过程以及高级映射。mybatis
几乎避免了所有的jdbc代码和手动的配置参数以及获取结果集。mybatis可以使用简单的XML或者注解来配置和映射原生类型、接口、和Java的POJO(普通老式java对象)为数据库中的记录。

2.ORM是什么?
ORM(Object Relational Mapping) ,对象关系映射,是一种为了解决关系型数据库与POJO的映射关系的技术。及ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对像自动持久化到关系型数据库中。

3.为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?
Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象时,可以根据对象关系模型直接获取,所以是全自动的;
Mybatis在查询关联对象时,需要手动编写sql来完成,及为半ORM框架。

4.传统JDBC开发存在的问题
1.频繁的创建数据库连接对象、释放,容易造成系统资源的浪费,影响性能。
2.结果集处理存在重复代码,处理麻烦、
3.。。。

5.JDBC的不足之处,Mybatis时如何解决的
在mybaits-config.xml中配置数据连接池,使用连接池来管理数据库连接。
将SQL语句配置在XXXMapper.xml文件中与java代码分离。
Mybatis自动将Java对象映射至sql语句。
Mybatis自动将SQL执行结果映射至Java对象。

Mybatis的解析和运行原理。

6.Mybaits的编程步骤是怎样的?
1.创建SqlSessionFactory
2.通过SqlSessionFactory创建SqlSession
3.通过SqlSession执行数据库操作
4.调用session.commit()提交事务
5.调用session.close()关闭会话

7.说说Mybatis的工作原理。
Mybatis的工作原理如图所示:
在这里插入图片描述
1)读取 MyBatis 配置文件:mybatis-config.xml 为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息,例如数据库连接信息。

2)加载映射文件。映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置文件 mybatis-config.xml 中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。

3)构造会话工厂:通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。

4)创建会话对象:由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。

5)Executor 执行器:MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。

6)MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。

7)输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。

8)输出结果映射:输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。

8.为什么需要预编译?

定义:SQL预编译是指数据库驱动在发送SQL语句和参数给DBMS之前堆SQL语句进行预编译,这样DBMS在执行SQL语句的时候,就不需要重新编译。
为什么要预编译?
JDBC 中使用对象 PreparedStatement 来抽象预编译语句,使用预编译。预编译阶段可以优化 SQL 的执行。预编译之后的 SQL 多数情况下可以直接执行,DBMS 不需要再次编译,越复杂的SQL,编译的复杂度将越大,预编译阶段可以合并多次操作为一个操作。同时预编译语句对象可以重复利用。把一个 SQL 预编译后产生的 PreparedStatement 对象缓存下来,下次对于同一个SQL,可以直接使用这个缓存的 PreparedState 对象。Mybatis默认情况下,将对所有的 SQL 进行预编译。

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

.映射器
10. #{}和${}的区别?

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

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

    Mybatis在处理时,是原值传入,就是把时,是原值传入,就是把{}替换成变量的值,相当于JDBC中的Statement编译

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

    #{} 可以有效的防止SQL注入,提高系统安全性;${} 不能防止SQL 注入

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

11.模糊查询like怎么写?

(1)’%${question}%’ 可能引起SQL注入,不推荐

(2)"%"#{question}"%" 注意:因为#{…}解析成sql语句时候,会在变量外侧自动加单引号’ ',所以这里 % 需要使用双引号" ",不能使用单引号 ’ ',不然会查不到任何结果。

(3)CONCAT(’%’,#{question},’%’) 使用CONCAT()函数,推荐

(4)使用bind标签


```java
<select id="listUserLikeUsername" resultType="com.jourwon.pojo.User">
  <bind name="pattern" value="'%' + username + '%'" />
  select id,sex,age,username,password from person where username LIKE #{pattern}
</select>


12.mapper中如何传递多个参数?
1.使用@Param注解传参法。

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

<select id="selectUser" resultMap="UserResultMap">
    select * from user
    where user_name = #{userName} and dept_id = #{deptId}
</select>

```#{}里面的名称对应的是注解@Param括号里面修饰的名称
2.使用JavaBean传参法。

```java
public User selectUser(User user);

<select id="selectUser" parameterType="com.jourwon.pojo.User" resultMap="UserResultMap">
    select * from user
    where user_name = #{userName} and dept_id = #{deptId}
</select>

#{}里面的名称对应的是User类里面的成员属性。

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

 1.通过在查询的SQL语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
<select id="getOrder" parameterType="int" resultType="com.jourwon.pojo.Order">
       select order_id id, order_no orderno ,order_price price form orders where order_id=#{id};
</select>

2.使用<resultMap>来映射字段名和实体类属性名一一对应。
<select id="getOrder" parameterType="int" resultMap="orderResultMap">
	select * from orders where order_id=#{id}
</select>

<resultMap type="com.jourwon.pojo.Order" id="orderResultMap">
    <!–用id属性来映射主键字段–>
    <id property="id" column="order_id">

    <!–用result属性来映射非主键字段,property为实体类属性名,column为数据库表中的属性–>
    <result property ="orderno" column ="order_no"/>
    <result property="price" column="order_price" />
</reslutMap>

14.Mybatis的一级缓存和二级缓存

1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。

2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置 ;

3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。

更新中。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值