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,一经查实,立即删除!

相关文章

包装类型与基本类型的装箱与拆箱操作

文章目录概述Boolean 与 booleanCharacter 与 charByte 与 byteShort 与 shortInteger 与 intFloat 与 floatDouble 与 doubleLong 与 long总结概述 基本类型与包装类型&#xff0c;存在相互转化的关系。 基本类型转为包装类型这个过程&#xff0c;被称之为装箱包装类型转为基…

机器人炒饭小块头一一_小块头机器人炒饭:全智能流程,炒饭芬芳独具

在我的生活里&#xff0c;没有什么不开心的事情是一顿炒饭解决不了的&#xff0c;实在不行就两顿。把前一天剩出来的隔夜饭放到锅里和家里的食材进行组合、翻炒&#xff0c;就可以千变万化&#xff0c;方便好吃又管饱。小块头茶油炒饭&#xff0c;是一份易拉罐材质独立包装的炒…

Java面试——Spring系列总结

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

gateway 过滤器执行顺序_spring boot gateway 过滤器的执行顺序

前言学习官方文档&#xff0c;发现对于过滤器有分为三类默认过滤器自定义过滤全局过滤器于是就有一个疑问&#xff0c;关于这些过滤器的访问顺序是怎样的&#xff0c;今天就以一个demo来进行测试准备阶段过滤器工厂类以此为模板&#xff0c;复制出几份就可以了&#xff0c;注意…

Java 线程状态流转

Java 线程一共有 6 种状态&#xff1a; NEW&#xff1a;新建状态&#xff0c;当一个线程被创建完成&#xff0c;还没有调用 start() 方法时&#xff0c;是这种状态。RUNNABLE&#xff1a;可运行状态&#xff0c;当一个线程正在正常地执行 run() 中的代码时&#xff0c;是这种状…

达梦数据库导入oracle数据_达梦数据库和oracle数据的一些区别

近期我在考达梦的dca发现有一些和oracle不同的地方&#xff0c;由于我是oracleDBA在维护达梦数据库的时候有需要注意的地方&#xff0c;现在分享一下2个数据库的一些区别。1、登陆的区别oracle:如果sys的密码忘记可以用操作系统验证方式登陆修改密码。dm:达梦数据库如果忘记了s…

Fail-fast 和 Fail-safe 机制

fail-fast 和 fail-safe 的区别 从字面意思来看 fail-fast 是快速失败&#xff0c;fail-safe 是安全失败&#xff0c;这都是集合类对于并发读写时的一种应对机制。 fail-fast&#xff0c;广泛应用于 java.util 下的集合类中&#xff0c;其机制为在使用迭代器遍历的过程中&…

【java8新特性】——lambda表达式与函数式接口详解(一)

一、简介 java8于2014年发布&#xff0c;相比于java7&#xff0c;java8新增了非常多的特性&#xff0c;如lambda表达式、函数式接口、方法引用、默认方法、新工具&#xff08;编译工具&#xff09;、Stream API、Date Time API、Optional等 。 当前很多公司的老产品依然使用的…

详解 ConcurrentHashMap

文章目录ConcurrentHashMap 的底层数据结构?ConcurrentHashMap 的带参构造方法的流程&#xff1f;ConcurrentHashMap 的 put 方法的流程?ConcurrentHashMap addCount 方法的流程是怎样的呢&#xff1f;ConcurrentHashMap transfer 方法的流程是怎样的呢&#xff1f;Concurren…

js 二叉树图形_js数据结构和算法(三)二叉树

二叉树的概念二叉树(Binary Tree)是n(n>0)个结点的有限集合&#xff0c;该集合或者为空集(空二叉树)&#xff0c;或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。二叉树的特点每个结点最多有两棵子树&#xff0c;所以二叉树中不存在度大于…

【java8新特性】——Stream API详解(二)

一、简介 java8新添加了一个特性&#xff1a;流Stream。Stream让开发者能够以一种声明的方式处理数据源&#xff08;集合、数组等&#xff09;&#xff0c;它专注于对数据源进行各种高效的聚合操作&#xff08;aggregate operation&#xff09;和大批量数据操作 (bulk data op…

Spring bean 不被 GC 的真正原因

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

ad域时间源配置_域控制器server2012时间同步NTP配置

一、域控配置1.修改注册表&#xff0c;设置域控服务器名称2.设置组策略&#xff0c;启动NTP服务器3.域策略中设置windows time服务自动启动二、服务端配置(Ntp服务器&#xff0c;客户端将根据这台服务器的时间进行同步)1、微软键R键&#xff0c;进入“运行”&#xff0c;输入“…

【java8新特性】——Optional详解(三)

一、简介 Optional类是Java8为了解决null值判断问题&#xff0c;借鉴google guava类库的Optional类而引入的一个同名Optional类&#xff0c;使用Optional类可以避免显式的null值判断&#xff08;null的防御性检查&#xff09;&#xff0c;避免null导致的NPE&#xff08;NullPo…

不使用 + 和 - 运算符计算两整数之和

问题概述 不使用运算符 和 -&#xff0c;计算两整数之和 思考 不使用 和 - &#xff0c;那就只能想到用位运算来处理了。思路如下&#xff1a; 两数进行 ^&#xff08;异或运算&#xff09;&#xff0c;可以得到两个数在相同位上数值不同的相加结果两数进行 &&#x…

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

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

宝塔安装sqlserver_linux宝塔面板安装安装 pdo_sqlsrv扩展

第一步安装源curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssqlrelease.repo第二步安装驱动yum install msodbcsql mssql-tools unixODBC-devel第三步下载pdo-sqlsrv源码wget http://pecl.php.net/get/pdo_sqlsrv-5.6.1.tgztar -zxvf …

【java8新特性】——方法引用(四)

一、简介 方法引用是java8的新特性之一&#xff0c; 可以直接引用已有Java类或对象的方法或构造器。方法引用与lambda表达式结合使用&#xff0c;可以进一步简化代码。 来看一段简单代码&#xff1a; public static void main(String[] args) {List<String> strList Ar…

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查…

【java8新特性】——默认方法(五)

一、简介 默认方法是指接口的默认方法&#xff0c;它是java8的新特性之一。顾名思义&#xff0c;默认方法就是接口提供一个默认实现&#xff0c;且不强制实现类去覆写的方法。默认方法用default关键字来修饰。 默认方法可以解决的痛点&#xff1a; 在java8之前&#xff0c;修…