Java面试——MyBatis系列总结

文章目录:

1.MyBatis是什么?

2.JDBC编程有哪些缺陷?MyBatis又是如何改进的?

3.MyBatis与Hibernate的区别在哪?

4.MyBatis的优缺点

5.请说说MyBatis的工作原理

6.MyBatis的架构设计是怎样的?

7.#{}和${}的区别

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

9.如何获取生成的主键?

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

11.什么是MyBatis的接口绑定?有哪些实现方式?

12.使用MyBatis的mapper接口调用时有哪些要求?

13.最佳实践中,通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗

14.MyBatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?

15.MyBatis的一级、二级缓存是什么?


1.MyBatis是什么?

MyBatis是一款优秀的dao持久层框架、一个半ORM(对象关系映射)框架。它支持定制化SQL、存储过程、高级映射、缓存机制,同时MyBatis几乎避免了JDBC代码中手动设置参数以及获取结果集等繁杂操作的过程。

2.JDBC编程有哪些缺陷?MyBatis又是如何改进的?

  • JDBC编程中频繁创建、释放数据库连接对象,容易造成系统资源浪费,影响系统性能。可以使用连接池解决这个问题。

​ 解决:在mybatis-config.xml中配置数据库连接池,使用连接池管理数据库连接。

  • JDBC编程中 sql 语句写在代码中造成代码不易维护,实际应用场景中sql的变化可能较大,sql变动需要改变java代码。

​ 解决:将SQL语句配置在XXXXmapper.xml映射文件中,与java代码分离。

  • JDBC编程中向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。

​ 解决:Mybatis中自动将java对象映射至sql语句。

  • JDBC编程中对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。

​ 解决:Mybatis中自动将sql执行结果映射至java对象。

3.MyBatis与Hibernate的区别在哪?

首先要提到一个词ORM。ORM(Object Relational Mapping)对象关系映射,是一种为了解决关系型数据库数据与简单Java对象(POJO)的映射关系的技术。

相同点:

  • 都是对jdbc的封装,都是持久层的框架,都用于dao层的开发。

不同点:

  • Hibernate是全自动ORM映射工具,Hibernate 对SQL语句封装,提供了日志、缓存、级联(级联比 MyBatis 强大)等特性,此外还提供 HQL(Hibernate Query Language)操作数据库,数据库无关性支持好,但会多消耗性能。使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
  • MyBatis 在查询关联对象或关联集合对象时,需要手动编写 SQL,支持动态 SQL、处理列表、动态生成表名、支持存储过程。所以,称之为半自动ORM映射工具。

4.MyBatis的优缺点

优点

与传统的数据库访问技术相比,ORM有以下优点:

  • 基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除SQL与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
  • 与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接。
  • 很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。
  • 提供映射标签,支持对象与数据库的字段映射;提供对象关系映射标签,支持对象关系组件维护。
  • 能够与Spring很好的集成。

缺点

  • SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。
  • SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

5.请说说MyBatis的工作原理

img

  1. 通过加载mybatis全局配置文件以及mapper映射文件初始化configuration对象和Executor对象(通过全局配置文件中的defaultExecutorType初始化);

  2. 创建一个defaultSqlSession对象,将configuration对象和Executor对象注入给defaulSqlSession对象中;

  3. defaulSqlSession通过getMapper()获取mapper接口的代理对象mapperProxy(mapperProxy中包含defaultSQLSession对象)

  4. 执行增删改查:

    • 通过defaulSqlSession中的属性Executor创建statementHandler对象;
    • 创建statementHandler对象的同时也创建parameterHandler和resultSetHandler;
  5. 通过parameterHandler设置预编译参数及参数值;

  6. 调用statementHandler执行增删改查;

  7. 通过resultsetHandler封装查询结果。

6.MyBatis的架构设计是怎样的?

img

  • API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
  • 数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
  • 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
  • 引导层:加载xml配置和Java配置。

7.#{}和${}的区别

  • #{}是占位符,预编译处理,可以防止SQL注入;${}是拼接符,字符串替换,没有预编译处理,不能防止SQL注入。
  • Mybatis在处理#{}时,#{}传入参数是以字符串传入,会将SQL中的#{}替换为?号,调用PreparedStatement的set方法来赋值;Mybatis在处理时,是原值传入,就是把{}时,是原值传入,就是把{}替换成变量的值,相当于JDBC中的Statement编译。
  • #{} 的变量替换是在DBMS 中,变量替换后,#{} 对应的变量自动加上单引号;的变量替换是在DBMS外,变量替换后,{} 的变量替换是在 DBMS 外,变量替换后,DBMS{} 对应的变量不会加上单引号。

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

  • “%”#{question}"%" 注意:因为#{…}解析成sql语句时候,会在变量外侧自动加单引号’ ',所以这里 % 需要使用双引号" ",不能使用单引号 ’ ',不然会查不到任何结果。
