Mybatis快速入门(4)

导读:本篇文章讲解 Mybatis快速入门(4),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

CSDN话题挑战赛第2期
参赛话题:学习笔记

学习之路,长路漫漫,需要您的陪伴。
关注一波,您的关注是我最大的动力。

Mybatis

这篇文章Mybatis快速入门(1)我们介绍了快速掌握Mybatis进行简单CRUD
这篇文章Mybatis快速入门(2)我们介绍了传参以及Mybatis的各种查询。
这篇文章Mybatis快速入门(3)我们介绍了使用Mybatis进行多表查询。
本篇文章,我们介绍一下Mybatis的动态Sql技术和Mybatis的缓存机制。

一、 动态SQL

Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决
拼接SQL语句字符串时的痛点问题,主要是介绍标签代替sql语句,更加的灵活。

先给出总的接口写法:

public interface DynamicSQLMapper {

    /*
     * 多条件查询
     */
    List<Emp> getEmpByCondition(Emp emp);

    /*
     * 测试choose when otherwise
     */
    List<Emp> getEmpByChoose(Emp emp);

    /*
     * 通过数组实现批量删除
     */
    int deleteMoreByArray(@Param("eids") Integer[] eids);
}

1. if

if标签可通过test属性的表达式进行判断,若表达式的结果为true,则标签中的内容会执行;反之标签中的内容不会执行

<select id="getEmpByCondition" resultType="Emp">
    select * from t_emp  where 1=1   (没有1=1的话where和and直接连接会报错)
    <if test="empName!=null and empName!=''">
        and emp_name = #{empName}
    </if>
    <if test="age!=null and age!=''">
        and age = #{age}
    </if>
    <if test="sex!=null and sex!=''">
        and sex = #{sex}
    </if>
    <if test="email!=null and email!=''">
        and email = #{email}
    </if>
</select>

2. where

	<select id="getEmpByCondition" resultType="Emp">
        select * from t_emp
        <where>
            <if test="empName!=null and empName!=''">
                and emp_name = #{empName}
            </if>
            <if test="age!=null and age!=''">
                and age = #{age}
            </if>
            <if test="sex!=null and sex!=''">
                and sex = #{sex}
            </if>
            <if test="email!=null and email!=''">
                and email = #{email}
            </if>
        </where>
    </select>

where和if一般结合使用:

a>若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字

b>若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的

and去掉

注意:where标签不能去掉条件最后多余的and

3. trim

<select id="getEmpByCondition" resultType="Emp">
    select <include refid="empColumns"></include> from t_emp
    <trim prefix="where" suffixOverrides="and|or">
        <if test="empName!=null and empName!=''">
            emp_name = #{empName} and
        </if>
        <if test="age!=null and age!=''">
            age = #{age} and
        </if>
        <if test="sex!=null and sex!=''">
            sex = #{sex} or
        </if>
        <if test="email!=null and email!=''">
            email = #{email} and
        </if>
    </trim>
</select>

trim用于去掉或添加标签中的内容

常用属性:

prefix:在trim标签中的内容的前面添加某些内容

prefixOverrides:在trim标签中的内容的前面去掉某些内容

suffix:在trim标签中的内容的后面添加某些内容

suffixOverrides:在trim标签中的内容的后面去掉某些内容

前三种sql标签可以用以下例子测试:

    @Test
    public void testgetEmpByCondition() {
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        List<Emp> list = mapper.getEmpByCondition(new Emp(null, "李四", 21, "男", "123@qq.com"));
        System.out.println(list);
    }

4.choose.when.otherwise

choose、when、otherwise相当于if…else if…else

<!--List<Emp> getEmpByChoose(Emp emp);-->
<select id="getEmpByChoose" resultType="Emp">
    select * from t_emp
    <where>
        <choose>
        <!--when相当于if,一个成立其他的标签就都不执行了,otherwise相当于最后一个else-->
            <when test="empName!=null and empName!=''">
                emp_name = #{empName};
            </when>
            <when test="age!=null and age!=''">
                age = #{age};
            </when>
            <when test="sex!=null and sex!=''">
                sex = #{sex};
            </when>
            <when test="email!=null and email!=''">
                email = #{email};
            </when>
            <otherwise>
                did = 1;
            </otherwise>
        </choose>
    </where>
</select>

测试:

    @Test
    public void testGetEmpByChoose() {
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        List<Emp> list = mapper.getEmpByChoose(new Emp(null, "张三", 23, "男", "123@qq.com"));
        System.out.println(list);
    }

