Mybatis系列之------(连接池)、(动态SQL语句)、(事务)、(多表关系操作)、(延迟加载机制)、(Mybatis缓存机制)

1,076 阅读8分钟

今日内容:

  • mybatis中的连接池(原理部分了解,应用部分会用)
  • mybatis基于XML配置的动态SQL语句使用(会用即可)
  • 事务控制
  • 多表关系描述(重点:掌握应用)

1、连接池:

作用:我们在实际开发中都会使用连接池。
        因为它可以减少我们获取连接所消耗的时间。

mybatis中的连接池
mybatis连接池提供了3种方式的配置:
	配置的位置:
		主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是表示采用何种连接池方式。
	type属性的取值:
		POOLED	 采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现
		UNPOOLED 采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想。
		JNDI	 采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。
			 注意:如果不是web或者maven的war工程,是不能使用的。
			 我们课程中使用的是tomcat服务器,采用连接池就是dbcp连接池。

连接池内部底层源码分析:

连接池工作原理介绍: 连接池执行流程图解析 POOLED与UNPOOLED连接池的区别展示

2、基于xml配置的动态SQL语句

mappers配置文件中的几个标签:
	<if>
	<where>
	<foreach>
	<sql>

使用截图:

3、mybatis中的事务

3.1、什么是事务?

事务

简单的说,事务就是一组原子性的 SQL 查询,这一组 SQL 要么全部执行成功,要么全部执行失败。

是计算机应用中不可或缺的组件模型,它保证了用户操作的原子性 ( Atomicity )、一致性 ( Consistency )、隔离性 ( Isolation ) 和持久性 ( Durabilily )。

事务分为本地事务和分布式事务。

通过sqlsession对象的commit方法和rollback方法实现事务的提交和回滚

3.2、事务的四大特性ACID

原子性

一个事务是不可分割的最小工作单元,整个事务要么全部成功,要么全部失败,不可能只执行中间的一部分操作。

一致性:

执行事务是使得数据库从一个一致性状态到另一个一致性状态,如果事务最终没有被提交,那么事务所做的修改也不会保存到数据库中。

隔离性:

通常来说,一个事务提交之前对其他事务是不可见的,但是这里所说的不可见需要考虑隔离级别,比如未提交读在提交前对于其他事务来说也是可见的,隔离级别,在下面会详细讲。

持久性:

事务一旦被提交,那么对数据库的修改会被永久的保存,即使数据库崩溃修改后的数据也不会丢失。

3.4、事务的隔离级别*

SQL 标准中定义了四种隔离级别,这里简单介绍一下这四种隔离级别。

未提交读

未提交读的意思是,事务中的修改,即使没有提交,对其他事务也都是可见的,但是这样会出现脏读,一般情况下,通常都不会使用未提交读。

提交读:

提交读的意思是,一个事务所做的修改在提交之前对其他事务都是不可见的,这个级别也叫做“不可重复读”,因为执行两次相同的操作,可能会得到不同的结果。

可重复读:

可重复读解决了脏读的问题,这个级别保证了同一个事务多次读取同样记录的结果是一致的,但是这个隔离级别无法解决幻读的问题,所谓幻读就是说,当某个事务读取范围数据时,另一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围数据时,会产生幻行。InnoDB 存储引擎通过 MVCC 解决了幻读的问题,可重复读是 MySQL 默认的事务隔离级别。

可串行化:

是最高的隔离级别,避免了前面说到的幻读问题。可串行化会给读取的每一行都加锁,所以可能导致大量超时和锁争用的问题,实际中很少使用这个隔离级别。

3.5、死锁

死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源。解决死锁的方法就是回滚一个或者多个事务。

4、mybatis中的多表查询概述

表之间的关系有几种:
	一对多
	多对一
	一对一
	多对多
举例:
	用户和订单就是一对多
	订单和用户就是多对一
		一个用户可以下多个订单
		多个订单属于同一个用户

	人和身份证号就是一对一
		一个人只能有一个身份证号
		一个身份证号只能属于一个人

	老师和学生之间就是多对多
		一个学生可以被多个老师教过
		一个老师可以交多个学生
特例:
	如果拿出每一个订单,他都只能属于一个用户。
	所以Mybatis就把多对一看成了一对一。

mybatis中的多表查询:
	示例:用户和账户
		一个用户可以有多个账户
		一个账户只能属于一个用户(多个账户也可以属于同一个用户)
	步骤:
		1、建立两张表:用户表,账户表
			让用户表和账户表之间具备一对多的关系:需要使用外键在账户表中添加
		2、建立两个实体类:用户实体类和账户实体类
			让用户和账户的实体类能体现出来一对多的关系
		3、建立两个配置文件
			用户的配置文件
			账户的配置文件
		4、实现配置:
			当我们查询用户时,可以同时得到用户下所包含的账户信息
			当我们查询账户时,可以同时得到账户的所属用户信息

	示例:用户和角色
		一个用户可以有多个角色
		一个角色可以赋予多个用户
	步骤:
		1、建立两张表:用户表,角色表
			让用户表和角色表具有多对多的关系。需要使用中间表,中间表中包含各自的主键,在中间表中是外键。
		2、建立两个实体类:用户实体类和角色实体类
			让用户和角色的实体类能体现出来多对多的关系
			各自包含对方一个集合引用
		3、建立两个配置文件
			用户的配置文件
			角色的配置文件
		4、实现配置:
			当我们查询用户时,可以同时得到用户所包含的角色信息
			当我们查询角色时,可以同时得到角色的所赋予的用户信息

5、Mybatis中的延迟加载

问题:在一对多中,当我们有一个用户,它有100个账户。
      在查询用户的时候,要不要把关联的账户查出来?
      在查询账户的时候,要不要把关联的用户查出来?
	
      在查询用户时,用户下的账户信息应该是,什么时候使用,什么时候查询的。
      在查询账户时,账户的所属用户信息应该是随着账户查询时一起查询出来。

什么是延迟加载
	在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)
什么是立即加载
	不管用不用,只要一调用方法,马上发起查询。

在对应的四种表关系中:一对多,多对一,一对一,多对多
	一对多,多对多:通常情况下我们都是采用延迟加载。
	多对一,一对一:通常情况下我们都是采用立即加载。

6、Mybatis中的缓存

什么是缓存
	存在于内存中的临时数据。
为什么使用缓存
	减少和数据库的交互次数,提高执行效率。
什么样的数据能使用缓存,什么样的数据不能使用
	适用于缓存:
		经常查询并且不经常改变的。
		数据的正确与否对最终结果影响不大的。
	不适用于缓存:
		经常改变的数据
		数据的正确与否对最终结果影响很大的。
		例如:商品的库存,银行的汇率,股市的牌价。
Mybatis中的一级缓存和二级缓存
	一级缓存:
		它指的是Mybatis中SqlSession对象的缓存。
		当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。
		该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中
		查询是否有,有的话直接拿出来用。
		当SqlSession对象消失时,mybatis的一级缓存也就消失了。
	
	二级缓存:
		它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
		二级缓存的使用步骤:
			第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
			         <settings>
                                     <setting name="cacheEnabled" value="true"/>
                                </settings>
			第二步:让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
			        <cache/>
			第三步:让当前的操作支持二级缓存(在select标签中配置)
			    在对应的 select 查询节点中添加 useCache=true

写在最后

推荐自己的Github地址:github.com/Lmobject

您的点赞与关注是对作者最大的支持与鼓励。且行且珍惜。