SSM框架--mybatis

醉酒当歌 提交于 2020-02-03 07:15:19

五.mybatis相关

1.jdbc介绍

JDBC是Java制定的接口,数据库产商依照该接口编写与自家数据库配套的实现类。比如MySQL、Oracle、SqlServer等都有自己的不同实现,这些实现类的集合既是我们笼统意义上的“驱动”。
在这里插入图片描述
在这里插入图片描述

2.preparedstatement和statement的区别

数据库系统会对sql语句进行预编译处理(如果JDBC驱动支持的话),预处理语句将被预先编译好,语法语义解析优化sql语句,指定执行计划执行并返回结果 但是很多情况,我们的一条sql语句可能会反复执行,或者每次执行的时候只有个别的值不同(比如select 的where子句值不同,update的set子句值不同,insert 的values值不同).如果每次都需要经过上面的词法语义解析,语句优化,制定执行计划等,则效率就明显不行了 所谓预编译语句就是将这类语句的值用占位符替代,可以视为将sql语句模板或者说参数化
什么是预编译(将这条sql(解析完成)语句放入缓存执行计划中,如果有相同的sql语句进来,就会直接执行该sql(解析完成)语句,省去解析的过程)

下面列出PreparedStatement的几点优势。
1.PreparedStatement可以写动态参数化的查询用PreparedStatement你可以写带参数的sql查询语句,通过使用相同的sql语句和不同的参数值来做查询比创建一个不同的查询语句要好,因为它可以用不同的参数调用它,这里的”?”就是参数的占位符。
2.PreparedStatement比 Statement 更快使用 PreparedStatement 最重要的一点好处是它拥有更佳的性能优势,SQL语句会预编译在数据库系统中。执行计划同样会被缓存起来,它允许数据库做参数化查询。使用预处理语句比普通的查询更快,因为它做的工作更少(数据库对SQL语句的分析,编译,优化已经在第一次查询前完成了)。为了减少数据库的负载,生产环境中德JDBC代码你应该总是使用PreparedStatement 。值得注意的一点是:为了获得性能上的优势,应该使用参数化sql查询而不是字符串追加的方式。下面两个SELECT 查询,第一个SELECT查询就没有任何性能优势。

3.MyBatis框架的理解?

属于持久层的框架。通过配置文件XML或注解,将接口和POJO映射成数据库中的记录……相关的依赖包,数据库表,配置文件(数据库驱动信息,核心配置文件),实体对象,最重要的Mapper接口对实体的增删改查操作和Mapper映射文件xml(也需要注册到核心配置文件中),通过SqlSessionFactory创建SqlSession对象进行操作……

mybatis的工作原理?执行流程?

mybatis执行过程代码
在这里插入图片描述

16、Xml映射文件中,除了常见的select|insert|updae|delete标签之外,还有哪些标签?

答:结果集映射标签、、、、, – 对给定命名空间的缓存配置。加上动态sql的9个标签,其中 为sql片段标签,通过 标签引入sql片段, 为不支持自增的主键生成策略标签。

在mybatis中如何传递参数?

在这里插入图片描述

${}和#{}的区别?

------${}就是数据源中通过对数据源驱动配置引入到框架核心配置文件中的变量值,#{}mapper.xml的预编译SQL文件……

2、两者的区别:(1)#{} : 采用预编译方式,可以防止 SQL 注入(2)${}: 采用直接赋值方式,无法阻止 SQL 注入攻击在大多数情况下,我们都是采用 #{} 读取参数内容。但是在一些特殊的情况下,我们还是需要使用 ${} 读取参数的。比如有两张表,分别是 dept 和 dept_01。如果需要在查询语句中动态指定表名,就只能使用 ${} 。再比如:需要动态的指定查询中的排序字段,此时也只能使用 ${},简单来说,在 JDBC 不支持使用占位符的地方,都可以使用 ${}。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

15、Mybatis动态sql有什么用?执行原理?有哪些动态sql?

Mybatis动态sql可以在Xml映射文件内,以标签的形式编写动态sql,执行原理是根据表达式的值 完成逻辑判断并动态拼接sql的功能。Mybatis提供了9种动态sql标签:trim|where|set|foreach|if|choose|when|otherwise|bind。

20、MyBatis实现一对一有几种方式?具体怎么操作的?

有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次,指通过一次 SQL 查询将所有的结果查询出来,然后通过配置的结果映射,将数据映射到不同的对象中去 , 通过在resultMap里面配置association节点配置一对一的类就可以完成;

