Mybatis

1.Mybatis简要概述

1.1 什么是Mybatis

(1)MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

1.2 什么是持久层

(1)持久层就是数据持久化:持久化就是将程序的数据在持久状态和瞬时状态转化的过程

(2)完成持久化工作的代码块

2.配置详解

2.1 环境配置(environments)

(1)MyBatis 可以配置成适应多种环境,不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。即每个数据库对应一个SqlSessionFactory 实例
在这里插入图片描述
1.<environments id =“development”>:

	1. id = development 默认使用的环境ID

2.<development id=“development”>:

	1. id = "development" 环境ID

3.<transactionManager type=“JDBC”>

	1. 在 MyBatis 中有两种类型的事务管理器 JDBC/MANAGED.
	2. i.JDBC:这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
	3. ii.MANAGED:这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期
	4. Mybatis默认使用的是JDBC

4.<dataSource type=“POOLED”>

a)dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。

b)有三种内建的数据源类型UNPOOLED POOLED  JNDI

PS:Mybatis连接池默认使用的是POOLED

PS:<dataSource type=“POOLED”>下面的就是你的数据库连接信息了

2.2 属性(properties)

PS:在外部创建一个xxx.properties文件,输入一下信息
在这里插入图片描述
PS:引入外部的xx.properties文件
在这里插入图片描述

  1. 这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置

2.3 类型别名(typeAliases)

  1. 给实体类全类路径起别名
    在这里插入图片描述
    在这里插入图片描述
  2. 给包起别名
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

PS:给包起别名如果不去实体类使用注解的话,默认别名为该实体类的首字母小写(比如UserName实体类即为userName)

2.4 设置(Settings)

(1)这个可前往官网查看:https://mybatis.org/mybatis-3/zh/configuration.html#settings

2.5 映射器(mappers)

  1. MapperRegistry:注册绑定我们的Mapper文件
  2. 绑定方式1:
    在这里插入图片描述
  3. 绑定方式2:
    在这里插入图片描述
    在这里插入图片描述
  4. 绑定方式3:
    在这里插入图片描述
    PS:映射文件与dao层的接口名字需一致,不然报如下错误
    在这里插入图片描述

3.生命周期和作用域

3.1 SqlSessionFactoryBuilder

① 这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了

② 因此SqlSessionFactoryBuilder实例的最佳作用域是方法作用域。即局部方法变量

3.2 SqlSessionFactory

①SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。它不需要多次创建。

②因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式

3.3 SqlSession

①每个线程都应该有它自己的 SqlSession 实例。

②SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域

③因此,我们需要在每次用完之后,赶紧关闭,否者资源会被占用。

4.resultMap(结果集映射)

4.1 问题演示

(1) 问题:当数据库字段跟实体类字段不一致时,就会出现获取到的内容为null的情况
(2) 解决:采用resultMap结果集映射–如下
在这里插入图片描述
其实这个只要将字段不一样的去映射就可以了,不必要一样的还去映射一遍(如下)
在这里插入图片描述

5.日志

5.1 开启日志等演示

(1)怎么开启日志:在mybatis核心配置文件开启
在这里插入图片描述
(2)开启Log4j日志工厂
①需要先导入log4j的jar包
在这里插入图片描述
②去mybatis核心配置文件设置
在这里插入图片描述
③创建一个log4j.properties文件
在这里插入图片描述
④PS:日志对象,参数为当前类的class。日志对象的创建及用处如下图
在这里插入图片描述

6.分页

6.1 利用sql语句limit进行分页

PS:先写好一个sql语句
在这里插入图片描述
PS:接口定义好,使用万能的map来传参数
在这里插入图片描述
PS:编写测试类
在这里插入图片描述

7.使用注解开发

7.1 使用java注解(编写查询)

PS:在dao层接口方法上注解输入sql语句
在这里插入图片描述
PS:使用class文件注册绑定映射
在这里插入图片描述
PS:其它sql操作万变不离其宗。
在这里插入图片描述
在这里插入图片描述
PS:不想要每次增删改都手动提交,可以改 如图
在这里插入图片描述

8.多对一的处理(association:关联)

8.1 按照结果嵌套处理

PS:Student类
在这里插入图片描述
PS:Mapper.xml的查询语句编写
在这里插入图片描述

8.2 按照查询嵌套处理: 即子查询

PS:Student实体类上方有,就不贴出来了,直接上xml配置
在这里插入图片描述

9.一对多的处理(collection:集合)

9.1 按照结果嵌套处理

PS:Teacher实体类
在这里插入图片描述
PS:Mapper.xml查询语句编写
在这里插入图片描述

9.2 按照查询嵌套处理: 即子查询

PS:实体类上面有了,就不重复了,Mapper.xml编写
在这里插入图片描述

9.3 总结一下多对一与一对多

(1) 关联使用:association(多对一)
(2) 集合使用:collection(一对多)
(3) javaType和ofType

