mybatis(下)

news2024/11/27 18:01:43

注解方式

常用注解标签
@Insert:插入 sql , 和 xml insert sql 语法完全一样
@Select :查询 sql, 和 xml select sql 语法完全一样
@Update :更新 sql, 和 xml update sql 语法完全一样
@Delete :删除 sql, 和 xml delete sql 语法完全一样
@Param :入参
@Results:设置结果集合
@Result :结果

public interface StudentDao {
    @Delete("delete from student where id=#{id}")
    void deleteStudent(int id);
}
@Test
public void delete(){
    SqlSession sqlSession= MybatisUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    studentDao.deleteStudent(1);//调用接口中方法 对应的sql
    sqlSession.commit();
    sqlSession.close();
}
@Update("update student set num = 103 where id = #{id}")
void updateState(int id);

@Select("select num,name from student where id = #{id}")
Student findStudent(int id);

Mybatis动态SQL

MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力。 如果你有使用JDBC 或其他相似框架的经验,你就明白条件地串联 SQL 字符串在一起是多么的痛苦,确保不能忘了空格或在列表的最后省略逗号。动态 SQL 可以彻底处理这种痛苦。

where、if

if test=“条件”:可以对传入的条件进行判断
对于查询条件个数不确定的情况,可使用元素。where标签:当where标签内的if有成立的,就会动态的添加一个where关键字;如果where后面有and、or这种关键字,也会动态删除
在这里插入图片描述

public interface StudentDao {
    List<Student> findStudents1(Student student);
}
<select id="findStudents1" resultType="com.ffyc.mybatisPro.model.Student">
    select * from student
    <where>
        <if test="num!=null">
            and num=#{num}
        </if>
        <if test="name!=null">
            and name=#{name}
        </if>
        <if test="gender!=null">
            and gender=#{gender}
        </if>
    </where>
</select>
@Test
public void query(){
    SqlSession sqlSession= MybatisUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student student=new Student();
    //student.setNum(103);
    student.setName("李四");
    studentDao.findStudents1(student);//调用接口中方法 对应的sql
    sqlSession.close();
}

trim

trim中的prefix可以自定义指定关键字,如果if成立就动态的添加指定的关键字
prefixOverrides删除掉指定的开头的关键字

<select id="findStudents1" resultType="com.ffyc.mybatisPro.model.Student">
    select * from student
    <trim prefix="where" prefixOverrides="and|or">
        <if test="num!=null">
            and num=#{num}
        </if>
        <if test="name!=null">
            and name=#{name}
        </if>
        <if test="gender!=null">
            and gender=#{gender}
        </if>
    </trim>
</select>

choose、when、otherwise

相当于if…else if…else;choose里面可以有when,可以没有otherwise

<select id="findStudents1" resultType="com.ffyc.mybatisPro.model.Student">
    select * from student
    <trim prefix="where" prefixOverrides="and|or">
        <choose>
            <when test="num!=null">
                num=#{num}
            </when>
            <when test="name!=null">
                and name=#{name}
            </when>
            <otherwise>
                and gender=#{gender}
            </otherwise>
        </choose>
    </trim>
</select>

set

set 可以动态的添加set关键字,可以去除最后的逗号;主要用于多次修改

public interface StudentDao {
    void updateStudent(Student student);
}
<update id="updateStudent" parameterType="com.ffyc.mybatisPro.model.Student">
    update student
        <set>
            <if test="num!=null">
                num=#{num},
            </if>
            <if test="name!=null">
                name=#{name},
            </if>
            <if test="gender!=null">
                gender=#{gender}
            </if>
        </set>
        where id=#{id}
</update>

也可以用trim实现

<update id="updateStudent" parameterType="com.ffyc.mybatisPro.model.Student">
    update student
    <trim prefix="set" suffixOverrides=",">
        <if test="num!=null">
            num=#{num},
        </if>
        <if test="name!=null">
            name=#{name},
        </if>
        <if test="gender!=null">
            gender=#{gender}
        </if>
    </trim>
    where id=#{id}
</update>
@Test
public void update(){
    SqlSession sqlSession= MybatisUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student student=new Student();
    student.setId(2);
    student.setNum(104);
    student.setName("李四44");
    studentDao.updateStudent(student);//调用接口中方法 对应的sql
    sqlSession.commit();
    sqlSession.close();
}

