MyBatis

123 阅读12分钟

什么是Mybatis

  • Mybatis是一个优秀的基于Java的持久层框架,它内部封装了Jdbc,使开发者至于要关注sql语句本身,而不需要花费精力去处理加载驱动,创建连接,创建statement等繁杂的过程。
  • mybatis通过xml或注解的方式将要执行的各种statement配置起来,并通过Java对象,和statement中sql的动态参数进行映射生成最终执行的sql语句
  • 最后mybatis框架执行sql并将执行的结果映射为Java对象并返回。采用ORM思想解决了实体和数据库映射的问题,对jdbc进行封装,屏蔽了jdbc api底层访问细节,使我们不用与jdbc api打交道,就可以完成对数据库的操作
    • 对象关系映射(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping)是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”
    • 广义上,ORM指的是面向对象的对象模型和关系型数据库的数据结构之间的相互转换。 狭义上,ORM可以被认为是,基于关系型数据库的数据存储,实现一个虚拟的面向对象的数据访问接口

O,R,M的定义

  • O(对象模型)
    • 实体对象,即我们在程序中根据数据库表结构建立的一个个实体Entity
  • R(关系型数据库的数据结构)
    • 即我们建立的数据库表
  • M(映射)
    • 从R(数据库)到O(对象模型)的映射,可通过XML文件映射

Mybatis简单开发步骤

Mybatis官网地址:www.mybatis.org/mybatis-3/

  • 添加mybatis的相关坐标

  • 创建user数据表

  • 创建User实体类

  • 编写映射文件UserMapper.xml(内部主要写的是sql语句)

    • 文件约束头:

  • 编写核心文件sqlMapConfig.xml(配置mybatis框架的一些核心配置)

    • 文件约束头:

  • 编写测试类

文件约束头

<?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="userMapper">
  