1)javaType用来指定实体类中属性的类型
2)ofType用来指定映射到list或者集合中的实体类类型,即泛型中的约束类型

10.动态SQL

10.1 什么是动态SQL

(1)动态SQL就是根据不同的条件生成不同的SQL语句

10.2 动态SQL之IF

PS:接口方法
在这里插入图片描述
PS:SQL编写
在这里插入图片描述
PS:测试
在这里插入图片描述

10.3 动态SQL语句之choose when otherwise

PS:接口方法
在这里插入图片描述
PS:SQL编写
在这里插入图片描述
PS:测试代码
在这里插入图片描述

10.4 动态SQL之set

PS:接口方法
在这里插入图片描述
PS:SQL编写
在这里插入图片描述

PS:测试
在这里插入图片描述
PS:这里还有个重要的点(这是官网的说法,可以理解一下)mybatis官网
在这里插入图片描述

10.5 动态SQL之foreach

PS:接口方法
在这里插入图片描述
PS:SQL编写
在这里插入图片描述
PS:测试代码
在这里插入图片描述

10.6 SQL片段

(1)SQL片段就是,当我们发现有些部分可以复用的时候,我们使用SQL片段将可以复用的部分提取出来
在这里插入图片描述

11.缓存

11.1 什么是缓存

(1)存在内存中的临时数据

(2)将用户经常查询的数据放在缓存中,用户去查询数据就不用从磁盘上查询,而是从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题

11.2 为什么使用缓存

(1)减少和数据库的交互次数,减少系统开销,提高系统效率

(2)当我们经常查询但是不经常改变的数据,就可以使用缓存

11.3 一级缓存

(1)一级缓存也叫本地缓存

(2)与数据库同一次会话期间查询的数据会放到本地缓存中,以后要用到这些数据的时候直接从缓存中拿,不需要再去查询数据库。

(3)一级缓存结束于你关闭SqlSession的时候。

(4)测试一级缓存
在这里插入图片描述
(5)缓存失效的情况:

1)使用更新 插入 删除语句的时候,缓存会更新,即失效。
2)关闭连接也会失效
3)手动清理缓存
4)不同Mapper文件

在这里插入图片描述

11.4 二级缓存

1.二级缓存也叫全局缓存
2.基于namespace级别的缓存,一个名称空间对应一个二级缓存
3.工作机制

1)一个会话查询到一条数据,这个数据就会被放在当前会话的一级缓存中。
2)如果会话关闭了,这个会话的一级缓存就没了,但是我们想要的是,这个一级缓存关闭了,数据会保存到二级缓存中
3)新的会话查询信息,就可以从二级缓存中获取内容。
4)不同的mapper查处的数据会放在自己对应的缓存中

4.开启二级缓存步骤:

···4.1先去mybatis核心配置文件开启cacheEnabled(虽然它默认就是true)···
在这里插入图片描述
···4.2 在当前Mapper.xml中使用二级缓存···
在这里插入图片描述
···4.3 注意点:一般记得要序列化实体类···
在这里插入图片描述
PS:二级缓存注意点:二级缓存是在一级缓存关闭之后才会将数据放到二级缓存的

11.5 缓存的一个原理(执行顺序)

1.缓存的一个原理(执行顺序)

1. 先去二级缓存里查看是否有想要的数据,有就直接取
2. 二级缓存没有再去一级缓存里查看是否有,有就直接取
3. 如果一级缓存也没有,再去数据库查询,然后数据查询到的会放在一级缓存里,一级缓存关闭数据会放到二级缓存里去。大致就是这么个流程

12.自定义缓存

12.1 流程讲解

(1)首先老规矩先导包

<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.2.1</version>
</dependency>

(2)然后配置ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">
    <!--
       diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
       user.home – 用户主目录
       user.dir  – 用户当前工作目录
       java.io.tmpdir – 默认临时文件路径
     -->
    <diskStore path="java.io.tmpdir/Tmp_EhCache"/>
    <!--
       defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
     -->
    <!--
      name:缓存名称。
      maxElementsInMemory:缓存最大数目
      maxElementsOnDisk:硬盘最大缓存个数。
      eternal:对象是否永久有效,一但设置了,timeout将不起作用。
      overflowToDisk:是否保存到磁盘,当系统当机时
      timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
      timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
      diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
      diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
      diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
      memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
      clearOnFlush:内存数量最大时是否清除。
      memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
      FIFO,first in first out,这个是大家最熟的,先进先出。
      LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
      LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
   -->
    <defaultCache
            eternal="false"
            maxElementsInMemory="10000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="259200"
            memoryStoreEvictionPolicy="LRU"/>
  
    <cache
            name="cloud_user"
            eternal="false"
            maxElementsInMemory="5000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="1800"
            memoryStoreEvictionPolicy="LRU"/>
  
</ehcache>

在这里插入图片描述
PS:结束,希望众位可以指出问题或者补充

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值