Mybatis详解

Mybatis详解


1.MyBatis是什么?

  • Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时只需要关注 SQL 语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement 等繁杂的过程。程序员直接编写原生态 sql,可以严格控制 sql 执行性能,灵活度高。
  • MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO 映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

1.1MyBatis优缺点

优点:

  1. 基于SQL语句编程,灵活性高
  2. 代码量少,不需要手动开关链接
  3. 兼容性好
  4. 提供映射标签,支持对象与数据库字段的关系映射;提供对象关系映射标签,支持对象关系组件维护
  5. 能够与spring很好的集成

缺点

  1. sql语句编写工作量大,当字段多、表多时很麻烦
  2. SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库

2.关联对象查询

对于查询而言,除了使用resultType指定返回记录类型,也可以使用resultMap进行查询结果的映射。

resultType: 查询结果是单表数据(单一实体),或者查询的列名和实体属性能一一对应, 一般用于简单结果集的映射配置
resultMap: 查询是多表数据(有多个实体),或者查询的列名和实体属性不能对应(例如:emp _name,empName)一般用于复杂结果集的映射配置

resultMap用于如下两种情况:

  • 查询结果的列名与实体属性不对应时,通过resultMap指明列和对象属性的映射关系
  • 在嵌套对象的结构中,设置对象的数据

2.1一对一关系

一对一关系(association):一个员工属于一个部门

在这里插入图片描述

在这里插入图片描述

2.2一对多关系

一对多关系(collection):一个部门有多个员工

在这里插入图片描述

在这里插入图片描述

3.动态SQL

动态sql标签:if、where、trim、set、foreach、choose

3.1 if标签

根据条件判断拼接SQL语句

在这里插入图片描述


:if标签一般用于非空验证,如上例,若id为空,if标签里的代码,将不会执行,反之,则会 执行。

3.2where标签

where一般和if结合使用,根据参数值动态拼接sql
1.当需要拼接条件的时候,会自动拼接where关键字
2.自动去除第一个条件前面的and关键字

在这里插入图片描述


:where标签会根据情况自动过滤掉前面的and或者or
如果where元素没有按正常套路出牌,我们还是可以通过自定义trim元素来定制我们想要的功能

<trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim>

另外,在xml文件中尽量避免写大于,小于,大于等于,小于等于 &

解决方案

在这里插入图片描述

3.3trim、set标签

trim标签一般用于去除sql语句中多余的and关键字,逗号,或者给sql语句前拼接 “where“、“set“以及“values(“ 等前缀,或者添加“)“等后缀,可用于选择性插入、更新、删除 或者条件查询等操作。

在这里插入图片描述


set标签:1.生成set关键字 2.去除最后的逗号

在这里插入图片描述

3.4foreach标签

foreach:循环方式生成SQL语句

foreach可以迭代任何对象(数组、集合等)。
当使用可迭代对象或者数组时, index 是当前迭代的次数, item 的值是本次迭代获取的元素。当使用字典(或者 Map.Entry 对象的集合)时,index 是 键, item 是值。 collection 标签可以填 (‘list’,‘array’,‘map’) 。

在这里插入图片描述

在这里插入图片描述

foreach遍历批量插入

在这里插入图片描述

3.5choose(when,otherwise)

choose:类似于switch分支语句,可以根据条件执行某个分支,走了一个分支之后,其他分支不 再执行

 <select id="findChoose" resultType="pojo.Class">
        select id,cla_name
        from class
        <where>
            <choose>
                <when test="name != null">
                    cla_name = #{name}
                </when>
                <otherwise>
                    id = 1
                </otherwise>
            </choose>
        </where>
    </select>

注:choose(when,otherwise)标签类似switch(case,default)

3.7sql标签定义通用标签

 	<sql id="classSql">
        select * from class
    </sql>
    <select id="findOne" resultType="pojo.Class">
        <include refid="classSql"></include>
        where id = 1;
    </select>

4.延迟加载

Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载, association 指的就是一对一,collection 指的就是一对多查询。在 Mybatis 配置文 件中,可以配置是否启用延迟加载 lazyLoadingEnabled=true|false。

它的原理是,使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截 器方法,比如a.getB().getName(),拦截器 invoke()方法发现a.getB()是 null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调 用 a.setB(b),于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName()方法的 调用。这就是延迟加载的基本原理。

关联查询加载时机

  • 直接加载:执行完主对象的查询后,马上执行对关联对象的查询
  • 侵入式加载:执行完主对象的查询后,不会执行对关联对象的查询,但当访问主对象的详情时,会执行关联对象的查询
  • 深度延迟:只有真正访问关联对象的详情才会执行查询语句

1.全局延迟

<!--现在的状态为直接加载,只要查询主记录就查询关联表-->(3.4.1版本之后的直接加载设
置)
<settings> 
	<setting name="lazyLoadingEnabled" value="false"/> 	
	<setting name="aggressiveLazyLoading" value="false"/>
</settings>
 <!--现在的状态为侵入式延迟加载:访问主记录的属性时,才触发关联表查询--> 
<settings> 
  <setting name="lazyLoadingEnabled" value="true"/>
	<setting name="aggressiveLazyLoading" value="true"/>
</settings>
<!--现在的状态为深度延迟加载,只有访问主记录中关联的对象属性时,才触发关联查询-->
<settings>
	<setting name="lazyLoadingEnabled" value="true"/>
	<setting name="aggressiveLazyLoading" value="false"/>
</settings>

2.部分延迟
在关联查询 collection 、 association 标签上添加 fetchType 属性,lazy表示(深度)延迟加 载,eager表示立即加载,指定属性后,将在映射中忽略全局配置参数 lazyLoadingEnabled

<association property="dept" 
autoMapping="true" 
javaType="Dept" 
select="getDeptByDeptId" 
column="dept_id" 
fetchType="lazy"> </association>

相关文章

学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习...
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面...
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生...
Can’t connect to local MySQL server through socket \'/v...
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 ...
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服...