MybatisMybatisPlus⾯试题
⽂章⽬录
1.MyBatis是什么?
MyBatis 是⼀款优秀的持久层框架,⼀个半 ORM(对象关系映射)框架,它⽀持定制化 SQL、存储过程以及⾼级映射。MyBatis 避免了⼏乎所有的 JDBC 代码和⼿动设置参数以及获取结果集。MyBatis 可以使⽤简单的 XML 或注解来配置和映射原⽣类型、接⼝和 Java 的POJO(Plain Old Java Objects,普通⽼式 Java 对象)为数据库中的记录。
2.ORM是什么
ORM(Object Relational Mapping),对象关系映射,是⼀种为了解决关系型数据库数据与简单Java对象(POJO)的映射关系的技术。简单的说,ORM是通过使⽤描述对象和数据库之间映射的元数据,将程序中的对象⾃动持久化到关系型数据库中。
3.为什么说Mybatis是半⾃动ORM映射⼯具?它与全⾃动的区别在哪⾥?
Hibernate属于全⾃动ORM映射⼯具,使⽤Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全⾃动的。
⽽Mybatis在查询关联对象或关联集合对象时,需要⼿动编写sql来完成,所以,称之为半⾃动ORM映射⼯具。
4.传统JDBC开发存在的问题
频繁创建数据库连接对象、释放,容易造成系统资源浪费,影响系统性能。可以使⽤连接池解决这个问题。但是使⽤jdbc需要⾃⼰实现连接池。
sql语句定义、参数设置、结果集处理存在硬编码。实际项⽬中sql语句变化的可能性较⼤,⼀旦发⽣变化,需要修改java代码,系统需要重新编译,重新发布。不好维护。
使⽤preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不⼀定,可能多也可能少,修改sql还要修改代码,系统不易维护。
结果集处理存在重复代码,处理⿇烦。如果可以映射成Java对象会⽐较⽅便。
5.JDBC编程有哪些不⾜之处,MyBatis是如何解决这些问题的?
1、数据库链接创建、释放频繁造成系统资源浪费从⽽影响系统性能,如果使⽤数据库连接池可解决此问题。
解决:在l中配置数据链接池,使⽤连接池管理数据库连接。
2、Sql语句写在代码中造成代码不易维护,实际应⽤sql变化的可能较⼤,sql变动需要改变java代码。
解决:将Sql语句配置在l⽂件中与java代码分离。
3、向sql语句传参数⿇烦,因为sql语句的where条件不⼀定,可能多也可能少,占位符需要和参数⼀⼀对应。
解决: Mybatis⾃动将java对象映射⾄sql语句。
4、对结果集解析⿇烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析⽐较⽅便。
解决:Mybatis⾃动将sql执⾏结果映射⾄java对象。
6.Hibernate 和 MyBatis 的区别
相同点
都是对jdbc的封装,都是持久层的框架,都⽤于dao层的开发。
不同点
映射关系
MyBatis 是⼀个半⾃动映射的框架,配置Java对象与sql语句执⾏结果的对应关系,多表关联关系配置简单
Hibernate 是⼀个全表映射的框架,配置Java对象与数据库表的对应关系,多表关联关系配置复杂
SQL优化和移植性
Hibernate 对SQL语句封装,提供了⽇志、缓存、级联(级联⽐ MyBatis 强⼤)等特性,此外还提供 HQL(Hibernate Query Language)操作数据库,数据库⽆关性⽀持好,但会多消耗性能。如果项⽬需要⽀持多种数据库,代码开发量少,但SQL语句优化困难。
MyBatis 需要⼿动编写 SQL,⽀持动态 SQL、处理列表、动态⽣成表名、⽀持存储过程。开发⼯作量相对⼤些。直接使⽤SQL语句操作数据库,不⽀持数据库⽆关性,但sql语句优化容易。
开发难易程度和学习成本
magnitude在仿真里是什么意思Hibernate 是重量级框架,学习使⽤门槛⾼,适合于需求相对稳定,中⼩型的项⽬,⽐如:办公⾃动化系统
MyBatis 是轻量级框架,学习使⽤门槛低,适合于需求变化频繁,⼤型的项⽬,⽐如:互联⽹电⼦商务系统
总结
MyBatis 是⼀个⼩巧、⽅便、⾼效、简单、直接、半⾃动化的持久层框架,
Hibernate 是⼀个强⼤、⽅便、⾼效、复杂、间接、全⾃动化的持久层框架。
7.MyBatis编程步骤是什么样的?
1、 创建SqlSessionFactory
2、 通过SqlSessionFactory创建SqlSession
3、 通过sqlsession执⾏数据库操作
4、 调⽤sessionmit()提交事务
mysql语句的执行顺序5、 调⽤session.close()关闭会话
8.请说说MyBatis的⼯作原理
MyBatis 的⼯作原理如下图
1)读取 MyBatis 配置⽂件:l 为 MyBatis 的全局配置⽂件,配置了 MyBatis 的运⾏环境等信息,例如数据库连接信息。
2)加载映射⽂件。映射⽂件即 SQL 映射⽂件,该⽂件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置⽂件 mybatis-
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 对结果集的解析过程。
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是否⽀持延迟加载?如果⽀持,它的实现原理是什么?
Mybatis仅⽀持association关联对象和collection关联集合对象的延迟加载,association指的就是⼀对⼀,collection指的就是⼀对多查询。在Mybatis配置⽂件中,可以配置是否启⽤延迟加载lazyLoadingEnabled=true|false。
它的原理是,使⽤CGLIB创建⽬标对象的代理对象,当调⽤⽬标⽅法时,进⼊⽅法,⽐如调⽤a.getB().getName(),invoke()⽅法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调⽤a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()⽅法的调⽤。这就是延迟加载的基本原理。
当然了,不光是Mybatis,⼏乎所有的包括Hibernate,⽀持延迟加载的原理都是⼀样的。createnewfile会覆盖文件吗
11.在mapper中如何传递多个参数
⽅法1:顺序传参法
public User selectUser(String name, int deptId);
<select id="selectUser" resultMap="UserResultMap">
select *from user
where user_name = #{0} and dept_id = #{1}
</select>
#{}⾥⾯的数字代表传⼊参数的顺序。
这种⽅法不建议使⽤,sql层表达不直观,且⼀旦顺序调整容易出错。
⽅法2:@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括号⾥⾯修饰的名称。
这种⽅法在参数不多的情况还是⽐较直观的,推荐使⽤。
⽅法3:Map传参法
public User selectUser(Map<String, Object> params);
<select id="selectUser" parameterType="java.util.Map" resultMap="UserResultMap">
select *from user
where user_name = #{userName} and dept_id = #{deptId}
</select>
#{}⾥⾯的名称对应的是Map⾥⾯的key名称。
这种⽅法适合传递多个参数,且参数易变能灵活传递的情况。
⽅法4:Java Bean传参法
手机oss是什么意思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>
javascript switch语句#{}⾥⾯的名称对应的是User类⾥⾯的成员属性。
这种⽅法直观,需要建⼀个实体类,扩展不容易,需要加属性,但代码可读性强,业务逻辑处理⽅便,推荐使⽤。
12.当实体类中的属性名和表中的字段名不⼀样,怎么办
第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种: 通过来映射字段名和实体类属性名的⼀⼀对应的关系。
<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>
13.使⽤MyBatis的mapper接⼝调⽤时有哪些要求?
1、Mapper接⼝⽅法名和l中定义的每个sql的id相同。
2、Mapper接⼝⽅法的输⼊参数类型和l中定义的每个sql 的parameterType的类型相同。
3、Mapper接⼝⽅法的输出参数类型和l中定义的每个sql的resultType的类型相同。
4、l⽂件中的namespace即是mapper接⼝的类路径。
14.简述Mybatis的Xml映射⽂件和Mybatis内部数据结构之间的映射关系?
答:Mybatis将所有Xml配置信息都封装到All-In-One重量级对象Configuration内部。在Xml映射⽂件中,标签会被解析为ParameterMap对象,其每个⼦元素会被解析为ParameterMapping对象。标签会被解析为ResultMap对象,其每个⼦元素会被解析为ResultMapping对象。每⼀个、、、标签均会被解析为MappedStatement对象,标签内的sql会被解析为BoundSql对象。
namespace+id是作为Map<String, MappedStatement>的key使⽤
15.MyBatis实现⼀对⼀,⼀对多有⼏种⽅式,怎么操作的?
indexof的用法不等于 1
有联合查询和嵌套查询。联合查询是⼏个表联合查询,只查询⼀次,通过在resultMap⾥⾯的association,collection节点配置⼀对⼀,⼀对多的类就可以完成
嵌套查询是先查⼀个表,根据这个表⾥⾯的结果的外键id,去再另外⼀个表⾥⾯查询数据,也是通过配置association,collection,但另外⼀个表的查询通过select节点配置。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论