谈谈 MyBatis

源自官方文档:MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java 对象为数据库中的记录。一句话就是对 JDBC 的封装。

MyBatis 的优缺点

优点:

1:SQL 语句与 Java 代码分离,便于统一管理。

2:提供 xml 标签,支持动态 SQL 编写。

3:消除了 JDBC 中大量冗余的代码,并通过数据库连接池维护连接。

4:很好的与各种数据库兼容,能够与 Spring 很好的集成。

5:提供对象关系映射标签,支持对象与数据库的 ORM 字段关系映射。

缺点:

1:SQL 语句编写的工作量较大,尤其是字段多,关联查询复杂时对于 SQL 的基础功底有一定要求。

2:对性能要求较高,需求变化较多的项目适合使用 MyBatis。

什么是 ORM

对象关系映射(Object Relational Mapping,简称 ORM),描述实体类属性和数据库字段之间的映射关系,将面向对象语言程序中的对象自动持久化到关系型数据库中,场景的 ORM 框架:Hibernate、MyBatis 等。

半自动和全自动 ORM 映射工具

Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或关联集合对象时,可以根据对象关系模型直接获取。

MyBatis 属于半自动 ORM 映射工具,使用 MyBatis 查询关联对象或关联集合对象时,需要手动编写 SQL 来完成。

JDBC 的不足和 MyBatis 的解决

1:JDBC 数据库创建链接和释放资源频繁造成系统资源浪费从而影响系统性能。MyBatis 使用数据库连接池管理数据库连接。

2:JDBC 的 SQL 语句写在代码中造成代码不易维护。MyBatis 将 SQL 语句配置在 mapper.xml 文件中与 Java 代码进行分离。

3:JDBC 的 SQL 语句传参非常麻烦,where 条件不确定且占位符要与参数一意对应。MyBatis 自动将 Java 对象映射到 SQL 语句中。

4:JDBC 对结果集解析较为麻烦,SQL 语句变化导致解析代码变化且解析前需要遍历。MyBatis 自动将 Java 对象映射到 SQL 语句中。

MyBatis 的编码步骤

1:创建 SqlSessionFactory。

2:通过 SqlSessionFactory 创建 SqlSession。

3:通过 SqlSession 执行数据库操作。

4:调用 session.commit() 提交事务。

5:调用 session.close() 关闭会话。

MyBatis 中 #{} 和 ${} 的区别

${} 是 properties 文件中的变量占位符。用于标签属性值和 SQL 内部的静态文本替换。

#{} 是 SQL 语句参数的占位符。MyBatis 会将 SQL 语句中的 #{} 替换为 ? 号。

#{} 方式能很大程度上防止 SQL 注入,一般使用 #{} 而不使用 ${}${} 无法防止SQL 注入,一般用于传入数据库对象,比如表名。

什么是 SQL 注入

源自百度百科:SQL 注入即是指 web 应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在 web 应用程序中事先定义好的查询语句的结尾上添加额外的 SQL 语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。一句话就是通过拼接非法的可执行的 SQL 语句非法获取数据信息。

MyBatis 的 mapper 接口调用的要求

1:mapper 接口的类路径即是 mapper.xml 文件中的 namespace 属性值。

2:mapper 接口方法名和 mapper.xml 文件中定义的每个 SQL 的 id 相同。

3:mapper 接口方法的入参类型和 mapper.xml 文件中定义的每个 SQL 的 parameterType 的类型相同。

4:mapper 接口方法的返回值类型和 mapper.xml 文件中定义的每个 SQL 的 resultType 的类型相同。

MyBatis 中的一级缓存与二级缓存

一级缓存:基于 PerpetuaCache 的 HashMap 本地缓存,作用域为 Session。当 Session flush 或 close 后,该 Session 中的所有 Cache 就将被清空。

二级缓存:与一级缓存机制相同,也是基于 PerpetuaCache 的 HashMap 本地缓存,但其作用域为 namespaces。二级缓存可以自定义存储源,例如 Ehcache。二级缓存会对一个 namespace 对应的 mapper.xml 文件中所有的 select 操作结果都进行缓存,不同线程之间就可以共用二级缓存。

当某一个作用域,不管是一级缓存 Session 还是二级缓存 namespaces 进行了增删改操作,默认该作用域下所有 select 中的缓存将被清除。

二级缓存开启:MyBatis 配置文件中开启 <cache />。

二级缓存的策略:<cache readOnly="true"/> 二级缓存返回给所有调用者是同一个缓存对象实例,调用者更新缓存实例后可以会造成其他调用者调用时出现数据不一致的情况。<cache readOnly="false"/> 二级缓存返回给所有调用者是总缓存对象的拷贝,不同调用者获取的是缓存对象的不同实例,各自维护各自的缓存对象,更新不会影响到其他的调用者。二级缓存默认使用安全的 <cache readOnly="false"/> 策略。