foreach

对集合进行遍历(尤其是在构建 IN 条件语句的时候)

public interface StudentDao {
    void deleteStudent(List<Integer> list);
}
<!--delete from student where id in (2,3)批量删除,对数组或集合进行遍历-->
<delete id="deleteStudent">
    delete from student where id in  
        <foreach collection="list" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
</delete>
@Test
public void delete1(){
    SqlSession sqlSession= MybatisUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    List<Integer> list=new ArrayList<>();
    list.add(2);
    list.add(3);
    studentDao.deleteStudent(list);//调用接口中方法 对应的sql
    sqlSession.commit();
    sqlSession.close();
}

对数组进行遍历

public interface StudentDao {
    void deleteStudent2(Integer[] array);
}
<delete id="deleteStudent2">
    delete from student where id in
        <foreach collection="array" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
</delete>
@Test
public void delete2(){
    SqlSession sqlSession= MybatisUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Integer[] array={4,5};
    studentDao.deleteStudent2(array);//调用接口中方法 对应的sql
    sqlSession.commit();
    sqlSession.close();
}

标记语言中,特殊符号处理

方式一:转义符号处理。在 mybatis 中的 xml 文件中,存在一些特殊的符号,比如:<、>、"、&、<>等,正常书写 mybatis 会报错,需要对这些符号进行转义。具体转义如下所示:

特殊字符转义字符
<&lt ;
>&gt ;
"&quot ;
&apos ;
&&amp ;
public interface StudentDao {
    List<Student> findStudents2(int num);
}
select id="findStudents2" resultType="com.ffyc.mybatisPro.model.Student">
    select * from student where num&lt;#{num}
</select>
@Test
public void query1(){
    SqlSession sqlSession= MybatisUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    studentDao.findStudents2(103);//调用接口中方法 对应的sql
    sqlSession.close();
}

方式二:除了可以使用上述转义字符外,还可以使用<![CDATA[]]>来包裹特殊字符。如下所示:

<select id="findStudents2" resultType="com.ffyc.mybatisPro.model.Student">
    select * from student where num <![CDATA[ < ]]> #{num}
</select>
<![CDATA[ ]]>是 XML 语法。在 CDATA 内部的所有内容都会被解析器忽略。但是有个问题那就是 、 、 等这些标签都不会被解析,所以 我们只把有特殊字符的语句放在 <![CDATA[ ]]> ,**尽量缩小<![CDATA[ ]]> 的范围。**

缓存

缓存(cache)的作用是为了减去数据库的压力,提高查询性能。缓存实现的原理是从数据库中查询出来的对象在使用完后不要销毁,而是存储在内存(缓存)中,当再次需要获取该对象时,直接从内存(缓存)中直接获取,不再向数据库执行select 语句,从而减少了对数据库的查询次数,因此提高了数据库的性能。

一级缓存

生:创建sqlsession
销毁:close()、clearCache()、执行update,delete,insert
Mybatis 有一级缓存和二级缓存。一级缓存的作用域是同一个 SqlSession,在同一个 sqlSession 中两次执行相同的 sql 语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据,不再从数据库查询,从而提高查询效率。当一个 sqlSession 结束后该 sqlSession 中的一级缓存也就不存在了。Mybatis 默认开启一级缓存。
在这里插入图片描述

@Test
public void cacheDemo1(){
    SqlSession sqlSession= MybatisUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student s1=studentDao.findStudentById(6);//调用接口中方法 对应的sql
    Student s2=studentDao.findStudentById(6);//调用接口中方法 对应的sql
    sqlSession.close();
}

在这里插入图片描述
查询了两次,但是sql语句执行了一次?因为两次查询的SQL语句一样,查询id为6 返回的对象会缓存到SqlSession对象中,SqlSession对象在内存中存,如果下一次还查询id为6的,就直接访问SqlSession 从缓存中拿就可以
一级缓存的生命周期
a、MyBatis 在开启一个数据库会话时,会创建一个新的 SqlSession 对象,SqlSession 对象中会有一个新的 Executor 对象。Executor 对象中持有一个新的 PerpetualCache 对象;如果 SqlSession 调用了 close()方法,会释放掉一级缓存 PerpetualCache 对象,一级缓存将不可用

