MyBatis概述

MyBatis学习
(一)MyBatis概述

传统JDBC劣势
1、代码繁琐
2、表关系维护复杂
3、硬编码
4、性能问题

ORM框架概念 -- Object-Relation Mapping 对象关系映射
ORM是一种规范,将简单Java对象(POJO)和数据库进行映射,使数据库表中的记录和POJO对象一一对应。
在Java应用领域流行的ORM框架有Hibernate、MyBatis等,

1、Hibernate 
    封装性好,开发人员通过XML映射文件(或注解)定义好映射规则后,H 根据规则自动生成SQL语句并调用JDBC的API执行。
    无法根据不同条件组装不同SQL
    对多表关联和复杂SQL查询支持较差
    不能有效支持SQL优化
    。。。等

2、MyBatis 
    手动提供POJO、SQL语句并匹配映射关系。
    半自动化的ORM框架
    核心思想:剥离出程序中大量SQL语句并将这些SQL语句配置到映射文件中。
    支持动态列、动态表名、存储过程,简易日志,缓存和级联功能

MyBatis功能架构
API接口层 数据查询、新增、更新、删除等接口,获取配置接口
数据处理层 参数映射 -> SQL解析 -> SQL执行 -> 结果映射
基础支持层 连接管理、事务管理、配置加载、缓存处理、配置框架

MyBatis工作流程
配置文件
-->SqlSessionFactory -> SqlSession(核心对象) -> Executor(执行器) -> MappedStatement
映射文件

MyBatis重要API(具体API、网上查阅)
SqlSession: 首要作用是持久化操作。生命周期为数据库处理事务的过程,要及时关闭。
SqlSession线程不安全,应注意多线程状态下的SqlSession对象,操作时注意隔离级别、数据库锁

SqlSessionFactory:创建SqlSession对象,SqlSessionFactory对象由SqlSessionFactoryBuilder对象创建 .build()方法
    .build()方法的两种形式
        SqlSessionFactory build(InputStream inputStream [, String environment] [, Properties props])
        SqlSessionFactory build(Configuration config)
        
SqlSession: 由SQLSessionFactory对象的openSession()方法创建
    .openSession()有多种形式 具体查表 常用的有
        SqlSession openSession()
    T selectOne(String statement)
    Map selectMap(String statement, String mapKey)
    T getMapper(Class type) 获取映射器
    ... == 还有很多
    
Executor:Executor(执行器)接口有两个实现类,其中BaseExecutor有三个继承类分别是
    BatchExecutor(重用语句并执行批量更新),
    ReuseExecutor(重用预处理语句prepared statement,跟Simple的唯一区别就是内部缓存statement),
    SimpleExecutor(默认,每次都会创建新的statement)。以上三个就是主要的Executor。
    Mybatis在Executor的设计上面使用了装饰器模式,
    我们可以用CachingExecutor来装饰前面的三个执行器目的就是用来实现缓存。
    
MappedStatement:MappedStatement就是用来存放我们SQL映射文件中的信息包括sql语句,输入参数,输出参数等等。
        一个SQL节点对应一个MappedStatement对象。

代码操作见IDEA

(二)MyBatis配置文件结构

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
 <environments default="development">       --环境
     <environment id="development">         --环境变量
         <transactionManager type="JDBC"/>      --事务管理器
         <dataSource type="POOLED">         --数据源
             <property name="driver" value="${driver}"/>
             <property name="url" value="${url}"/>
             <property name="username" value="${username}"/>
             <property name="password" value="${password}"/>
         </dataSource>
     </environment>
 </environments>
 <databseIdProvider type=""/>       --数据厂商标识
     <mappers>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
     </mappers>
</configuration>

<properties>元素 用于配置属性  通过<property> 或 peoperties文件配置MyBatis
    子元素:如 mybatis-config-property.xml
    properties:在src目录下新建一个db.properties文件 如mybatis-config-properties.xml
        配置文件中的值优于子元素的值
        
