好处

MyBatis持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

常见问题

1. #{}和${}的区别是什么?

#{}方式能够很大程度防止sql注入
$方式无法防止Sql注入
$方式一般用于传入数据库对象,例如传入表名
一般能用#的就别用$
#{}是预编译处理,${}是字符串替换。Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1,id);
#{} 这种取值是编译好SQL语句再取值

${} 这种是取值以后再去编译SQL语句

Mybatis在处理${}时,就是把${}替换成变量的值。使用#{}可以有效的防止SQL注入,提高系统安全性。

我们经常使用的是#{},一般解说是因为这种方式可以防止SQL注入,简单的说#{}这种方式SQL语句是经过预编译的,它是把#{}中间的参数转义成字符串,举个例子:

select * from student where student_name = #{name}

预编译后,会动态解析成一个参数标记符?:

select * from student where student_name = ?

而使用${}在动态解析时候,会传入参数字符串

select * from student where student_name = 'lyrics'

2. 一级、二级缓存
1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空。
2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:<cache/>
3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。

3. 通常一个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会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。

4.Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
第一种是使用<resultMap>标签,逐一定义列名和对象属性名之间的映射关系。第二种是使用sql列的别名功能,将列别名书写为对象属性名,比如T_NAME AS NAME,对象属性名一般是name,小写,但是列名不区分大小写,Mybatis会忽略列名大小写,智能找到与之对应对象属性名,你甚至可以写成T_NAME AS NaMe,Mybatis一样可以正常工作。有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

5. Mybatis映射文件中,如果A标签通过include引用了B标签的内容,请问,B标签能否定义在A标签的后面,还是说必须定义在A标签的前面?
虽然Mybatis解析Xml映射文件是按照顺序解析的,但是,被引用的B标签依然可以定义在任何地方,Mybatis都可以正确识别。
原理是,Mybatis解析A标签,发现A标签引用了B标签,但是B标签尚未解析到,尚不存在,此时,Mybatis会将A标签标记为未解析状态,然后继续解析余下的标签,包含B标签,待所有标签解析完毕,Mybatis会重新解析那些被标记为未解析的标签,此时再解析A标签时,B标签已经存在,A标签也就可以正常解析完成了。

6.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()方法的调用。这就是延迟加载的基本原理。

7.Mybatis映射文件中,如果A标签通过include引用了B标签的内容,请问,B标签能否定义在A标签的后面,还是说必须定义在A标签的前面?
虽然Mybatis解析Xml映射文件是按照顺序解析的,但是,被引用的B标签依然可以定义在任何地方,Mybatis都可以正确识别。
原理是,Mybatis解析A标签,发现A标签引用了B标签,但是B标签尚未解析到,尚不存在,此时,Mybatis会将A标签标记为未解析状态,然后继续解析余下的标签,包含B标签,待所有标签解析完毕,Mybatis会重新解析那些被标记为未解析的标签,此时再解析A标签时,B标签已经存在,A标签也就可以正常解析完成了。

8.Xml映射文件中,除了常见的 select|insert|update|delete标签之外,还有哪些标签?
还有很多其他的标签,加上动态sql的9个标签,trim|where|set|foreach|if|choose|when|otherwise|bind等,其中为sql片段标签,通过标签引入sql片段,为不支持自增的主键生成策略标签。

9.简述Mybatis的Xml映射文件和Mybatis内部数据结构之间的映射关系?
Mybatis将所有Xml配置信息都封装到All-In-One重量级对象Configuration内部。在Xml映射文件中,<parameterMap>标签会被解析为ParameterMap对象,其每个子元素会被解析为ParameterMapping对象。<resultMap>标签会被解析为ResultMap对象,其每个子元素会被解析为ResultMapping对象。每一个<select>、<insert>、<update>、<delete>标签均会被解析为MappedStatement对象,标签内的sql会被解析为BoundSql对象。