@Test
public void cacheDemo1(){
    SqlSession sqlSession= MybatisUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student s1=studentDao.findStudentById(6);//调用接口中方法 对应的sql
    sqlSession.close();//清除缓存
    SqlSession sqlSession2= MybatisUtil.getSqlSession();
    StudentDao studentDao2 = sqlSession2.getMapper(StudentDao.class);
    Student s2=studentDao2.findStudentById(6);//调用接口中方法 对应的sql
    sqlSession.close();
}

b、如果 SqlSession 调用了clearCache(),会清空 PerpetualCache 对象中的数据,但是该对象仍可使用。

@Test
public void cacheDemo1(){
    SqlSession sqlSession= MybatisUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student s1=studentDao.findStudentById(6);//调用接口中方法 对应的sql
    sqlSession.clearCache();//清除一级缓存中的数据
    Student s2=studentDao.findStudentById(6);//调用接口中方法 对应的sql
    sqlSession.close();
}

在这里插入图片描述
c、SqlSession 中执行了任何一个 update 操作(update()、delete()、insert()) ,都会清空一级缓存的数据,但是该对象可以继续使用。

@Test
public void cacheDemo1(){
    SqlSession sqlSession= MybatisUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student s1=studentDao.findStudentById(6);//调用接口中方法 对应的sql
    Student student=new Student();
    student.setId(6);
    student.setNum(106);
    student.setName("李四");
    studentDao.updateStudent(student);//中间执行新增、删除、修改操作,一级缓存也会清除
    Student s2=studentDao.findStudentById(6);//调用接口中方法 对应的sql
    sqlSession.close();
}

在这里插入图片描述

二级缓存

二级缓存是 SqlSessionFactory 级别的,SqlSessionFactory只有一个。
SqlSession1创建,查询到的数据放在SqlSessionFactory中,SqlSession1销毁;SqlSession2创建,仍然可以拿到SqlSessionFactory中数据
配置二级缓存
第一步:启用二级缓存
在 mybatis_config.xml中启用二级缓存,如下代码所示,当cacheEnabled 设置为 true 时启用二级缓存,设置为 false 时禁用二级缓存。

 <!--在mybatis_config.xml中配置-->
<settings> <!--全局开启二级缓存-->
    <setting name="cacheEnabled" value="true"/>
</settings>

可以全局的开启缓存,也可以局部的开启或关闭缓存(useCache=“true”)
在这里插入图片描述
第二步:对象序列化
将所有的 model类实现序列化接口 Java.io. Serializable。

package com.ffyc.mybatisPro.model;

import java.io.Serializable;

public class Student implements Serializable {
    //......
}

第三步:配置映射文件
在 Mapper 映射文件中添加,表示此 mapper 开启二级缓存。
当 SqlSeesion 关闭时,会将数据存入到二级缓存.

<!--StudentMapper.xml中配置二级缓存-->
<cache
    eviction="FIFO"
    flushInterval="60000"
    size="512"
    readOnly="true"