<settings>元素 控制MyBatis运行时的状态和行为。
    cacheEnabled  -- 全局开启或关闭配置文件中所有映射器已配置的任何缓存
    lazyLoadingEnabled  -- 延迟加载的全局开关
    aggressiveLazyLoading  -- 
    multipleResultSetsEnabled  -- 是否允许单一语句返回多个结果集
    useColumnLabel  -- 使用列标签代表列名
    logPrefix  参数值MyBatis增加到日志名称的前缀
    ... == 还有很多
    <settings>
         <setting name="cacheEnabled" value="true"/>
         <setting name="lazyLoadingEnabled" value="true"/>
         <setting name="multipleResultSetsEnabled" value="true"/>
         <setting name="useColumnLabel" value="true"/>
         <setting name="useGeneratedKeys" value="false"/>
         <setting name="autoMappingBehavior" value="PARTIAL"/>
         <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
         <setting name="defaultExecutorType" value="SIMPLE"/>
         <setting name="defaultStatementTimeout" value="25"/>
         <setting name="defaultFetchSize" value="100"/>
         <setting name="safeRowBoundsEnabled" value="false"/>
         <setting name="mapUnderscoreToCamelCase" value="false"/>
         <setting name="localCacheScope" value="SESSION"/>
         <setting name="jdbcTypeForNull" value="OTHER"/>
         <setting name="lazyLoadTriggerMethods"
         value="equals,clone,hashCode,toString"/>
    </settings>

<typeAliases>元素 给较长类的类名取一个别名
    <typeAliases> <typeAlias alias="student" type = "com.ye.pojo.Student"/>  </typeAliases>
    <package name="com.ye.pojo"> 此时别名为此包内类名的小写 
    如果以扫描包的形式设置别名时,不愿用MyBatis默认的别名,可以再POJO类中添加注解@Alias
    @Alias(value="stu")
    同时一些常用JAVA类型也有MyBatis提供的别名
<typeHandlers>元素 类型处理器, JAVA->JDBC JDBC->JAVA   当为SQL语句设置参数或从结果中取值时
    基本类型可满足基本需求。若不满足需求则可以先编写typeHandler类实现接口或继承,其次完成配置。加入到MyBatis配置文件汇中
    该元素,知道就行。
<ObjectFactory>元素 对象工厂创建结果集对象 默认情况为DefaultObjectFactory类完成,实际开发中,需要自定义ObjectFactory
    自定义OF的两个环节:编写OF类,其次完成配置。 MyBatis通过元素配置

<environments>元素 配置数据库信息
    MyBatis支持多种环境,可以实现多个数据库使用相同的SQL映射
        UNPOOLED POOLED JNDI 三种数据源
        UNPOOLED 非连接池类型,只在每次被请求时才会打开和关闭连接
        POOLED 连接池类型,维持有一定活跃量的连接对象。可配置多重属性
        JNDI  能在EJB或应用服务器之列的容器中使用,容器可以集中在或在外部配置数据源,然后放置一个JNDI上下文的引用
            initial_context 在InitialContext中寻找上下文,
            data_source 引用数据源实例位置的上下文路径
    <environment>元素定义运行环境  <transactionManager type="JDBC"> 配置事务管理器
        JDBC和MANAGED
        JDBC:提交、回滚、关闭等事务管理
        MANAGED:交给容器管理事务

<mappers>元素 引入映射文件。包含POJO对象和数据表之间的映射信息,元素引导MyBatis找到映射文件并解析其中映射信息
    1)相对于类路径的资源引用  resource
    2)使用完全限定资源定位符(本地文件路径) < mapper url = "">
    3)使用映射器接口实现类的完全限定类名   class
    4)将包内的映射器接口实现全部注册为映射器 <package>

MyBatis映射文件结构

select元素 查询语句 parameterType  resultType 类名/别名
insert元素
delete元素
update元素