xml 文件中,除了常见的 CRUD 标签外还有哪些标签

其他 5 个标签 resultMap / parameterMap / sql / include / selectKey。

动态 SQL 的 9 个标签:trim / where / set / foreach / if / choose / when / otherwise / bind。

mapper 接口的实现原理

mapper 接口的底层是通过 Map<String, MapperedStatement> 集合维护。key 为接口的路径名 + 方法名拼接的字符串或 namespace + id,value 为 MapperedStatement 对象。MapperedStatement 对象即为 namespace 下的标签 id 对应的对象,例如 namespace=”com.xpy.mapper.UserMapper” 下的 select / insert / update / delete 标签 id=”getUserById” 对应的对象。接口的路径名 + 方法名拼接的字符串,例如 com.xpy.mapper.UserMapper.getUserById 定位一个唯一的 MapperedStatement 对象。

MapperedStatement 对象唯一说明 mapper 接口中的的方法不能重载。

不同的 xml 文件中,如果配置了 namespace,id 就可以重复,如果没有配置 namespace,则 id 对应的数据就会造成覆盖。

mapper 接口的工作原理是 JDK 动态代理。MyBatis 运行时会使用 JDK 动态代理为 mapper 接口生成代理对象 proxy,代理对象 proxy 会拦截接口方法转而去执行 MapperedStatement 对象,并将 SQL 的执行结果返回。

MyBatis 分页和分页插件的原理

MyBatis 使用 RowBounds 对象进行分类,是针对 ResultSet 结果集执行的内存分页。要实现物理分页可以通过 SQL 中配置 LIMIT 参数或使用分页插件。

分页插件的原理是使用 MyBatis 提供的插件接口实现自定义插件,在插件的拦截方法内拦截待执行的 SQL 语句进行重写,根据 dialect 方言添加对应的物理分页语句和参数。

MyBatis 的插件运行原理

MyBatis 仅支持 ParameterHandler、ResultSetHandler、StatementHandler、Executor 这四种接口的插件。每当执行这四种接口对象的方法时,就会进入拦截方法,也就是 InvocationHandler 的 invoke 方法,拦截指定需要拦截的方法。

编写一个插件只需实现 MyBatis 的 Interceptor 接口并重写 intercept 方法,然后在给插件编写一个注解,指定要拦截哪一个接口的哪些方法,最后在配置文件中配置编写的插件。

MyBatis 如何将 SQL 执行结果封装为目标对象返回的

第一种是通过 resultMap 标签逐一定义数据库字段名和实体类属性名之间的映射关系,第二种是使用别名,将数据库字段名写成实体类属性名,例如 t_title as title。有了映射关系后,MyBatis 会通过反射创建对象,同时给对象的属性逐一赋值并返回,找不到或没有映射关系的属性无法完成赋值。

MyBatis 的动态 SQL 的执行原理

动态 SQL 是指可以在 xml 文件中可以通过标签的形式动态编写 SQL,完成逻辑判断和动态拼接 SQL 语句的功能。动态 SQL 的执行原理是使用 OGNL 从 SQL 参数对象中计算表达式的指,根据表达式的值动态拼接 SQL。

MyBatis 关联查询的实现方式及区别

MyBatis 支持一对一、一对多、多对一、多对多的关联查询。关联对象查询有两种实现方式,第一种是单独发送一个 SQL 语句去查询关联对象,赋值给主对象并返回主对象。第二种是使用嵌套查询,使用 join 查询,一部分列是 A 对象的属性值,一部分列是 B 对象的属性值,只发送一个 SQL 语句就可以把主对象和其关联对象全都查出来。

MyBatis 的 Executor 执行器

MyBatis 有三种基本的 Executor 执行器:SimpleExecutor、ReuseExecutor、BatchExecutor。这些执行器都严格限制在 SqlSession 生命周期范围内。

SimpleExecutor:每执行一次 update 或 select,就开启一个 Statement 对象,用完立刻关闭。

ReuseExecutor:执行 update 或 select 时,以 SQL 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后不关闭,而是放到 Map<String, Statement> 中,供下一次使用。

BatchExecutor:在执行 update 时将所有 SQL 都添加到批处理中,等待统一执行,执行器缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch 完毕后,等待逐一执行 executeBatch。JDBC 批处理不支持 select。

MyBatis 配置文件中可以指定默认的 ExecutorType 执行器类型,也可以手动给 DefaultSqlSessionFactory创建 SqlSession 的方法传递 ExecutorType 参数类型。

MyBatis 是否可以映射 Enum 枚举类