MyBatis的好处及常见问题的更多相关文章

  1. 零基础IDEA整合SpringBoot + Mybatis项目,及常见问题详细解答

    开发环境介绍:IDEA + maven + springboot2.1.4 1.用IDEA搭建SpringBoot项目:File - New - Project - Spring Initializr ...

  2. 四)mybatis 二级缓存 ehcache 常见问题

    1. java.io.NotSerializableException 94359 [EH_CACHE Async Replication Thread] ERROR n.s.e.d.jgroups. ...

  3. MyBatis知多少(17)MyBatis和JDBC

    有了MyBatis,就不再需要编写JDBC代码了.像JDBCT这样的API的确非常强大,但使用起来总不免觉得太过繁琐.代码清单给出了一个使用JDBC的示例. 从这个例子中很容易看出,JDBC API会 ...

  4. hibernate和mybatis

    本来是个菜鸟程序员,现在大学还没毕业. 最近一直在想一个问题,到底是hibernate好还是mybatis好.我总觉得 hibernate好用之极,在大学里做过的小项目都是用的hibernate,只要 ...

  5. Mybatis(一) mybatis入门

    学习了hibernate这个持久层框架之后,在来学习Mybatis简直是无压力,因为Mybatis入门门栏很低,如果学习过了hibernate的话,对于Mybatis的学习很简单了,如果没学习过hib ...

  6. SSM(Spring + Springmvc + Mybatis)框架面试题

    JAVA SSM框架基础面试题https://blog.csdn.net/qq_39031310/article/details/83050192 SSM(Spring + Springmvc + M ...

  7. MyBatis最原始的实现curd的操作

    关于jdbc的缺点: 1.数据库链接创建释放频繁造成系统资源浪费从而影响系统性能.如果使用数据库连接池可以解决此问题. 2.sql语句在代码中硬编码,不利于维护,sql变动需要改变java代码 3.使 ...

  8. Mybatis学习(一)—————mybatis入门

    学习了hibernate这个持久层框架之后,在来学习Mybatis简直是无压力,因为Mybatis入门门栏很低,如果学习过了hibernate的话,对于Mybatis的学习很简单了,如果没学习过hib ...

  9. Mybatis学习---基础知识考核

    MyBatis 2.什么是MyBatis的接口绑定,有什么好处 接口映射就是在IBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定,    我们直接调用接口方法就可以,这样比起原来了Sql ...

随机推荐

  1. Python学习—数据库篇之初识mysql

    一.下载与安装 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司.MySQL 最流行的关系型数据库管理系统,在 WEB 应用方面MySQL是最好 ...

  2. jquery-confirm使用方法

    简要教程 jquery-confirm是一款功能强大的jQuery对话框和确认框插件.它提供多种内置的主题效果,可以实现ajax远程加载内容,提供动画效果和丰富的配置参数等.它的特点还有: 可以使用键 ...

  3. 监听端口,获取webService请求报文

    第一步下载我们的wsdl文件到本地 第二步建立一个测试webservice工程,把wsdl放在项目里面 第三步把测试webservice中的wsdlLocation改成localhost.....你的 ...

  4. Python入门day04_函数与装饰器

    一.函数入门 什么是函数: # 函数:函数是一系列代码的集,用来完成特定功能的代码块,类似于工具,可以重复不但的去使用 为什么要有函数: # 优点:# 1. 避免代码的冗余 # 2. 让程序代码结构更 ...

  5. 使用nifi采集数据要配置的环境

    第一步 安装 Anaconda3-2019.03-Windows-x86_64.exe 下载地址:https://repo.anaconda.com/archive/Anaconda3-2019.03 ...

  6. laravel5增删改查

    路由规则: 数据库配置: config/database.php laravel5/.env 控制器: 表单: 展示页面: 修改页面:

  7. C#编码问题以及C#往Mysql插数据编码问题

    C#将字符转换成utf8编码 GB321编码转换   public static string get_uft8(string unicodeString) { UTF8Encoding utf8 = ...

  8. WCF 服务的集合管理器的设计

    今天是2019年2月1日,时间过得针对,马上就年底了,当前新年也离我们越来越近了.在此,我也祝福经常浏览我博客的朋友们“新年快乐.阖家欢乐”,来年有一个好彩头.在即将结束这一年之计,写今年的最后一片文 ...

  9. 7B - 今年暑假不AC

    “今年暑假不AC?” “是的.” “那你干什么呢?” “看世界杯呀,笨蛋!” “@#$%^&*%...” 确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了.  ...

  10. vue实例的生命周期

    Vue实例的生命周期也就是这个实例从出生到死亡的过程,所以我在文档原图上把这个周期大致分为创建过程 | 运行过程 | 销毁过程三个阶段,不同结果或又分为一些小的阶段 在第一个阶段,创建阶段,会完成Vu ...