</mapper>
```

mybatis的映射文件的概述

  • mapper标签:根标签,其中的属性namespace(命名空间),与对sql操作的标签中的id一起组成查询的唯一标识
  • select标签:查询操作,还有insert,uopdate,delete, 标签中有id属性,与mapper标签中的namespace组成查询的唯一标识,resultType属性为查询结果对应的实体类型

Mybatis的增删改查操作

mybatis的插入数据操作

插入操作注意的问题

  • 插入语句使用insert标签
  • 在映射文件中使用parameterType属性指定要插入的数据类型
  • sql语句中使用#{实体属性名}方式引用实体中的属性值
  • 插入操作使用的api是sqlsession.insert(“命名空间+id”,实体对象)
  • 插入操作涉及数据库变化,mybatis默认是不自动提交事务的,所以在增删改的操作要手动提交,即sqlsession.commit()

mybatis的修改数据操作

mybatis的删除操作

 删除操作注意问题:Sql语句中使用#{任意字符串}方式引用传递的单个参数

MyBatis核心配置文件概述

MyBatis核心配置文件层级关系

  • configuration配置
    • properties 属性
    • settings 设置
    • typeAliases 类型别名
    • typeHandlers 类型处理器
    • objectFactory 对象工厂
    • plugins 插件
    • environments环境
      • environment 环境变量
        • transactionManager 事务管理器
          • 其中事务管理器(transactionManager)类型有两种
            • JDBC:这个配置就是直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域
            • MANAGED:这个配置几乎没做什么,它重来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如JEE应用服务器的上下文)。默认情况下它会关闭连接,然后一些容器并不希望这样,因此需要将closeConnection属性设置为false来阻止它默认的关闭行为
        • dataSource 数据源
          • 其中数据源(dataSource)类型有三种
            • POOLED:这个数据源的实现利用”池”的概念将jdbc连接对象组织起来(常用)
            • UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接
            • JNDI:这个数据源的实现是为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用
    • databaseidProvider 数据库厂商标识
    • mappers 映射器

Mybatis常用配置解析

  • environments标签:数据库环境的配置,支持多环境配置。
  • mapper标签:该标签的作用是加载映射的,加载方式有如下几种
    • 使用相对于类路径的资源引用,例如:”
    • 使用完全限定资源定位符(URL):例如:”
    • 使用映射器接口实现类的完全限定类名,例如:”
    • 将包类的映射器接口实现全部注册为映射器,例如:”
  • properties标签:实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件
  • typeAliases标签
    • 类型别名是为Java类型设置一个短的名字。原来的类型名称如下
    • 配置typeAliases,为com.itheima.damain.User定义别名为user

MyBatis相应API

SqlSession工厂构建器SqlSessionFactoryBuilder

常用API:SqlSessionFactoryBuilder(InputStream inputStream)
通过加载mybatis核心文件的输入流的形式构建一个SqlSessionFactory对象

其中Resources工具类,这个类在org.apache.ibatis.io包中。Resources类帮助你从类资源路径,文件系统或一个web URL中加载资源文件

SqlSession工厂对象SqlSessionFactory

SqlSessionFactory有多个方法创建SqlSession实例。常用的有如下两个:

  • openSession():会默认开启一个事务,但事务不会自动提交,也就意味着需要手动提交该事务,更新操作数据才会持久化到数据库中。
  • openSession(boolean autoCommit):参数为是否自动提交,如果设置为true,那么不需要手动提交事务

SqlSession会话对象

  • 执行语句的方法主要有:
  • 操作事务的方法主要是:

Mybatis的Dao层实现

代理开发方式

介绍:

采用Mybatis的代理开发方式实现Dao层的开发,这种方式是我们后面进入企业的主流。Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper接口开发需要遵循以下规范::

  • Mapper.xml文件中的namespace与mapper接口的全类名相同
  • Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
  • Mapper接口方法的参数类型和Mapper.xml中定义的相对应sql的parameterType的类型相同
  • Mapper接口方法的返回类型和Mapper.xml中定义的相对应sql的resultType类型相同

编写UserMapper接口

sqlsession操作接口

传入接口后,mybatis底层会为这个接口动态的生成代理对象,返回的就是这个接口的实现对象,然后就可以调用mapper接口的中定义的方法,就会映射到mapper.xml中的statement

MyBatis动态sql语句(test属性中写条件判断式)

  • if
    • where 1=1可以用where标签进行代替
  • where
    • 当where标签中有内容时,会自动生成where关键字,并且将内容前多余的and或or去掉
    • 当where标签中没有内容时,此时where标签没有任何效果,并不会生成where关键字
    • **注意:**where标签不能将其中内容后面多余的and和or去掉
  • choose,when,otherwise
    • when至少一个,otherwise最多一个
  • trim
    • 若标签中有内容时:
      • **prefix/suffix:**将trim标签中内容前面或后面添加指定内容
      • **suffixOverrides/prefixOverrides:**将trim标签中内容前面或后面去掉指定内容
    • 若标签内没有内容,trim标签也没有任何作用
  • foreach
    • collection:设置需要循环的数组或集合
    • item:表示数组或集合中的每一个数据
    • separator:循环体之间的分隔符,默认有空格
    • open:foreach标签所循环的所有内容的开始符
    • close:foreach标签所循环的所有内容的结束符
    • 批量删除
    • 批量添加

sql片段的抽取

MyBatis核心配置文件深入

typeHandlers标签

你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。具体的做法:实现org.apache.ibatis.type.TypeHandler接口,或继承一个很便利的类org.apache.ibatis.type.BaseTypeHandler,然后可以选择性的将他映射到一个JDBC类型。例如需求:一个Java中的Date数据类型,我想存到数据库的时候存一个1970年至今的毫秒数,取出来时转换成Java的Date,即Java的Date与数据库的Vachar毫秒值之间转换

MyBatis 内置的 TypeHandler

  • BooleanTypeHandler:用于 java 类型 boolean,jdbc 类型 bit,boolean
  • ByteTypeHandler:用于 java 类型 byte,jdbc 类型 TINYINT
  • ShortTypeHandler:用于 java 类型 short,jdbc 类型 SMALLINT
  • IntegerTypeHandler:用于 INTEGER 类型
  • LongTypeHandler:用于 long 类型
  • FloatTypeHandler:用于 FLOAT 类型
  • DoubleTypeHandler:用于 double 类型
  • StringTypeHandler:用于 java 类型 string,jdbc 类型 CHAR、VARCHAR
  • ArrayTypeHandler:用于 jdbc 类型 ARRAY
  • BigDecimalTypeHandler:用于 java 类型 BigDecimal,jdbc 类型 REAL、DECIMAL、NUMERIC
  • DateTypeHandler:用于 java 类型 Date,jdbc 类型 TIMESTAMP
  • DateOnlyTypeHandler:用于 java 类型 Date,jdbc 类型 DATE
  • TimeOnlyTypeHandler:用于 java 类型 Date,jdbc 类型 TIME

开发步骤

  • 定义转换类继承类BaseTypeHandler
  • 覆盖四个为实现的方法,其中setNonNullParameter为Java程序设置数据到数据库的回调方法,getNullableResult为查询时mysql的字符串类型转换成Java的type类型的方法
  • 在mybatis核心配置文件中进行注册
  • 测试转换是否成功

plugins标签

Mybatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据

开发步骤:

  • 导入通用的PageHelper的坐标
  • 在mybatis核心配置文件中配置PageHelper插件
  • 测试分页数据获取

获取与分页相关的参数

Mybatis获取参数值的两种方式

MyBatis获取值的两种方式:${}和#{}

${}本质就是字符串的拼接,#{}的本质就是占位符赋值
—字符串拼接

—占位符赋值

${}使用字符串拼接的方式拼接sql,若为字符串类型日期类型的字段进行赋值时,需要手动加单引号;但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号

1.单个字面量类型的参数

若mapper接口中的方法参数为单个的字面量类型
此时可以使用{}和#{}以任意的名称获取参数的值,注意{}要手动添加单引号

2.多个字面量类型的参数

若mapper接口中的方法参数为多个字面量类型时
此时MyBatis会自动将这些参数放在一个map集合中,以arg0,arg1…为键,以参数为值;以param1,param2…为键,以参数为值;因此只需要通过{}和#{}访问map集合中的键就可以获取相应的值,注意{}需要手动加单引号

3.map类型的参数

只需要通过${}和#{}访问map集合中的键就可以获取相应的值

4.mapper接口方法的参数是实体类类型的参数

只需要通过{}和#{}以属性的方式访问属性值就可以,**注意{}需要手动加单引号**

5.使用@Param标识参数

可以通过@Param注解标识mapper接口中的方法参数

此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,参数为值;以param1,param2…为键,以参数为值,只需要通过{}和#{}访问map集合中的键就可以获取相应的值,注意{}需要手动加单引号

MyBatis各种查询功能

  • 若查询出的数据只有一条

    • 可以通过实体类对象接收

    • 可以通过list集合接收

    • 可以通过map集合接收

  • 若查询出的数据有多条

    • 可以通过实体类型的list集合接收

    • 可以通过map类型的list集合接收

    • 可以在mapper接口方法上添加@MapKey注解,此时就可以将每条数据转换的map集合作为值,以某个字段的值作为键,放在同一个map中

  • 模糊查询(% 匹配任意多个字符包括0个,_ 匹配任意单个字符)

mybatis获取添加功能自增的主键

解决字段名和属性名的映射关系

  • 为字段起别名,保持和属性名一样
  • 通过全局配置mapUnderscoreToCamelCase设置为true 默认为false
  • 使用resultMap解决映射关系
    • resultMap标签:设置自定义映射关系
    • id(resultMap标签中的属性):resultMap的唯一标识,不能重复
    • type(resultMap标签中的属性):设置映射关系中的实体类类型
    • 子标签:
    • id:设置主键的字段映射关系
    • result:设置普通字段映射关系
    • 属性 :
    • properties:设置映射关系中的属性名,必须是type属性所设置的实体类类型中的属性名
    • column: 设置映射关系中的字段名,必须是sql语句查询出的字段名

解决多对一的映射关系

  • 级联属性赋值
  • association解决多对一的映射关系
    • property:需要处理多对一的映射关系的属性名
    • javaType :该属性的实体类类型
  • 分步查询
    • select:设置分步查询的sql的唯一标识(namespace.sqlid或mapper接口的全类名.方法名)
    • column:设置分步查询的条件(字段名),告诉第二步(select中的接口方法)查询我给你传这个参数,你按照我穿的这个参数进行查询
    • fetchType:当开启了全局的延迟加载之后,可通过此属性手动控制延迟加载的效果—-lazy表示延迟加载,eager表示立即加载

延迟加载

分布查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:

  • lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
  • aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。相反,每个属性会按需加载

此时就可以实现按需加载,获取什么数据,就只会执行相应的sql,此时可以通过association和collection中的fetchType属性设置当前的分布查询是否使用延迟加载。

解决一对多的映射关系

  • collection解决一对多的映射关系
    • property:需要处理多对一的映射关系的属性名
    • ofType:该属性的实体类类型

mybatis的注解开发

这几年来注解开发越来越流行,mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper映射文件了。

常用注解:

  • @Insert:添加
  • @Update:修改
  • @Delete:删除
  • @Select:查询
  • @Result:实现结果集封装
  • @Results:可以与Result一起使用,封装多个结果集
  • @One:实现一对一结果集封装
  • @Many:实现一对多结果集封装

注意:简单sql可以用注解,比较简单,但复杂sql建议还是xml配置文件编写

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情