sql元素  定义可重用的SQL代码片段。
    <sql id = "studentCols">  </sql>
    <include />引入sql代码   即统一列名,方便更改

ResultMap元素 映射结果集 包含多个子元素 封装并实现了一些JDBC没有提供的功能

(三)MyBatis的关联映射

3.1表与表之间的关系  一对一  一对多  多对多

3.2一对一
    使用MyBatis处理一对一的表关系,在映射文件中加入<association>元素 -> 映射文件<resultMap>元素的子元素
    详见代码ch02
3.3一对多
3.4多对多
3.5主键映射
    获取主键值可以通过配置映射文件中<insert>元素完成映射  
        useGeneratedKeys    获取数据库内部产生的主键值
        keyProperty     指定主键
        如果数据库中主键非自增,则使用<insert>中的<selectKey>子元素获取主键值

(四)动态SQL MyBatis提供的拼接SQL语句的机制,在映射文件中,可以通过动态元素灵活组装SQL语句
--详情请见代码ch04

4.1.1 常用元素有 if choose trim foreach
4.1.2 if元素 用于条件判断,常与test属性联合使用 根据需求动态控制where子句内容
4.1.3 choose when otherwise 三元素  choose包含when和otherwise
    choose 相当于Java中的Switch语句   至少要包含一个when元素 0/1个otherwise
4.1.4 where元素 通常与if联用 如果where后面有以and或者or开头的内容时则自动将and 和 or 删除
    即方便于使用 where 1 = 1 处理and
4.1.5 set元素 适用于update语句中。处理set后面以逗号结尾的内容,将逗号删除。即动态设置set 并消除无关逗号
4.1.6 trim元素 删除多余关键字 可以直接实现where 和 set元素功能
    四种属性:prefix前缀 prefixOverrides前缀后面是'xx'时删除后面的xx suffix后缀 suffixOverrides
4.1.7 foreach元素 用于遍历。支持数组、List或Set接口的集合
    collection item index open/close separator 5个属性
    通常用于SQL语句的in关键字
4.1.8 bind元素 将OGNL表达式的值绑定到一个变量,对变量的引用更简单。提高可移植性。
    如在一些值的前后加上通配符

4.2 注解  实现POJO对象和数据表之间的映射 直接将SQL语句写在接口上。
    要创建接口。再在Mapper中配置接口。
4.2.1 select注解
4.2.2 insert注解
4.2.3 update注解
4.2.4 delete注解
4.2.5 param注解

(五)MyBatis缓存处理

5.1 MyBatis缓存机制
    缓存将程序使用频率较高的数据存储在内存中。MyBatis支持的缓存分为一级缓存和二级缓存
    一级缓存是SQLSession级别的缓存,MyBatis在SqlSession对象中引入一个HashMap对象作为存储数据的区域
    二级缓存是Mapper级别的缓存,多个SqlSession去操作同一个Mapper的Sql语句,二级是跨SqlSession的。
    一级缓存默认开启,二级缓存手动开启

5.2.1 一级缓存原理
    当操作与缓存中的操作不同时,会清空缓存,重新输入。缓存也可手动删除
5.2.2 一级缓存应用
    
5.3.1 二级缓存原理
    作用域范围更大,可以跨多个SQlSession对象,可自定义缓存源。
    清空缓存是为了防止程序误读内容。
5.3.2 二级缓存的配置
    在全局配置中打开二级缓存
        <settings>  <setting name="cacheEnable" value="true"/></settings>
    在映射文件中打开二级缓存
        <cache></cache> - eviction flushInterval size readonly
5.3.3 二级缓存应用
    打开二级缓存 第一次操作结束之后才写入二级缓存 
    全局配置文件 <setting name="cacheEnabled" value="true"/>
    映射文件 <cache></cache>
    pojo类 implements Serializable  可序列化

5.4.1 EhCache简介 分布式缓存将缓存数据进行集中管理
    ehcache.xml进行配置文件
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容