/>
public class MybatisUtil {
    static SqlSessionFactory sessionFactory;
    //静态代码块,在类加载时执行一次
    static {
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader("mybatis_config.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        sessionFactory = new SqlSessionFactoryBuilder().build(reader);
    }
    //创建并返回SqlSession
    public static SqlSession getSqlSession(){
        return sessionFactory.openSession();
    }
}
@Test
public void cacheDemo2(){
    //用的是同一个SqlSessionFactory
    SqlSession sqlSession= MybatisUtil.getSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    Student s1=studentDao.findStudentById(6);//调用接口中方法 对应的sql
    sqlSession.close();//一级缓存销毁,毁时会将缓存写入到二级缓存

    SqlSession sqlSession2= MybatisUtil.getSqlSession();
    StudentDao studentDao2 = sqlSession2.getMapper(StudentDao.class);
    Student s2=studentDao2.findStudentById(6);
    //此时可以从二级缓存获取数据,因为共享的是同一个SqlSessionFactory
    sqlSession.close();
}

在这里插入图片描述
可以单独为某一个语句关闭二级缓存,加上useCache=“false”,即使配置过二级缓存,二级缓存也会失效

<select id="findStudentById" parameterType="int" resultMap="studentMap" useCache="false">
    select
        s.id,
        s.num,
        s.name,
        s.gender,
        s.birthday,
        d.num dormNum,
        a.account,
        s.oper_time
        from student s left join dorm d on s.dormid=d.id
                left join admin a on s.adminid=a.id
                where s.id=#{id}
</select>

在这里插入图片描述

MyBatis 架构

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/875506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深入理解ES6】字符串和正则表达式

概念 字符串&#xff08;String&#xff09;是JavaScript6大原始数据类型。其他几个分别是Boolean、Null、Undefined、Number、Symbol&#xff08;es6新增&#xff09;。 更好的Unicode支持 1. UTF-16码位 字符串里的字符有两种&#xff1a; 前 个码位均以16位的编码单元…

Excel表格制作,快速提升效率好方法!

“作为一个刚开始工作的职场新人&#xff0c;每天要做各种不同的表格&#xff0c;真的让我很崩溃&#xff0c;感觉我对这些表格制作一点都不了解&#xff0c;Excel表格制作有什么比较好的方法吗&#xff1f;” Excel作为一款广泛应用于各个领域的管理和分析工作&#xff0c;给我…

SAP ME2L/ME2M/ME3M报表增强添加字段(包含:LMEREPI02、SE18:ES_BADI_ME_REPORTING)

ME2L、ME2M、ME3M这三个报表的字段增强&#xff0c;核心点都在同一个结构里 SE11:MEREP_OUTTAB_PURCHDOC 在这里加字段&#xff0c;如果要加的字段是EKKO、EKPO里的数据&#xff0c;直接加进去&#xff0c;啥都不用做&#xff0c;就完成了 如果要加的字段不在EKKO和EKPO这两个…

RISC-V公测平台发布 · 7-zip 测试

简介 7-Zip 是一个开源的压缩和解压缩工具&#xff0c;具有高压缩比和快速解压缩的特点。除了普通的文件压缩和解压缩功能之外&#xff0c;7-Zip 还提供了基准测试功能&#xff0c;通过压缩和解压缩大型文件来评估系统的处理能力和性能。 7-Zip 提供了一种在不同压缩级别和多…

浅析kubernetes部署:javashop部署概览

javashop部署概览 节点规划 首先我们对节点进行规划&#xff0c;方便起见&#xff0c;我们进行如下简单的规划&#xff1a; 这里请根据您的实际情况进行合理的资源安排&#xff0c;或和我们售后工程师讨论形成方案。 域名规划 我们以test.com为主域名规划我们的系统域名如下&…

qq录屏怎么弄?手把手教会你!

“有没有人知道qq怎么录屏呀&#xff0c;听说qq可以录屏&#xff0c;刚好最近需要录制屏幕&#xff0c;就想用qq去录&#xff0c;但是找了很久&#xff0c;都没找到&#xff0c;有人知道吗&#xff0c;谢谢了。” 在如今数字化时代&#xff0c;屏幕录制已成为广泛使用的工具。…

云计算——存储虚拟化功能

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​ 目录 前期回顾 前言 一.存储虚拟化功能 1.精简磁盘和空间回收 2.快照 &#xff08;1&a…

Qt应用开发(基础篇)——滚屏区域基类 QAbstractScrollArea

一、前言 QAbstractScrollArea滚屏区域抽象类继承于QFrame&#xff0c;QFrame继承于QWidget&#xff0c;是QListview(列表浏览器)、QTableview(表格浏览器)、QTextEdit(文本编辑器)、QTextBrowser(文本浏览器)等所有需要滚屏区域部件的抽象基类。 框架类QFrame介绍 QAbstractSc…

高忆管理:概念火认购却不火!ESG理财如何打破僵局?

曾几何时&#xff0c;国内ESG理财曾被贴上“小众”标签&#xff0c;现在&#xff0c;跟着ESG理念的遍及与深化群众&#xff0c;这一“小众”的出资理念正在走向“群众”。 有银行理财子公司人士向证券时报券商我国记者表示&#xff0c;从组织视点来看&#xff0c;以债券类为主的…

【AI作画】使用Stable Diffusion的艺术二维码完全生成攻略

文章目录 前言Stable Diffusion 简介 什么是云端平台&#xff1f;优势灵活性和可扩展性成本效益高可用性和容错性管理简便性 选择适合的云端平台 平台优势平台操作购买算力并创建工作空间启动工作空间应用市场一键安装 使用Stable-Diffusion作图使用控制网络将文本转图像二维码…

windows pip安装出现 error: Microsoft Visual C++ 14.0 is required

可参考&#xff1a;如何解决 Microsoft Visual C 14.0 or greater is required. Get it with “Microsoft C Build Tools“_不吃香菜的小趴菜的博客-CSDN博客 一、安装Visual Studio2022 1、下载&#xff1a;下载 Visual Studio Tools - 免费安装 Windows、Mac、Linux 我这使…

【前端|Javascript第4篇】详解Javascript的事件模型:小白也能轻松搞懂!

前言 在当今数字时代&#xff0c;前端技术正日益成为塑造用户体验的关键。而其中一个不可或缺的核心概念就是JavaScript的事件模型。或许你是刚踏入前端领域的小白&#xff0c;或者是希望深入了解事件模型的开发者&#xff0c;不论你的经验如何&#xff0c;本篇博客都将带你揭开…

iTOP-STM32MP157开发板Linux Misc驱动编写实验程序(运行测试)

启动 STM32MP157 开发板&#xff0c;我们通过 nfs 挂载共享文件目录&#xff0c;我们进入到共享目录&#xff0c;加载驱动模块如 图所示&#xff1a; insmod misc.ko 驱动加载成功后&#xff0c;输入以下命令&#xff0c;查看注册的设备节点是否存在&#xff0c;如下图所示&a…

NSI45030AT1G LED驱动器方案为汽车外部及内部照明恒流稳流器(CCR)方案

关于线性恒流调节器&#xff08;CCR&#xff09;&#xff1a;是一种用于控制电流的稳定输出。它通常由一个功率晶体管和一个参考电流源组成。CCR的工作原理是通过不断调节功率晶体管的导通时间来维持输出电流的恒定。当输出电流超过设定值时&#xff0c;CCR会减少功率晶体管的导…

激战本地生活:抖音美团打得火热,小红书也来“搅局”?怎么开通小红书本地生活服务商呢?

小红书也来本地生活赛道“横插一脚”了。 上线面向本地生活的交易合作服务平台、推出面向达人的探店内容扶持计划、“0押金、0佣金、流量扶持” 激励更多商家入场......在已经硝烟弥漫的申请cmxyci本地生活赛道&#xff0c;小红书开始放大招。 据了解&#xff0c;小红书是在今年…

sift-1M数据集的读取及ES插入数据

sift是检查ann近邻召回率的标准数据集,ann可以选择faiss,milvus等库或者方法;sift数据分为query和base,以及label(groundtruth)数据。本文采用sift-1M进行解读,且看如下: 1、sift-1m数据集 官方链接地址:Evaluation of Approximate nearest neighbors: large datase…

嵌入式微控制器架构为AI演进

如果您将IoT与AI相结合会得到什么&#xff1f;AIoT是简单的答案&#xff0c;但由于神经网络技术的进步&#xff0c;使机器学习不再局限于超级计算机的世界&#xff0c;因此您还将获得嵌入式微控制器的巨大新应用领域。如今&#xff0c;智能手机应用处理器可以&#xff08;并且确…

UML 类图的画法

1.类图的画法 类 整体是个矩形&#xff0c;第一层类名&#xff0c;第二层属性&#xff0c;第三层方法。 &#xff1a;public- : private# : protected空格: 默认的default 对应的类写法。 public class Student {public String name;public Integer age;protected I…

kubernetes集群(k8s)之安装部署Calico 网络

目录 安装部署Calico 网络 &#xff08;一&#xff09;环境准备 &#xff08;二&#xff09;部署docker环境 &#xff08;三&#xff09;部署kubernetes集群 &#xff08;四&#xff09;部署Calico网络插件 安装部署Calico 网络 &#xff08;一&#xff09;环境准备 IP地…

混淆矩阵、F1score详解

混淆矩阵&#xff08;Confusion Matrix&#xff09; TP&#xff08;True Positives)&#xff1a;真正例&#xff0c;预测为正例而且实际上也是正例&#xff1b; FP&#xff08;False Positives)&#xff1a;假正例&#xff0c;预测为正例然而实际上却是负例&#xff1b; FN&…