5.foreach

<!--    int deleteMoreByArray(Integer[] eids);-->
<delete id="deleteMoreByArray">
    delete from t_emp where
    <foreach collection="eids" item="eid" separator="or">
        eid = #{eid}
    </foreach>

    <!--
        delete from t_emp where eid in
        <foreach collection="eids" item="eid" separator="," open="(" close=")">
            #{eid}
        </foreach>
    -->
</delete>

属性:

collection:设置要循环的数组或集合

item:表示集合或数组中的每一个数据

separator:设置循环体之间的分隔符

open:设置foreach标签中的内容的开始符

close:设置foreach标签中的内容的结束符

测试:

    @Test
    public void testdeleteMoreByArray() {
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        System.out.println(mapper.deleteMoreByArray(new Integer[]{5, 6, 7}));
    }

6、SQL片段

sql片段,前面介绍trim标签的时候已经运用到了,可以记录一段公共sql片段,在使用的地方通过include标签进行引入

<sql id="empColumns"> 
	eid,ename,age,sex,did 
</sql> 
select <include refid="empColumns"></include> from t_emp

refid: 连接的sql语句的 id

总结:

/*
 * 动态SQL:
 * 1.if:根据标签中的test属性对应的表达式决定标签中的内容是否需要拼接到SQL中
 * 2.where:
 * 当where标签中有内容时,会自动生成where关键字,并且将内容前多余的and和or去掉
 * 当where标签中没有内容时,where标签无效果
 * 注意:where标签不能将其中内容后面多余的and和or去掉
 * 3.trim
 * 若标签中有内容时
 * prefix|suffix:在trim标签中的内容前面或后面加上指定内容
 * prefixOverrides|suffixOverrides:在trim标签中的内容前面或后面去掉指定内容
 * 若标签无内容,则标签没有效果
 * 4.choose when otherwise 相当于 if...else if...else
 * when至少有一个,otherwise至多有一个
 * 5.foreach
 * collection:设置需要循环的数组或集合
 * item:表示数组或集合中的每个数据
 * separator:循环体之间的分隔符
 * open:foreach标签所循环的所有内容的开始符
 * close:foreach标签所循环的所有内容的结束符
 * 6.sql标签
 * 设置SQL片段:<sql id="empColumns">eid,emp_name,age,sex,email</sql>
 * 引用SQL片段:<include refid="empColumns"></include>
 */

二、MyBatis的缓存

1、MyBatis的一级缓存

一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就

会从缓存中直接获取,不会从数据库重新访问

使一级缓存失效的四种情况:

  1. 不同的SqlSession对应不同的一级缓存

  2. 同一个SqlSession但是查询条件不同

  3. 同一个SqlSession两次查询期间执行了任何一次增删改操作

  4. 同一个SqlSession两次查询期间手动清空了缓存

2、MyBatis的二级缓存

二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被

缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取

二级缓存开启的条件:

	①在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置
	
	②在映射文件中设置标签<cache/>
	
	③二级缓存必须在SqlSession关闭或提交之后有效

查询的数据所转换的实体类类型必须实现序列化的接口

使二级缓存失效的情况:

两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效

3、二级缓存的相关配置

在mapper配置文件中添加的cache标签可以设置一些属性:

  • eviction属性:缓存回收策略

​ LRU(Least Recently Used) – 最近最少使用的:移除最长时间不被使用的对象。

​ FIFO(First in First out) – 先进先出:按对象进入缓存的顺序来移除它们。

​ SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

​ WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

​ 默认的是 LRU。

  • flushInterval属性:刷新间隔,单位毫秒

​ 默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新

  • size属性:引用数目,正整数

​ 代表缓存最多可以存储多少个对象,太大容易导致内存溢出

  • readOnly属性:只读,true/false

​ true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了

​ 很重要的性能优势。

​ false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是

​ false。

4、MyBatis缓存查询的顺序

先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。

如果二级缓存没有命中,再查询一级缓存

如果一级缓存也没有命中,则查询数据库

SqlSession关闭之后,一级缓存中的数据会写入二级缓存

Mybatis快速入门介绍到这里就结束啦,感谢你的阅读,一起学习,一起进步!

点赞,关注,收藏,您的支持是我更新的最大动力!!!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/118506.html

(0)
seven_的头像seven_bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!