Mybatis基础

ORM模型

Java程序都是通过JDBC连接数据库的,由于JDBC存在缺陷,在实际工作中提出来对象关系映射(ORM)

ORM模型就是数据库的表和简单Java对象的映射关系模型,它主要解决数据库数据和POJO对象的相互映射关系。通过这层映射关系就可以简单迅速地把数据库表的数据转化为POJO

Mybatis简介

一个半自动化映射框架,需要手动配置提供POJO、SQL和映射关系。Mybatis可配置动态SQL,也能通过配置决定SQL映射关系,支持存储过程。Mybatis是针对映射器构建的SQL构建的轻量级框架,也支持自动绑定Javabean

Mybatis核心组件

  • SqlSessionFactoryBuilder(构造器):它会根据配置信息或者代码来生成SqlSessionFactory(工厂接口)
  • SqlSessionFactory:依赖工厂来生成SqlSession(会话)
  • SqlSession:是一个既可以发送SQL去执行并返回结果,也可以获取Mapper的接口
  • Mapper:它是Mybatis新设计的组件,它是一个Java接口和XML文件(或注解)构成,需要给出对应的SQL和映射规则它负责发送SQL去执行,并返回结果。
    Mybatis构成

    核心组件生命周期

SqlSessionFactoryBuilder:是利用XML或者Java编码获取资源来构建SqlSessionFactory的,它可以构建多个SessionFactory,它的作用就是一个构建器,一旦构建成功就失去了意义,因此它的生命周期只存在方法的局部。

SqlSessionFactory:它的作用是创建SqlSession,而SqlSession是一个会话,相当于JDBC里面的connection对象,每次应用程序访问数据库,我们就需要通过SqlSessionFactory来构建SqlSession,所以SqlSessionFactory的生命周期在Mybatis应用的整个生命周期内。为进行统一管理与避免资源浪费,SqlSessionFactory应采用单例模式进行统一创建SqlSession,并且每一个数据库对应一个SqlSessionFactory。

SqlSession:SqlSession是一个会话,相当于JDBC里面的connection对象,它的生命周期应该是请求数据库处理事务的过程中,它是一个线程不安全的对象,在设计多线程应注意隔离级别等。在执行完事务之后,应该及时关闭SqlSession。数据库事务交由SqlSession控制,可通过SqlSession提交和回滚。

Mapper:Mapper是一个接口,它没有任何实现类,它的作用是发送SQL,然后返回结果。或者执行SQL从而修改数据库的数据,它应该在SqlSession事务方法之内, 是一个方法级的对象,它就像JDBC中的一条SQL语句执行,最大的周期范围与SqlSession相同。
Mybatis组件生命周期

映射器

映射器定义了命名空间,命名空间对应的是一个接口的全路径,而不是实现类。我们使用这个接口能调度我们想要的SQL,并组装我们需要的结果。

public interface ProcessDefinitionMapper extends BaseMapper<ProcessDefinition> {

    ProcessDefinition queryByDefineName(@Param("projectId") int projectId,
                                        @Param("processDefinitionName") String name);
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper">
     <select id="queryByDefineName"        resultType="映射对象全路径">
         sql语句
    </select>
</mapper>

主要元素

  • select:查询语句,最常用、最复杂的元素之一,可自定义参数,返回结果集等。
  • insert:插入语句,执行后返回插入条数整数
  • update:更新语句,执行后返回更新条数整数
  • delete:删除语句,执行后返回删除条数整数
  • parameterMap: 定义映射关系,不适用
  • sql: 定义一部分SQL,然后可在各个地方引用。
  • resultMap:用来描述从数据库结果集中来加载对象,提供映射规则
  • cache:给定命名空间的缓存配置
  • cache-ref:其他命名空间缓存配置的引用

自动映射可以在setting元素中配置autoMapppingBehavior属性值来设置其策略,它包含:

  • NONE:取消自动映射
  • PARTIAL:只会自动映射,没有定义嵌套结果集映射的结果集。(默认)
  • FULL:会自动映射任意复杂的结果集(无论是否嵌套)

select元素部分配置信息详解:

  • flushCache:它的作用是调用SQL后,是否要求Mybatis清空之前查询的本地缓存和二级缓存。取值为bool类型,默认值为false
  • useCache:启动二级缓存的开关,要求是否将此次结果缓存。取值为bool类型,默认值为true

insert元素部分配置信息详解:

