MyBatis见解4
10.MyBatis的动态SQL
10.5.trim标签
trim标签可以代替where标签、set标签
- mapper
//修改public void updateByUser2(User user);
<update id="updateByUser2" parameterType="User">update user<!-- 增加SET前缀,忽略,后缀 --><trim prefix="SET" suffixOverrides=","><if test="birthday!=null">birthday=#{birthday},</if><if test="sex!=null and username != '' ">sex=#{sex},</if><if test="address!=null and username != '' ">address=#{address},</if></trim>where id=#{id}</update>
insert 用法
void addUser(User user);
<insert id="addUser" parameterType="user">INSERT INTO user<!--trim标签一定要包括if标签,作用:prefix:加上前缀,“(”suffix:加上后缀,“)”prefixOverrides:去除多余的前缀内容suffixOverrides:去除多余的后缀内容,“,”--><trim prefix="(" suffix=")" suffixOverrides=","><if test="username!=null and username!=''">username,</if></trim><trim prefix="VALUES(" suffix=")" suffixOverrides=","><if test="username!=null and username!=''">#{username},</if></trim></insert>
10.6.foreach标签
foreach标签的常见使用场景是集合进行遍历
- mapper
//批量删除public void deleteUserByIds(@Param("ids") List<Integer> ids);//批量添加public void insertUsers(@Param("userList") List<User> userList);
//批量删除public void deleteUserByIds(@Param("ids") List<Integer> ids);//批量添加public void insertUsers(@Param("userList") List<User> userList);
- 测试
@Testpublic void testDeleteUserByIds(){UserDao userDao = sqlSession.getMapper(UserDao.class);List<Integer> ids = new ArrayList();ids.add(50);ids.add(64);ids.add(67);userDao.deleteUserByIds(ids);}@Testpublic void testInsertUsers(){UserDao userDao = sqlSession.getMapper(UserDao.class);long start = System.currentTimeMillis();List<User> userList = new ArrayList<>();for(int i = 0 ;i < 10000; i++) {User user = new User();user.setUsername("刘德华");user.setPassword("111");user.setBirthday(new Date());user.setSex("男");user.setAddress("香港");//userDao.insertUser(user);userList.add(user);}userDao.insertUsers(userList);long end = System.currentTimeMillis();System.out.println("一万条数据总耗时:" + (end-start) + "ms" );sqlSession.commit();}
10.7.sql标签
sql元素标签用来定义可重复使用的SQL代码片段,使用时只需要用include元素标签引用即可
- mapper
//复杂条件查询public List<User> findByUser3(User user);
<!-- 定义SQL片段 --><sql id="query_user_where"><if test="username!=null and username != ''">and username=#{username}</if><if test="birthday!=null">and birthday=#{birthday}</if><if test="sex!=null and sex != ''">and sex=#{sex}</if><if test="address!=null and address != ''">and address=#{address}</if></sql><select id="findByUser3" resultType="User">select * from user<where><include refid="query_user_where"></include></where></select>
- 测试
@Testpublic void testFindAll3(){UserDao userDao = sqlSession.getMapper(UserDao.class);User user = new User();user.setAddress("香港");user.setUsername("刘德华");List<User> userList = userDao.findByUser3(user);for(User u : userList){System.out.println(u);}}
11.MyBatis的缓存
创建工程:

11.1缓存介绍
-
为什么使用缓存?
首次访问时,查询数据库,并将数据存储到内存中;再次访问时直接访问缓存,减少IO、硬盘读写次数、提高效率
-
Mybatis中的一级缓存和二级缓存?
-
一级缓存:
它指的是mybatis中的SqlSession对象的缓存。当我们执行完查询之后,查询的结果会同时存在在SqlSession为我们提供的一块区域中。当我们再次查询同样的数据,mybatis会先去SqlSession中查询是否有,有的话直接拿出来使用。当SqlSession对象消失时,Mybatis的一级缓存也就消失了。
-
二级缓存:
它指的是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessioFactory对象创建的SqlSession共享其缓存。

-
11.2.一级缓存
11.2.1.mapper
public interface UserDao {//根据id查询用户信息public User findUserById(Integer id);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.by.dao.UserDao"><select id="findUserById" resultType="User" parameterType="int">select * from user where id=#{id}</select>
</mapper>
11.2.2.测试一级缓存
@Testpublic void testFindUserById() throws Exception{SqlSession sqlSession1 = sqlSessionFactory.openSession();UserDao userDao = sqlSession1.getMapper(UserDao.class);User user1 = userDao.findUserById(41);//执行查询System.out.println("第一次查询:" + user1);User user2 = userDao.findUserById(41);//不执行查询System.out.println("第二次查询:" + user2);SqlSession sqlSession2 = sqlSessionFactory.openSession();userDao = sqlSession2.getMapper(UserDao.class);User user3 = userDao.findUserById(41);//执行查询System.out.println("第三次查询:" + user1);}
11.2.3.一级缓存的分析
一级缓存是SqlSession范围的缓存,当调用SqlSession的commit(),close()等方法时,就会清空一级缓存。

-
第一次发起查询用户id为 1 的用户信息,先去找缓存中是否有id为 1 的用户信息,如果没有,从数据库查询用户信息。 得到用户信息,将用户信息存储到一级缓存中。
-
如果sqlSession去执行 commit操作(执行插入、更新、删除),清空 SqlSession 中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
-
第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。
11.2.4.测试清空一级缓存
xxxxxxxxxx @Test public void testFindUserById() throws Exception{ UserDao userDao = sqlSession.getMapper(UserDao.class); User user1 = userDao.findUserById(41);//执行查询 System.out.println("第一次查询:" + user1); User user2 = userDao.findUserById(41);//不执行查询 System.out.println("第二次查询:" + user2); sqlSession.commit(); User user3 = userDao.findUserById(41);//执行查询 System.out.println("第三次查询:" + user1); }
11.3.二级缓存
11.3.1.pojo
注意:当我们在使用二级缓存时,所缓存的类一定要实现java.io.Serializable接口,这种就可以使用序列化方式来保存对象。
public class User implements Serializable {private Integer id;private String username;private String password;private Date birthday;private String sex;private String address;//set get... ...
}
11.3.2.开启二级缓存
- 在SqlMapConfig.xml 文件开启二级缓存
<settings><!-- 开启二级缓存的支持 --><setting name="cacheEnabled" value="true"/>
</settings>
- 配置相关的Mapper映射文件
<mapper namespace="com.by.dao.UserDao"><!-- 开启二级缓存的支持 --><cache></cache>
11.3.3.测试二级缓存
@Testpublic void testSecondUserById(){SqlSession sqlSession1 = sqlSessionFactory.openSession();UserDao userDao = sqlSession1.getMapper(UserDao.class);User user1 = userDao.findUserById(41);//执行查询System.out.println("第一次查询:" + user1);sqlSession1.commit();//二级缓存在sqlSession.commit()或者sqlSession.close()之后生效SqlSession sqlSession2 = sqlSessionFactory.openSession();UserDao userDao2 = sqlSession2.getMapper(UserDao.class);User user2 = userDao2.findUserById(41);//不执行查询System.out.println("第二次查询:" + user2);}
11.3.4.二级缓存分析
二级缓存是mapper映射级别的缓存,多个SqlSession去操作同一个Mapper映射的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
二级缓存结构图:

11.3.5.测试清空二级缓存
@Test
public void testSecondUserById(){SqlSession sqlSession1 = sqlSessionFactory.openSession();UserDao userDao = sqlSession1.getMapper(UserDao.class);User user1 = userDao.findUserById(43);//执行查询System.out.println("第一次查询:" + user1);sqlSession1.commit();SqlSession sqlSession3 = sqlSessionFactory.openSession();UserDao userDao3 = sqlSession3.getMapper(UserDao.class);userDao3.deleteUserById(41);sqlSession3.commit();SqlSession sqlSession2 = sqlSessionFactory.openSession();UserDao userDao2 = sqlSession2.getMapper(UserDao.class);User user2 = userDao2.findUserById(43);不执行查询System.out.println("第二次查询:" + user2);sqlSession2.commit();sqlSession2.close();
}
12.MyBatis的注解开发-了解
创建工程:

12.1.注解开发的缺点
MyBatis可以在接口中直接添加MyBatis注解,完成CRUD。
但注解模式属于硬编码到.java文件中,失去了使用配置文件外部修改的优势,可结合需求选用。
12.2.mapper
public interface UserDao {/*** 查询所有用户* @return*/@Select("select * from user")public List<User> findAll();/*** 保存操作* @param user* @return*/@Insert("insert into user(username,sex,birthday,address)values(#{username},“+"#{sex},#{birthday},#{address})")@SelectKey(keyColumn="id",keyProperty="id",resultType=Integer.class,before =false,statement = { "select last_insert_id()" })int saveUser(User user);/*** 更新操作* @param user* @return*/@Update("update user set username=#{username},address=#{address}," +"sex=#{sex},birthday=#{birthday} where id =#{id} ")void updateUser(User user);/*** 删除用户* @param id* @return*/@Delete("delete from user where id = #{id} ")void deleteUser(Integer id);/*** 查询使用聚合函数* @return*/@Select("select count(*) from user ")int findTotal();/*** 根据id查询用户* @return*/@Select("select * from user where id = #{id} ")public User findById(Integer id);/*** 一对多* @return*/@Results(id="resultMap",value= {@Result(id=true,column="id",property="id"),@Result(column="username",property="username"),@Result(column="sex",property="sex"),@Result(column="address",property="address"),@Result(column="birthday",property="birthday"),@Result(column="id",property="accounts",many=@Many(select="com.by.dao.AccountDao.findByuId",fetchType= FetchType.LAZY))})@Select("select * from user")public List<User> findAll2();
}
public interface AccountDao {@Results(id="accountMap",value= {@Result(id=true,column="id",property="id"),@Result(column="uid",property="uid"),@Result(column="money",property="money"),@Result(column="uid",property="user",one=@One(select="com.by.dao.UserDao.findById",fetchType= FetchType.LAZY))})@Select("select * from account")List<Account> findAll();@Select("select * from account where uid = #{uid} ")List<Account> findByuId(Integer id);
}
12.3.pojo
public class User implements Serializable {private Integer id;private String username;private String password;private Date birthday;private String sex;private String address;private List<Account> accounts;//一对多关系映射private List<Account> accounts;// get set toString方法省略
}
public class Account implements Serializable {private Integer id;private Integer uid;private Double money;//一对一关系映射private User user;// get set toString方法省略
}
12.4.测试
@Testpublic void testFindAll() throws Exception{UserDao userDao = sqlSession.getMapper(UserDao.class);List<User> userList = userDao.findAll2();for(User user : userList){System.out.println(user);}}
相关文章:
MyBatis见解4
10.MyBatis的动态SQL 10.5.trim标签 trim标签可以代替where标签、set标签 mapper //修改public void updateByUser2(User user);<update id"updateByUser2" parameterType"User">update user<!-- 增加SET前缀,忽略,后缀…...
Linux操作系统——进程(三) 进程优先级
进程优先级 首先呢,我们知道一个进程呢(或者也可以叫做一个任务),它呢有时候要在CPU的运行队列中排队,要么有时候阻塞的时候呢又要在设备的等待队列中排队,其实我们排队的本质就是:确认优先级。…...
插入排序详解(C语言)
前言 插入排序是一种简单直观的排序算法,在小规模数据排序或部分有序的情况下插入排序的表现十分良好,今天我将带大家学习插入排序的使用。let’s go ! ! ! 插入排序 插入排序的基本思想是将待排序的序列分为已排序和未排序两部分。初始时,…...
Json和Xml
一、前言 学习心得:C# 入门经典第8版书中的第21章《Json和Xml》 二、Xml的介绍 Xml的含义: 可标记性语言,它将数据以一种特别简单文本格式储存。让所有人和几乎所有的计算机都能理解。 XML文件示例: <?xml version"1.…...
STM32 支持IAP的bootloader开发,使用串口通过Ymodem协议传输固件
资料下载: https://download.csdn.net/download/vvoennvv/88658447 一、概述 关于IAP的原理和Ymodem协议,本文不做任何论述,本文只论述bootloader如何使用串口通过Ymodem协议接收升级程序并进行IAP升级,以及bootloader和主程序两个工程的配置…...
【SVN】centos7搭建svn--亲测能通
centos7.6搭建svn 1 知识小课堂1.1 CentOS1.2 SVN 2 搭建过程2.1 前期准备2.2 通过yum命令安装svnserve2.3 创建版本库目录2.4 创建svn版本库2.5 配置修改2.5 防火墙配置2.6 启动或关闭svn服务器2.6.1 进程守护2.6.2 检测svn端口3690是否已经监听:2.6.3 关闭SVN 2.7…...
MY FILE SERVER: 1
下载地址 https://download.vulnhub.com/myfileserver/My_file_server_1.ova 首先我们需要发现ip 我的kali是59.162所以167就是靶机的 然后我们拿nmap扫一下端口 nmap -sV -p- 192.168.59.167 扫完发现有七个端口开放 按照习惯先看80 没看到有啥有用信息,用nikto扫一下 nik…...
Day70力扣打卡
打卡记录 收集足够苹果的最小花园周长(找规律 二分) 链接 class Solution:def minimumPerimeter(self, neededApples: int) -> int:l, r 1, 10 ** 5while l < r:mid (l r) >> 1if 2 * (2 * (mid ** 3) 3 * (mid ** 2) mid) > nee…...
3. 行为模式 - 迭代器模式
亦称: Iterator 意图 迭代器模式是一种行为设计模式, 让你能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。 问题 集合是编程中最常使用的数据类型之一。 尽管如此, 集合只是一组对象的…...
rsync文件同步
场景:主要是用来发布文件。 一、rsync服务器端架设 1、安装 wget https://download.samba.org/pub/rsync/src/rsync-3.0.6.tar.gz tar -zxvf rsync-3.0.6.tar.gz ./configure --prefix/usr/local/rsync make make install 2、配置 2.1、配置rsyncd.conf 不存在…...
docker 安装mysql 8.0.35
1.拉取镜像 docker pull mysql:8.0.35 2.创建相关挂载目录与文件 mkdir -p /opt/mysql8/conf mkdir -p /opt/mysql8/data mkdir -p /opt/mysql8/logs 或者:mkdir -p /opt/mysql8/{data,conf,logs,mysqld,mysql-files} 文件与文件夹授权:chmod -R 775 /opt/mysql8/* 3.运…...
力扣labuladong一刷day46天并查集
力扣labuladong一刷day46天并查集 文章目录 力扣labuladong一刷day46天并查集一、323. 无向图中连通分量的数目二、130. 被围绕的区域三、990. 等式方程的可满足性 一、323. 无向图中连通分量的数目 题目链接:https://leetcode.cn/problems/number-of-connected-co…...
C++11(上):新特性讲解
C11新特性讲解 前言1.列表初始化1.1{ }初始化1.2std::initializer_list 2.类型推导2.1 auto2.2 typeid2.3 decltype 3.范围for4.STL的变化4.1新容器4.2容器的新方法 5.右值引用和移动语义5.1 左值引用和右值引用5.2 左值引用与右值引用比较5.3 右值引用的使用场景5.4 右值、左值…...
将mapper.xml保存为idea的文件模板
将mapper.xml保存为idea的文件模板 在idea的File and Code Templates中将需要使用模板的内容添加为模板文件。 那么接下来请看图,跟着步骤操作吧。 mapper.xml文件内容 <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE mapper P…...
LabVIEW在横向辅助驾驶系统开发中的应用
LabVIEW在横向辅助驾驶系统开发中的应用 随着横向辅助驾驶技术的快速发展,越来越多的研究致力于提高该系统的效率和安全性。项目针对先进驾驶辅助系统(ADAS)中的横向辅助驾驶进行深入研究。在这项研究中,LabVIEW作为一个强大的系…...
STM32移植LVGL图形库
1、问题1:中文字符keil编译错误 解决方法:在KEIL中Options for Target Flash -> C/C -> Misc Controls添加“--localeenglish”。 问题2:LVGL中显示中文字符 使用 LVGL 官方的在线字体转换工具: Online font converter -…...
迪文屏开发保姆级教程5—表盘时钟和文本RTC显示
这篇文章要讲啥事呢? 本篇文章主要介绍了在DGBUS平台上使用表盘时钟和文本时钟RTC显示功能的方法。 文哥悄悄话: 官方开发指南PDF:(不方便下载的私聊我发给你) https://download.csdn.net/download/qq_21370051/8864…...
免费IDEA插件推荐-Apipost-Helper
IDEA插件市场中的API调试插件不是收费(Fast Request )就是不好用(apidoc、apidocx等等)今天给大家介绍一款国产的API调试插件:Apipost-Helper,完全免费且好看好用! 这款插件由Apipost团队开发的…...
Django(二)
1.django框架 1.1 安装 pip install django3.21.2 命令行 创建项目 cd 指定目录 django-admin startproject 项目名mysite ├── manage.py [项目的管理工具] └── mysite├── __init__.py├── settings.py 【配置文件,只有一部分…...
Kafka集群架构服务端核心概念
目录 Kafka集群选举 controller选举机制 Leader partition选举 leader partition自平衡 partition故障恢复机制 follower故障 leader故障 HW一致性保障 HW同步过程 Epoch Kafka集群选举 1. 在多个broker中, 需要选举出一个broker, 担任controller. 由controller来管理…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