<select id="getEmpByName" resultType="com.szh.bean.Employee">select id,lastName,email,genderfrom employeewhere lastName like "%"#{lastName}"%"
</select>List<Employee> list = mapper.getEmpByName("小");
  • ‘%${question}%’ 可能引起SQL注入,不推荐。
<select id="getEmpByName" resultType="com.szh.bean.Employee">select id,lastName,email,genderfrom employeewhere lastName like '%${lastName}%'
</select>List<Employee> list = mapper.getEmpByName("小");
  • CONCAT(’%’,#{question},’%’) 使用CONCAT()函数,推荐。
<select id="getEmpByName" resultType="com.szh.bean.Employee">select id,lastName,email,genderfrom employeewhere lastName like concat("%",#{lastName},"%")
</select>List<Employee> list = mapper.getEmpByName("小");
  • 使用bind标签。
<select id="getEmpByName" resultType="com.szh.bean.Employee"><bind name="pattern" value="'%' + lastName + '%'"/>select id,lastName,email,genderfrom employeewhere lastName like #{pattern}
</select>List<Employee> list = mapper.getEmpByName("小");

9.如何获取生成的主键?

对于支持主键自增的数据库(MySQL)

<!-- useGeneratedKeys 设置为"true"表明 MyBatis 要获取由数据库自动生成的主键,keyColumn指定数据库主键,keyProperty指定 Java 实体类中对应的主键字段 -->
<insert id="insertUser" useGeneratedKeys="true" >keyProperty="userId" >insert into user(user_name, user_password, create_time)values(#{userName}, #{userPassword} , #{createTime, jdbcType= TIMESTAMP})
</insert>

parameterType 可以不写,Mybatis可以推断出传入的数据类型。如果想要访问主键,那么parameterType 应当是java实体或者Map。这样数据在插入之后可以通过java实体或者Map来获取主键值。

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

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

<select id="getEmpById" resultType="com.szh.bean.Employee">select id,last_name lastName,email,genderfrom employeewhere id = #{id}
</select>

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

<resultMap id="myMap" type="com.szh.bean.Employee"><id column="id" property="id"/><result column="last_name" property="lastName"/><result column="email" property="email"/><result column="gender" property="gender"/>
</resultMap>

第3种:在mybatis全局配置文件中开启驼峰命名规则。

<settings><setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

11.什么是MyBatis的接口绑定?有哪些实现方式?

接口绑定,就是在MyBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定,我们调用接口方法的时候,最终会执行绑定的SQL语句。

接口绑定有两种实现方式,当Sql语句比较简单时候,可以使用注解绑定,当SQL语句比较复杂时候,一般用xml绑定的比较多。

  • 通过注解绑定,就是在接口的方法上面加上 @Select、@Update等注解,里面包含Sql语句来实现接口绑定;
  • 通过在xml里面写SQL语句来实现绑定, 在这种情况下,要指定xml映射文件里面的namespace必须为接口的全限定类名,同时接口的方法名和SQL语句的id一一对应。

12.使用MyBatis的mapper接口调用时有哪些要求?

  • Mapper.xml文件中的namespace应该是对应mapper接口的全限定类名。
  • Mapper接口方法名和mapper.xml中定义的sql语句id一一对应。
  • Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql语句的parameterType的类型相同。
  • Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql语句的resultType的类型相同。

13.最佳实践中,通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗

Dao接口,就是人们常说的Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement

举例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到namespace为com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement。在Mybatis中,每一个<select><insert><update><delete>标签,都会被解析为一个MappedStatement对象。

Dao接口里的方法,是不能重载的,因为是全限定类名+方法名的保存和寻找策略,需要保证全限定类名+方法名的唯一性。(重载了话,方法名一定是重复的)

Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理对象proxy,代理对象proxy会拦截接口方法调用,转而执行方法对应的sql语句,然后将sql执行结果返回。

14.MyBatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?

Mybatis动态sql可以让我们在xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能,Mybatis提供了9种动态sql标签trim|where|set|foreach|if|choose|when|otherwise|bind。

其执行原理为,使用OGNL(对象导航图语言Object Graph Navigation Language)从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。

15.MyBatis的一级、二级缓存是什么?

  • 一级缓存:采用 PerpetualCache,HashMap 存储。MyBatis默认打开一级缓存,其存储作用域为 当前sqlSession会话对象,当 sqlSession flush 或 close 之后,该 sqlSession 中的所有 Cache 就将清空。可以调用clearCache();//手动清理缓存。
  • 二级缓存:默认也是采用 PerpetualCache,HashMap 存储,不同之处在于二级缓存的存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,开启二级缓存之后(在mybatis主配置文件中添加<setting name="cacheEnabled" value="true"/>;其次在对应的mapper映射文件中添加 ),对应的实体类需要实现Serializable序列化接口(可用来保存对象的状态)。
  • 对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)进行了C/U/D 操作后,默认该作用域下所有缓存将被清理掉。

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/557305.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java面试——Spring系列总结

文章目录&#xff1a; 1.什么是Spring&#xff1f; 2.Spring由哪些模块组成&#xff1f; 3.Spring中都用到了哪些设计模式&#xff1f; 4.什么是Spring IOC容器&#xff1f;有什么作用&#xff1f; 5.Spring IoC的实现机制 6.BeanFactory 和 ApplicationContext有什么区别…

Spring bean 不被 GC 的真正原因

概述 自从开始接触 Spring 之后&#xff0c;一直以来都在思考一个问题&#xff0c;在 Spring 应用的运行过程中&#xff0c;为什么这些 bean 不会被回收&#xff1f; 今天深入探究了这个问题之后&#xff0c;才有了答案。 思考点 大家都知道&#xff0c;一个 bean 会不会被回…

vts传感器采取船舶的_详解虎门大桥监测系统:传感器与物联网功不可没

来源&#xff1a;传感器专家网近日&#xff0c;虎门大桥“虎躯一震”给全国人民来了个“深呼吸”。虎门大桥是广东沿海地区重要的交通枢纽&#xff0c;始建于1992年&#xff0c;1997年通车至今&#xff0c;大桥一直都十分平稳。但在5月5日下午&#xff0c;虎门大桥发生异常抖动…

MySQL 排名函数.md

概述 MySQL 自带的排名的函数&#xff0c;主要有&#xff1a; row_number()rank()dense_rank()ntile() 测试数据 测试数据如下所示&#xff1a; row_number() 函数 用法如下&#xff1a; SELECT row_number() OVER (ORDER BY Salary DESC) row_num,Salary FROMEmployee查…

深度学习auc_机器学习集成学习与模型融合!

↑↑↑关注后"星标"Datawhale每日干货 & 每月组队学习&#xff0c;不错过Datawhale干货 作者&#xff1a;李祖贤&#xff0c;深圳大学&#xff0c;Datawhale高校群成员对比过kaggle比赛上面的top10的模型&#xff0c;除了深度学习以外的模型基本上都是集成学习的…

数控车椭圆编程实例带图_数控车床编程教程,图文实例详解

一、数控车编程特点(1) 可以采用绝对值编程(用X、Z表示)、增量值编程(用U、W表示)或者二者混合编程。(2) 直径方向(X方向) 系统默认为直径编程&#xff0c;也可以采用半径编程&#xff0c;但必须更改系统设定。(3) X向的脉冲当量应取Z向的一半。(4)采用固定循环&#xff0c;简化…

参考文献起止页码怎么写_毕业论文文献综述不会写?快来看看这篇文章(附含通用模板)...

文献综述是对所研究主题的现状进行客观的叙述和评论、寻求新的研究突破点。一个资料全面、研究深入的综述不仅可以帮助作者确立毕业论文的选题&#xff0c;还可以为论文的深入研究提供有力的支撑。本文分享一份"毕业论文文献综述万能模板",以供参考。一、文献综述的基…

常用并发工具类(线程池)

文章目录概述ThreadPoolExecutorThreadPoolExecutor 的主要属性Worker 主要属性线程池的状态线程池的状态流转线程池提交任务的执行流程线程数量的设置线程池的种类FixedThreadPoolCachedThreadPoolSingleThreadExecutorScheduledThreadPoolExecutorSingleThreadScheduledExecu…

JVM 内存模型与内存分配方式

文章目录JVM 内存模型概述基于分代收集理论设计的垃圾收集器所管理的堆结构方法区的演变内存分配划分内存的方法划分内存时如何解决并发问题对象栈上分配基于分代收集理论的垃圾收集器管理下的内存分配规则对象优先分配在 Eden 区大对象直接进入老年代长期存活的对象将逐步进入…

image pil 图像保存_如何利用python中的PIL库做图像处理?

自从这个世界上出现了Python编程&#xff0c;一切都好像有了新的思路与进展&#xff0c;比如人工智能&#xff0c;还有我们常用的PS&#xff0c;你可知道Python也可以做图像处理&#xff0c;用的就是PIL库&#xff0c;还没有用过的&#xff0c;还没有发现的&#xff0c;还没有实…

link st 量产工具_ST-Link资料03_ST-Link固件升级、驱动下载安装方法

说明&#xff1a;本文原创作者『strongerHuang』本文首发于微信公众号『嵌入式专栏』&#xff0c;同时也更新在我的个人网站&#xff1a;EmbeddedDevelop一、写在前面前两篇文章讲述的都是关于ST-Link的一些理论知识&#xff0c;建议初学者看看&#xff1a;ST-Link资料01_ST-Li…

SSM 框架整合 spring 发送邮件功能实现!

基于SSM的 spring 发送邮件的实现 由于考虑到项目中需要&#xff0c;如果程序出现异常或其它问题&#xff0c;可以发送邮件来及时提醒后台维护人员处>理。所以目前考虑使用JavaMail来实现邮件发送&#xff01;如下&#xff0c;是我整理的一些内容&#xff0c;做个笔记记录下…

Java 故障处理与性能监控工具

文章目录概述基础工具jpsjstatjinfojmapjhatjstack高级工具VisualVMVisualVM 的主要功能ArthasGC Easy概述 在使用 Java 语言进行开发的过程中&#xff0c;我们很可能会遇到各种程序问题。 比如&#xff0c;可能会遇见程序突然就静止不动了&#xff0c;但是程序进程依然显示在…

SSM整合框架实现发送邮件功能

SSM整合框架实现发送邮件功能 1.导入发送邮件的依赖 <!-- 发送邮件jar包--><!--spring支持--><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>5.0.0.RELE…

ap接口 php_2018年小米高级 PHP 工程师面试题(模拟考试卷)

点击蓝字关注我们&#xff01;每天获取最新的编程小知识&#xff01;源 / php中文网 源 / www.php.cn在面试之前多看看有关公司的面试资料&#xff0c;对之后的面试会很有帮助。今天就给大家带来2018年小米高级 PHP 工程师面试题(模拟考试卷)&#xff0c;有着一定的参考价…

composer 设置版本号_Composer依赖管理 – PHP的利器

别再到处搜PHP类扩展包了&#xff0c;对于现代语言而言&#xff0c;包管理器基本上是标配。Java 有 Maven&#xff0c;Python 有 pip&#xff0c;Ruby 有 gem&#xff0c;Nodejs 有 npm。PHP 的则是 PEAR&#xff0c;不过 PEAR 坑不少&#xff1a;依赖处理容易出问题配置非常复…

SpringBoot2.5.4发送邮件4种方式

一.准备 在创建SpringBoot项目 二、选择依赖 选择依赖时 发现其选择依赖时有邮件发送与Springboot整合的jar包&#xff0c;我们勾选即可 如果未勾选也不要紧&#xff0c;咱们手动导入 <dependency><groupId>org.projectlombok</groupId><artifactId…

手游传奇刷元宝_传奇手游 平民制霸刀刀爆元宝!

新轩辕神途手游游戏介绍新轩辕神途是一款玩法种类十分丰富多样的神途手游&#xff0c;游戏内拥有放置挂机升级玩法&#xff0c;玩家不用浪费时间工作上学都能自动升级打宝&#xff0c;更有十分庞大的世界地图等你来探索&#xff0c;十分靠谱&#xff0c;更受欢迎&#xff0c;爆…

MySQL 逻辑架构与常用的存储引擎

文章目录概述逻辑架构示意图Server 层功能模块连接器查询缓存分析器优化器执行器存储引擎层InnoDBInnoDB 主要特性InnoDB 引擎下的查询过程MyISAMMyISAM 的主要特性MyISAM 引擎下的查询过程InnoDB 和 MyISAM 的对比概述 MySQL 是我们平时开发中最常用的关系型数据库&#xff0…

java 阿里云接口实现发送短信验证码

1.先去阿里云开通短信服务&#xff1a; 2.添加模板及签名&#xff1a;需要审核&#xff0c;个人账户审核就几分钟就OK 先解释一下模板及签名&#xff1a; 标准参照&#xff1a;https://help.aliyun.com/document_detail/55324.html?spm5176.sms-sign.0.0.765c1cbeNhvWBZ 去…