可以,MyBatis 可以映射任何对象到表的列上。映射方式为自定义一个 TypeHandler,实现 TypeHandler 的 setParameter 和 getResult 方法,setParameter 方法实现 javaType 到 jdbcType 的转换,设置 SQL 占位符参数。getResult 方法实现 jdbcType 到 javaType 的转换,获取列查询结果。

MyBatis 解析标签规则

MyBatis 解析 xml 文件是按照顺序解析的,但 MyBatis 解析标签时如果发现引用了另外一个标签,但另外一个标签尚未解析到,此时就会将此标签标记为未解析状态,继续解析余下的标签,待所有标签解析完毕,MyBatis 会重新解析被标记为未解析状态的标签,此时另一个标签已经存在,也就正常解析完成了。所以如果一个标签通过 include 引用了另外一个标签的内容,则另外一个标签可以定义在任何地方。

 
 
原文链接:https://www.kuangstudy.com/bbs/1462698745987616770

谈谈MyBatis持久层框架的更多相关文章

  1. MyBatis持久层框架使用总结 转载

    MyBatis持久层框架使用总结   MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google co ...

  2. MyBatis持久层框架使用总结

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis . 2 ...

  3. Spring集成MyBatis持久层框架

    一.MyBatis介绍 MyBatis 是一款优秀的持久层框架,它支持定制化SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的JDBC代码和手动设置参数以及获取结果集,可以使用简单的XML ...

  4. MyBatis持久层框架学习之01 MyBatis的起源和发展

    一.MyBatis的简介  MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.    MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集. MyB ...

  5. spring-boot+mybatis开发实战:如何在spring-boot中使用myabtis持久层框架

    前言: 本项目基于maven构建,使用mybatis-spring-boot作为spring-boot项目的持久层框架 spring-boot中使用mybatis持久层框架与原spring项目使用方式 ...

  6. java持久层框架mybatis如何防止sql注入

    看到一篇很好的文章:http://www.jfox.info/ava-persistence-framework-mybatis-how-to-prevent-sql-injection sql注入大 ...

  7. 持久层框架之MyBatis

    1.mybatis框架介绍: MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并 ...

  8. Java数据持久层框架 MyBatis之背景知识三

    摘录自:http://www.cnblogs.com/lcngu/p/5437281.html 对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.or ...

  9. Java数据持久层框架 MyBatis之API学习一(简介)

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

  10. Java数据持久层框架 MyBatis之背景知识二

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

随机推荐

  1. fastjson反序列化各版本利用汇总

  2. 【Android逆向】破解黑宝宝apk,绕过签名校验

    这是52pojie的一道题,实现输入任何密码都可以登录成功 他知道你最近在学习Android逆向 他想在游戏上线前让你测试一下他新加的签名验证是否能防住别人的破解. 下面是李华编写的黑宝宝apk 链接 ...

  3. vue upload 图片转base64、转二进制数组,保存编码数据到文件

    功能需求 1.图片转base64 2.base 64 转二进制数组 3.保存二进制数据到文件下载到本地 解决方法 问题1: 参考资料 vue element upload图片 转换成base64 具体 ...

  4. 【华为机试ACM基础#01】字符串最后一个单词长度、计算某字符出现次数、提取不重复的整数(熟悉字符/字符串/整数的输入)

    字符串最后一个单词的长度 描述 计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000.(注:字符串末尾不以空格为结尾) 输入描述: 输入一行,代表要计算的字符串,非空,长度小于5000 ...

  5. 矩池云快速安装torch-sparse、torch-geometric等包

    租用机器,按自己需要的环境选择一个环境,我这里选择的是Pytorch 1.10. 租用成功后点击租用页面的 Jupyterlab 链接. Jupyterlab 里新建一个Terminal 用来安装环境 ...

  6. 【Filament】纹理贴图

    1 前言 ​ 本文主要介绍使用 Filament 实现纹理贴图,读者如果对 Filament 不太熟悉,请回顾以下内容. Filament环境搭建 绘制三角形 绘制矩形 绘制圆形 绘制立方体 ​ Fi ...

  7. 【Azure 批处理 】Azure Batch门户中创建自定义作业模式失败解决办法

    问题描述 跟随官方文档,快速创建Azure批处理任务(快速入门:在 Azure 门户中运行第一个 Batch 作业),在添加作业时,选择"自定义模式",并添加文档中所提供的简单命令 ...

  8. SpringCloud 网关组件Gateway

    官网文档: https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/ 1. 概述 1.1 什么是网关 ...

  9. 在winform中如何嵌入第三方软件窗体✨

    相关win32api的学习 SetParent [DllImport("user32.dll ", EntryPoint = "SetParent")] pri ...

  10. springMvc精简整理

    精简共分步 新建一个web工程  导入核心就二包,因为springmvc 包自己有依赖 <?xml version="1.0" encoding="UTF-8&qu ...