mybatis的面试题
- 1、什么是mybatis?
- 2、mybatis的优势
- 3、mybatis的缺点
- 4、Hibernate 和 MyBatis 的区别
- 5、#和 $的区别是什么?
- 6、当实体类中的属性名和表中的字段名不一样·怎么办?
- 7、模糊查询 like 语词该怎么写?
- 8、通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原理是什么?
- 9、mybatis是如果分页的,分页插件的原理是什么
- 10、Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
- 11、如何执行批里插入?
- 12、如何获取自动生成的(主)键值?14、在 mapper 中如何传递多个参数?
- 13、Mybatis 动态 sql 有什么用?有哪些动态 sql?
- 14、mybatis的一级缓存、二级缓存
1、什么是mybatis?
mybatis是一款用于持久层的、轻量级的半自动化ORM框架,封装了所有jdbc操作以及设置查询参数和获取结果集的操作,支持自定义sql、存储过程和高级映射。
2、mybatis的优势
- 相对jdbc,可以直接在mybatis-config.xml文件中配置数据库连接池
- 相对jdbc,在编写SQL的时候,更加的便捷,不需要再代码里面写硬代码,后期修改更加的方便。
- 相对jdbc的SQL语句,where条件后的参数需要使用占位符替代,而且存在部分条件不存在的情况,导致SQL有变化,需要写很多Java代码来实现,mybatis可以自动将Java对象映射到SQL上。
- SQL写在xml中,让SQL和Java代码进行了解耦,便于管理
- 提供了xml标签,支持编写动态SQL,且可重用。
- 提供了映射标签,支持对象和数据库的ORM字段映射
- 提供对象关系映射标签,支持对象关系组维护
3、mybatis的缺点
- SQL的编写工程比较大,考验开发人员的SQL编写能力
- SQL语句依赖数据库,导致数据库的可移植性比较差
4、Hibernate 和 MyBatis 的区别
-
映射关系
- mybatis是半自动映射框架,配置Java对象和SQL语句的执行的结果的对应关系,多表关联关系配置简单
- HIbernate是一个全表映射的框架,配置Java对象与数据库表的映射关系,多表关联关系配置复杂。
-
SQL优化和可移植性
- Hibernate 对 SQL 语句封装,提供了日志、缓存、级联(级联比 MyBatis 强大)等特性,此外还提供 HQL(Hibernate Query Language)操作数据库,数据库无关性支持好,但会多消耗性能。如果项目需要支持多种数据库,代码开发量少,但 SQL 语句优化困难。
- MyBatis 需要手动编写 SQL,支持动态 SQL、处理列表、动态生成表名、支持存储过程。
开发工作量相对大些。直接使用 SQL 语句操作数据库,不支持数据库无关性,但 sql 语句
优化容易。
-
开发难易程度和学习成本
- Hibernate 是重量级框架,学习使用门槛高,适合于需求相对稳定,中小型的项目,比如:
办公自动化系统。 - MyBatis 是轻量级框架,学习使用门槛低,适合于需求变化频繁,大型的项目,比如:互
联网电子商务系统。
- Hibernate 是重量级框架,学习使用门槛高,适合于需求相对稳定,中小型的项目,比如:
5、#和 $的区别是什么?
- 相同点
- 都能获取到变量的值
- 不同点
- #{}是同过预编译的方式,先在SQL中使用?来占位,再去替换成参数,这样就可以预防SQL注入的问题
- ${}是直接将字符串替换掉
6、当实体类中的属性名和表中的字段名不一样·怎么办?
- 在SQL中,通过别名的方式来和实体类对应
- 使用xml中的resultmap中的result标签,将实体类中的属性名和表中字段名映射
7、模糊查询 like 语词该怎么写?
- like concat(‘%’,#{},‘%’)
- like ‘%${question}%’
- NAME like ‘%’|| #{name} || ‘%’
8、通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原理是什么?
- dao层的接口名称会被映射到mapper.xml中的namespace标签上,接口的方法名称,就是mapper中的statement的ID,接口内的方法参数,就是传递给SQL的参数。mapper接口没有实现类,当调用接口时,接口名称+方法名称会拼接成一个key,可以唯一定位到一个mapperstatement,在mybatis中,每一个标签都会被生成一个mapperstatement对象,然后mybatis在运行时,会使用jdk的动态代理为mapper接口代理生成对象proxy,代理对象会拦截接口方法,转而执行mapperstatement中的SQL,然后将执行SQL的结果返回。
9、mybatis是如果分页的,分页插件的原理是什么
- mybatis使用RowBounds对象进行分页,他是针对reslitset结果集执行的内存分页,而非物理分页。可以直接在SQL内直接拼接分页参数,实现物理分页,也可以使用分页插件来实现物理分页。
- 分页插件原理是,使用mybatis提供的插件接口,在插件拦截方法中拦截SQL,重写SQL,添加对应的物理分页语句和分页参数来实现分页。
10、Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
- 第一种,使用标签,将对象名和数据库表字段名一一映射
- 通过SQL的别名来映射
- 然后mybatis通过放射来创建对象,再通过反射来给对象的属性赋值,找不到映射对象的就不能完成赋值。
11、如何执行批里插入?
- 使用 foreach标签
- 在代码中循环调用插入方法
12、如何获取自动生成的(主)键值?14、在 mapper 中如何传递多个参数?
- 在标签中,使用useGeneratedKeys = true,表示开启自动生成主键值,keyProperty = ‘ID’,表示指定属性值返回到哪一个字段中。
<insert id="save" parameterType="com.platform.entity.AdEntity" useGeneratedKeys="true" keyProperty="id">
- 使用元素的order属性:可以通过order属性来指定获取主键值的顺序
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
<selectKey keyProperty="id" order="AFTER" resultType="int">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO user (username, password) VALUES (#{username}, #{password})
</insert>
在上面的例子中,order属性设置为AFTER表示在插入语句执行后获取主键值。
- 使用元素的statementType属性:可以通过statementType属性来指定获取主键值的方式
<insert id="insertUser" parameterType="User">
<selectKey keyProperty="id" statementType="PREPARED" resultType="int">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO user (username, password) VALUES (#{username}, #{password})
</insert>
13、Mybatis 动态 sql 有什么用?有哪些动态 sql?
mybatis动态SQL有什么用:
- 动态SQL就是动态的根据属性值来拼接数据库执行的SQL语句,也就是多次查询或者变更操作会依据传递的参数不同,而导致生成的SQL语句不通
mybatis动态SQL有哪些?
- 标签:判断传入的参数是否符合某种规则
- 标签:where标签可以配合if标签使用,动态条件,不用再写where 1=1
- 标签:适用于更新中,当匹配某个条件后,才会对该字段进行更新操作
- :标签:循环插入操作
14、mybatis的一级缓存、二级缓存
- 一级缓存:一级缓存的作用域是同一个SQLsession,同一个SQLsession两次查询相同的SQL,第一次执行完毕后,会将数据直接放到缓存中,第二次查询,就直接从缓存中取,而不到数据库中取,大大提高了效率,当一个SQLsession结束后,他的一级缓存也就结束了
- 二级缓存是多个SQLsession共享,其作用域是mapper的同一个namespace,不同的SQLsession,两次执行同一个namespace下的SQL语句,且向SQL中传递的参数一致,第一次查询完,直接将结果写到缓存中,第二次直接去缓存中取。默认不开启二级缓存