  • keyProperty:表示以哪个列作为属性的主键,不能和keyColumn同时使用,如果是联合主键可以用逗号将其隔开。
  • useGeneratedKeys:这会令Mybstis使用JDBC的getGeneratedKeys方法获取出数据库内部生成的主键。但是使用它必须要给keyProperty或者keyColumn赋值,取值为bool类型, 默认值为false
  • keyColumn:指定第几列为主键。

有时候需要根据一些特殊的关系设置主键的id的值。假设我们取消表t_role的id自增的规则,我们的要求是:如果表t_role没有记录,则我们设置id=1,否则我们就取最大id加2,来设置新的主键,对于特殊的要求,mybatis也需要应对方法。

<insert id="insertRole" parameterType="role" useGeneratedKeys="true" keyProperty>
    <selectKey keyProperty="id" resultType="int" order="BEFORE">
        select if(max(id) is null, 1, max(id)+2) as newId from t_role
    </selectKey>
    insert into t_role(id,role_name,note) values(#{id},#{roleName},#{note})
</insert>

联级与延迟加载

mybatis中联级分为3类,分别为association(一对一)、collection(一对多)、discriminator(鉴别器、根据实际选择特定的条件关联不同的结果集)

由于多级联级中获取一个对象时会把所有的信息都取出来,这样会造成SQL执行过多导致性能下降,这就是N+1问题,为了解决这个问题,可采用延迟加载功能。

延迟加载一开始不取出联级数据,只有当使用它才会发送SQL去取回数据。在mybatis中,延迟加载有俩个全局参数lazyLoadingEabledagressiveLazyLoading

lazyLoadingEabled的含义是是否开启延迟加载功能。agressiveLazyLoading的含义是对任意延迟属性的调用会使带有延迟加载属性的对象完整加载;反之,每种属性都将按需加载。

上面俩种属性都是针对全局延迟加载而言的,当然mybatis也有局部延迟加载的功能,可在association跟collection元素加上属性值fetchType,它有俩种取值范围,分别为eager和lazy,默认值为eager。一旦配置它,该查询它将覆盖全局延迟属性。

缓存(cache)

使用缓存的关键点存储内容访问的命中率

系统缓存(一级缓存与二级缓存)

mybatis对缓存提供支持,但是在没有配置的默认情况下,mybatis只开启一级缓存(一级缓存只相对于Sqlsession而言)

一级缓存即对同一个Sqlsession对象调用同一个Mapper方法,则会调用缓存,不会再次请求数据库。即一级缓存针对Sqlsession隔离。

二级缓存使得缓存在SqlSessionFactory层面提供各个Sqlsession对象共享。实现二级缓存的时候,Mybatis要求返回的POJO对象必须是可序列化的,即需要实现Serializable接口,配置方法只需要在映射的XML文件中开启缓存即可。

动态SQL

Mybatis的动态SQL包含以下几种与元素

  • if :判断语句,单条件分支判断,与test属性联合使用,test为条件判断语句
  • choose(when、otherwise):多条件分支判断‘
  • trim(where、set):辅助元素,
  • foreach:循环语句,在in语句等列举条件常用

Mybtis的解析和运行原理

Mybtis的运行分为俩大部分,一部分是读取配置文件缓存到Configuration对象,用以创建SqlSessionFactory,第二部分是SqlSession对象的执行过程。底层是反射技术与动态代理对象技术

Mapper是mybatis中的一个接口,采用的是JDK动态代理,而JDK动态代理使用反射技术实现调用方法前后调用需要的相应方法。

SqlSession下的四大对象

Mapper其实就是一个动态代理对象,进入到MapperMethod的execute方法,它经过简单判断就进入SqlSession的删除、更新、插入、选择等方法。Mapper执行过程是通过Executor、StatementHandler、ParameterHandler、ResultHandler来完成数据库操作和结果返回的。

  • Executor代表执行器,由它来调度StatementHandler、ParameterHandler、ResultHandler来执行对应的SQL
  • StatementHandler(数据库会话器)的作用是使用数据库的statement(preparedstatement)来执行操作,它是四大对象的核心,起到承上启下的作用
  • ParameterHandler(参数处理器)用于SQL对参数的处理
  • ResultHandler(结果处理器)进行最后数据集(ResultSet)封装并返回的
    sqlsession内部运行机制