嵌套查询是先查一个表,根据这个表里面的结果的 外键id,去再另外一个表里面查询数据,也是通过association配置,但另外一个表的查询通过select属性配置。

21、MyBatis实现一对多有几种方式,怎么操作的?

有联合查询和嵌套查询。联合查询是几个表联合查询,只查询一次,通过在resultMap里面的collection节点配置一对多的类就可以完成;嵌套查询是先查一个表,根据这个表里面的 结果的外键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的查询通过select节点配置。

22、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,支持延迟加载的原理都是一样的。

Mybatis配置文件中通过两个属性lazyLoadingEnabled和aggressiveLazyLoading来控制延迟加载和按需加载。
lazyLoadingEnabled:是否启用延迟加载,mybatis默认为false,不启用延迟加载。lazyLoadingEnabled属性控制全局是否使用延迟加载,特殊关联关系也可以通过嵌套查询中fetchType属性单独配置(fetchType属性值lazy或者eager)。
aggressiveLazyLoading:是否按需加载属性,默认值false,lazyLoadingEnabled属性启用时只要加载对象,就会加载该对象的所有属性;关闭该属性则会按需加载,即使用到某关联属性时,实时执行嵌套查询加载该属性。

对于XML映射文件和Mapper接口对应,这Mapper接口的原理是什么?

---------也就是映射文件的namespace值对应Mapper接口包名接口名,接口中的方法名为映射文件中的id值,接口中的方法参数为传递给映射文件的sql参数。Mapper接口没有实现类,调用时采用接口全限名+方法名组成的字符串作为key,即可定位对应的标签(,……)。Mapper接口原理是JDK动态daili(这两个字被平台加入到了违禁词系统了……)……

什么是分页?

---------------分页就是将数据库表的记录分页显示,比如1000条记录,分成100页来显示(从0页、0行开始),第0页显示第0-99条数据,以此类推……。逻辑分页,显示每页数据时首先查询1000条数据,然后根据当前页码选出其中的100条来显示。物理分页,先判断该选出的这1000条的第几条到第几条,然后数据库根据给定的请求查询出需要的100条数据返回给前端。

Mybatis如何进行分页?

----------属于对上个问题的延续,逻辑分页采用的是RowBounds对象进行分页,针对ResultSet结果集执行的内存分页。物理分页可以直接用带有物理分页的参数,也可以使用分页插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据方言添加对应的物理分页语句和参数。……

一级、二级缓存?

----------------一级缓存是默认的,作用域为Session,当Session flush或close之后,Session中的所有缓存被清空。二级缓存需要手动配置开启的,存储作用域为namespace,即整个mapper接口……
MyBatis的缓存分为一级缓存和二级缓存,两种缓存的缓存粒度是一样的,都是对应一条sql查询语句,但是二者的生命周期是不一样的,一级缓存的生命周期是SqlSession对象的使用期间,随着SqlSession对象的死亡而消失;二级缓存的生命周期是同MyBatis应用一样长的;并且是首先查询二级缓存,然后再查询一起缓存。1.缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空。2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper ,并且可自定义存储源,如 Ehcache。二级缓存的作用域是全局的,二级缓存在SqlSession关闭或提交之后才会生效。

11、Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

第一种是使用标签,逐一定义列名和对象属性名之间的映射关系。第二种是使用sql列的别名功能,将列别名书写为对象属性名,比如T_NAME AS NAME,对象属性名一般是name,小写,但是列名不区分大小写,Mybatis会忽略列名大小写,智能找到与之对应对象属性名,你甚至可以写成T_NAME AS NaMe,Mybatis一样可以正常工作。

    有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。
27、简述Mybatis的插件运行原理,以及如何编写一个插件。

答:Mybatis仅可以编写针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件,Mybatis使用JDK的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,当然,只会拦截那些你指定需要拦截的方法。

编写插件:实现Mybatis的Interceptor接口并实现intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件

  • 在四大对象创建的时候
  • 1、每个创建出来的对象不是直接返回的,而是
  •  interceptorChain.pluginAll(parameterHandler);
    
  • 2、获取到所有的Interceptor(拦截器)(插件需要实现的接口);
  •  调用interceptor.plugin(target);返回target包装后的对象
    
  • 3、插件机制,我们可以使用插件为目标对象创建一个代理对象;AOP(面向切面)
  •  我们的插件可以为四大对象创建出代理对象;
    
  •  代理对象就可以拦截到四大对象的每一个执行;
    
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!