标题 MyBtatis框架使用
一.MyBatis 简介: 封装 JDBC 操作,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
利用反射打通 java 类与 SQL 语句之间的相互转换。
可以使用单的 XML或注解用于配置和原始映射,将接口和 Java的 POJO(Plain Old Java
Objects,普通的 Java 对象)映射成数据库中的记录。
其是一个半自简动 ORM(Object Relation Mapping 对象关系映射)框架 Hibernant 是
全自动的。
个人总结:MyBatis 是支持定制化 SQL,存储过程以及高级映射的优秀的持久层框架。
二.ORM 介绍:
因为要满足 java 对象得到持久化(即保存)的需求。
ORM:(Object/Relation Mapping):对象,关系映射。
ORM 的实现思想:
将关系数据库中的记录映射成为对象,以对象的形式展现,程序员可以把数据库的
操作转为对象的操作;
三.MyBatis 的优点:
基于 SQL 语句编程,相当灵活。不会对应用程序或者数据库的现有设置造成任何影响。
SQL 语句写在 XML 中,减少 SQL 语句与程序代码的耦合,便于统一管理。
提供 XML 标签,支持编写动态 SQL 语句,并可重用。
与 JDBC 相比减少了 50%的代码量,消除的 JDBC 大量冗余的代码,不需要手动开关连
接。
很好的与各种数据库兼容(因为 MyBatis 是使用 JDBC 连接数据,所以只要 JDBC 支持
的数据库 MyBatis 都支持)。
能够与 Spring 很好的集成。
提供映射标签,支持对象与数据库的 ORM 字段关系映射。
提供对象映射标签,支持对象关系组件维护。
对于开发人员而言,核心 sql 发送需要自己优化。
对于程序来说,sql 和 java 代码分开,功能便捷清洗,一个专注业务,一个专注数据。
四.MyBatis 的缺点:
SQL 语句的编写工作量较大,尤其当字段多,关联表多时,对开发人员编写 SQL 语句
的功底有一定 的要求。
SQL 语句依赖于数据库,导致数据库一致性差,不能随意更换数据库。
五.MyBatis 框架的使用场合:
MyBatis 专注于 SQL 本身,是一个足够灵活的 DAO 层解决方案。
对性能的要求性很高,或者需求变化较多的项目,如互联网项目,MyBatis 是个不错的
选择。
六.MyBatis 中#{}与${}的区别: #{} :是预编译处理
MyBatis 在处理#{}时会将 SQL 中的#{}替换为?号,调用 PreparedStatemen(预编译
语句对象)t 的 set 方法来赋值。
KaTeX parse error: Unexpected character: '' at position 13: {}: 是字符串替换。 ̲ MyBatis 在处理{}时,就是把${}的值替换成变量的值。
使用#{}可以有效的防止 SQL 注入,提高系统安全性。
七.MyBatis 缓存机制:
作用: 提高应用查询效率。
查找顺序: 二级开启从二级找,二级缓存未开启从一级缓存(Map:返回类型 resuleMap)查
找。
一级缓存特点: 生命周期:MyBatis 的生命周期和 SqlSession 一致。
同一个会话(SqlSession)默认开启,基于内存储存,关闭会话一级缓存数据被清除或
者显示调用清空缓存方法。
使用:
在 MyBatis 配置文件中设置(mytatis-config.xml)
SESSION:默认开启一级缓存。这种情况下会缓存一个会话中执行的所有查询
STATEMENT: 本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将
不会共享数据。
个人理解:①如果在一级缓存开启时,修改了数据库中的值,在执行相同查询,
一级缓存失效,会在次向数据发发送一次查询。
详情博客地址:https://www.cnblogs.com/zhuzhu-you/p/13888596.html
二级缓存特点: 同一个 namespace,进程缓存,基于内存+硬盘,默认不开启,需要手动开启。 使用:
在 MyBatis 配置文件中设置(mytatis-config.xml)
详情博客地址:https://www.cnblogs.com/zhuzhu-you/p/13888596.html
八.MyBatis 延迟加载:
MyBatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association
指的是一对一,collection 指的是一对多查询。在 MyBatis 配置文件中,可以配置是否
请用延迟加载 lazyLoadingEnabled=true|false。
延迟加载:在真正使用数据的时候才发起查询,不用的时候不查询关联的数据,延迟加
载又叫按需查询(懒加载);
立即加载:不管用不用,只要一调用方法,马上发起查询。 使用场景:在对应的四种表关系中,一对多、多对多通常情况下采用延迟加载,多对一、
一对一通常情况下采用立即加载。
详情博客地址:https://www.cnblogs.com/zhuzhu-you/p/13892794.html
九.MyBatis 实行一对一的操作方式
联合查询
几个表联合查询,只查询一次,通过在 resuleMap 里面配置 association 节点配置
一对一的类就可以完成。
嵌套查询
先查一个表,根据这个表里面的外键 id,再去另一个表里面查询数据,也是通过
association 配置,但另一个表的查询通过 select 属性配置。
十.MyBatis 实行一对多的操作方式
有联合查询和嵌套查询
联合查询
联合查询是几个表联合查询,只查询一次,通过在 resultMap 里面配置
collection 标签配置一对多的类就可以完成。
嵌套查询
嵌套查询是先查一个表,根据这个表里面给过的外键 id,再去另一个表里查
询数据,也是通过配置 collection,当另外一个表查询通过 select 节点配置。
十一. MyBatis 工作的基本流程
读取配置文件(mytatis-config.xml),配置文件包含数据库连接信息和 Mapper 映射文件
或者 Mapper 包路径。
有了这些信息就能创建 SqlSessionFactory,SqlSessionFatory 的生命周期是程序级,程序
运行的时候建立起来,程序结束的时候消亡。
SqlSessionFactory 建立 SqlSession,目的执行 sql 语句,SqlSession 是过程级,一个方法
中建立,方法结束应该关闭(close());
当用户使用 mapper.xml 文件中的配置的方法时,mybatis 首先会解析 sql 动态标签为对
应数据路 sql 语句的形式,并将其封装进 MapperStatement 对象,然后通过 executor
将 sql 注入数据库执行,并返回结果。
将返回的结果通过映射,包装成 java 对象
十二. MyBatis 全局配置文件简介
文件结构如下:
configuration 配置
properties 属性
Settings 设置
typeAliases 类型命名
typtHandlers 类型处理器
objectFactory 对象工厂
plugins 插件
MyBatis 使用
5 environments 环境
environment 环境变量
transactionManager 事务管理器
dataSource 数据源
databaseldProvider 数据库厂商标识
mappers 映射器
十三.常用 Settings 设置
打印执行过程
开启二级缓存
开启延迟加载
设置加载的数据是按需还是全部
其他设置详情博客:https://www.cnblogs.com/zhuzhu‐you/p/MyBaitsSettings.html
十三. 开发环境的准备
(1) 导入 log4j,MyBatis,MySql,测试,依赖 jar 包
(3) 创建数据库资源文件 db.properties
(4) Mapper.xml
十四. 创建 MyBatis 项目实现数据库的增删改查
详情博客: https://www.cnblogs.com/zhuzhu‐you/p/13850967.html
十五. typeAliases 别名处理
类型别名是为 Java 类型设置一个短的名字,可以方便我们引用某个类。
**
十六.MyBatis 已经取好的别名,用户返回和传入
(parameterType,reslutType…)
十七.Mapper 映射器
用来在 mybatis 初始化的时候,告诉 mybatis 需要引入哪些 Mapper 映射文件。
mapper 逐个注册 SQL 映射文件
resource : 引入类路径下的文件 。
url : 引入网络路径或者是磁盘路径下的文件。
class : 引入 Mapper 接口。
有 SQL 映射文件 , 要求 Mapper 接口与 SQL 映射文件同名同位置.。 没有 SQL 映射文件 , 使用注解在接口的方法上写 SQL 语句。
使用批量注册,这种方式要求 SQL 映射文件名必须和接口名相同并且在同一目录下
十八. MyBatis 映射文件(写 sql 的 Mapper.xml)
- SQL 映射文件有很少的几个顶级元素(按照它们 MyBatis 的真正强大在于它的映射语
句,也是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如
果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代
码。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。 - 应该被定义的顺序):
cache – 给定命名空间的缓存配置。
cache-ref – 其他命名空间缓存配置的引用。
resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加
载对象。
parameterMap – 已废弃!老式风格的参数映射。内联参数是首选,这个元素可
在将来被移除,这里不会记录。
sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语
具体详情:https://www.cnblogs.com/zhuzhu‐you/p/13850967.html
十八.参数传递
(1)参数传递的方式 - 单个参数
可以接受基本类型,对象类型。这种情况 MyBatis 可直接使用这个参数,不需要经过任
何处理。 - 多个参数
任意多个参数,都会被 MyBatis 重新包装成一个 Map 传入。Map 的 key 是 param1,
param2,或者 0,1…,值就是参数的值 - 命名参数
为参数使用@Param 起一个名字,MyBatis 就会将这些参数封装进 map 中,key 就是我
们自己指定的名字 - POJO
当这些参数属于我们业务 POJO 时,我们直接传递 POJO - Map
我们也可以封装多个参数为 map,直接传递 - Collection/Array
会被 MyBatis 封装成一个 map 传入, Collection 对应的 key 是 collection,Array 对应的 key
是 array. 如果确定是 List 集合,key 还可以是 list.
(2)参数处理 - 参数位置支持的属性:
javaType、jdbcType、mode、numericScale、resultMap、typeHandler、jdbcTypeName、
expression - 实际上通常被设置的是:可能为空的列名指定 jdbcType ,例如:
(3)参数的获取方式 - #{key}:可取普通类型、POJO 类型、多个参数、集合类型
获取参数的值,预编译到 SQL 中。安全。Preparedstatement -
k
e
y
:
可
取
单
个
普
通
类
型
、
P
O
J
O
类
型
、
多
个
参
数
、
集
合
类
型
注
意
:
取
单
个
普
通
类
型
的
参
数
,
{key}:可取单个普通类型、POJO 类型、多个参数、集合类型 注意:取单个普通类型的参数,
key:可取单个普通类型、POJO类型、多个参数、集合类型注意:取单个普通类型的参数,{}中不能随便写 必须用_parameter
_parameter 是 Mybatis 的内置参数
获取参数的值,拼接到 SQL 中。有 SQL 注入问题。Statement ORDER BY KaTeX parse error: Expected 'EOF', got '#' at position 13: {name} 原则:能用#̲{}取值就优先使用#{} 解决…{}
e.g.原生的 JDBC 不支持占位符的地方 就可以使用${}
e.g.Select column1,column2…from 表 where 条件 group by 组表示 having 条件
order by 排序字段 desc/asc limit X,X;
十九. select 查询的几种情况 - 查询单行数据返回单个对象
public Employee getEmployeeById(Integer id ); - 查询多行数据返回对象的集合
public List getAllEmps(); - 查询单行数据返回 Map 集合
public Map<String,Object> getEmployeeByIdReturnMap(Integer id ); - 查询多行数据返回 Map 集合
@MapKey(“id”) // 指定使用对象的哪个属性来充当 map 的 key(对象的属
性,而不是数据库的列)
public Map<Integer,Employee> getAllEmpsReturnMap();
二十.resultType 自动映射 - autoMappingBehavior 默认是 PARTIAL,开启自动映射的功能。唯一的要求是列名
和 javaBean 属性名一致 - 如果 autoMappingBehavior 设置为 null 则会取消自动映射
- 数据库字段命名规范,POJO 属性符合驼峰命名法,如 A_COLUMN aColumn,我
们可以开启自动驼峰命名规则映射功能,mapUnderscoreToCamelCase=true
缺点:多表查询 完成不了
二十一. resultMap 自定义映射 - 自定义 resultMap,实现高级结果集映射
- id :用于完成主键值的映射
- result :用于完成普通列的映射
- association :一个复杂的类型关联;许多结果将包成这种类型
- collection : 复杂类型的集
- Id&reslut:
- POJO 中的属性可能会是一个对象,我们可以使用联合查询,并以级联属性
的方式封装对象.使用 association 标
签定义对象的封装规则。
- 使用级联的方式:
- Association
- Association 分布查询的应用:
实际的开发中,对于每个实体类都应该有具体的增删改查方法,也就
是 DAO 层,因此
对于查询员工信息并且将对应的部门信息也查询出来的需求,就可以
通过分步的方式
完成查询。
先通过员工的 id 查询员工信息
再通过查询出来的员工信息中的外键(部门 id)查询对应的部门信息.
association 分步查询使用延迟加载
在分步查询的基础上,可以使用延迟加载来提升查询的效率,只
需要在全局的
Settings 中进行如下的配置:
- Collection
POJO 中的属性可能会是一个集合对象,我们可以使用联合查询,并以
级联属性的方式封装对象.使用 collection 标签定义对象的封装规则。
Collction(mapper.xml)
- Collecton 分布查询
实际的开发中,对于每个实体类都应该有具体的增删改查方法,也就
是 DAO 层,因此对于查询部门信息并且将对应的所有的员工信息也查
询出来的需求,就可以通过分步的方式完成查询。
先通过部门的 id 查询部门信息
再通过部门 id 作为员工的外键查询对应的部门信息
二十二.collection 和 association 的 fetchType 的属性介绍
在 和标签中都可以设置 fetchType,指定本次查询是否要使
用延迟加载。默认为 fetchType=”lazy” ,如果本次的查询不想使用延迟加载,则可设置
为
fetchType=”eager”.
fetchType 可以灵活的设置查询是否需要使用延迟加载,而不需要因为某个查询不想使
用延迟加载将全局的延迟加载设置关闭.
二十三.MyBatis 动态 sql 使用 - 简介:
a. 动态 SQL 是 MyBatis 强大特性之一。极大的简化我们拼装 SQL 的操作
b. 动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似
c. MyBatis 采用功能强大的基于 OGNL 的表达式来简化操作
a) If
b) choose(when,otherwise)
c) trim(where,set)
d) Foreach
d. OGNL( Object Graph Navigation Language )对象图导航语言,这是一种强大的
表达式语言,通过它可以非常方便的来操作对象属性。 类似于我们的 EL,SpEL
等。
a) 访问对象属性: person.name
b) 调用方法:person.getName()
c) 调用静态属性/方法: @java.lang.Math@PI ,
@java.util.UUID@randomUUID()
d) 调用构造方法: new com.atguigu.bean.Person(‘admin’).name
e) 运算符:+,-*,/,%
f) 逻辑运算符:in,not in,>,>=,<,<=,==,!=
注意:xml 中特殊符号如”,>,<等这些都需要使用转义字符。 - If where 的使用
a. Where 用于解决 SQL 语句中 where 关键字以及条件中第一个 and 或者 or 的问题
- trim 的使用
a. Trim 可以在条件判断完的 SQL 语句前后 添加或者去掉指定的字符。
b. prefix: 添加前缀。
c. prefixOverrides: 去掉前缀。
d. suffix: 添加后缀。
e. suffixOverrides: 去掉后缀
- Set 的使用
a. set 主要是用于解决修改操作中 SQL 语句中可能多出逗号的问题
在这里插入图片描述
- choose(when、otherwise)
a. choose 主要是用于分支判断,类似于 java 中的 switch case,只会满足所有分支
中的一个
- Foreach 的使用
a. foreach 主要用户循环迭代
b. collection: 要迭代的集合
c. item: 当前从集合中迭代出的元素
d. open: 开始字符
e. close:结束字符
f. separator: 元素与元素之间的分隔符
g. index:
迭代的是 List 集合: index 表示的当前元素的下标
迭代的 Map 集合: index 表示的当前元素的 k
- 动态 sql 的使用
a. sql 标签是用于抽取可重用的 sql 片段,将相同的,使用频繁的 SQL 片段抽取
出来,单独定义,方便多次引用。
b. 抽取 SQL:
二十四.resultType 和 resultMap 的区别
概述:
resultType 和 resultMap 功能类似 ,都是返回对象信息 ,但是 resultMap 要更强大一些 ,
可自定义。因为 resultMap 要配置一下,表和类的一一对应关系,所以说就算你的字段名和你
的实体类的属性名不一样也没关系,都会给你映射出来,但是,resultType 就比较鸡肋了,必
须字段名一样,比如说 cId 和 c_id 这种的都不能映射 。下面介绍几个常用的映射关系:
resultMap:描述如何将结果集映射到 java 对象。
resultMap 属性:id,type。
resultMap 的子元素:id,result,association,collection。
区别: resultType:直接返回类型。
resultMap:对外部 resultMap 的引用。
二者不能存在
应用上的区别
resultType: 当使用 resultType 做 SQL 语句返回结果类型处理时,对于 SQL 语句查询出的字段在相应的 pojo 中必须有
和它相同的字段对应,而 resultType 中的内容就是 pojo 在本项目中的位置,适用于单表查询。
resuleMap:
当使用 resultMap 做 SQL 语句返回结果类型处理时,通常需要在 mapper.xml 中定义 resultMap 进行 pojo
和相应表字段的对应。
resultMap 对于一对一表连接的处理方式通常为在主表的 pojo 中添加嵌套另一个表的 pojo,然后在
mapper.xml 中采用 association 节点元素进行对另一个表的连接处理。
resultType 是直接表示返回类型的(对应着我们的 model 对象中的实体)。
resultMap 则是对外部 ResultMap 的引用 (提前定义了 db 和 model 之间的隐射 key–>value 关系 ),但是
resultType 跟 resultMap 不能同时存在。
二十五.association 和 collection 的区别
association: 处理一对一、多对一
collection: 处理一对多
详情博客:https://www.jianshu.com/p/d01a6250ba13