当前位置: 首页 > news >正文

MyBatis写法汇总

Mybatis写法汇总

1. 批量操作

1.1 批量插入

<insert id="batchInsert" parameterType="java.util.List">INSERT INTO user (username, password, create_time) VALUES<foreach collection="list" item="item" separator=",">(#{item.username}, #{item.password}, #{item.createTime})</foreach>
</insert>

1.2 批量更新

<update id="batchUpdate" parameterType="java.util.List"><foreach collection="list" item="item" separator=";">UPDATE userSET username = #{item.username}, password= #{item.password}WHERE id = #{item.id}</foreach>
</update>

1.3 批量删除

<delete id="batchDelete" parameterType="java.util.List">DELETE FROM user WHERE id IN<foreach collection="list" item="id" open="(" separator="," close=")">#{id}</foreach>
</delete>

通过使用<foreach> 标签,我们可以将多个操作合并为一条SQL语句,大大减少了数据库交互次数,提高了操作效率。

2. 动态SQL

动态SQL是MyBatis的强大特性之一,允许我们根据不同的条件动态构建SQL语句。<if>标签是实现动态SQL的核心。

2.1 动态查询

<select id="findUsers" resultType="User">SELECT * FROM userWHERE 1=1<if test="username != null and username != ''">AND username LIKE CONCAT('%', #{username}, '%')</if><if test="email != null and email != ''">AND email = #{email}</if><if test="status != null">AND status = #{status}</if>
</select>

3. 多条件分支查询

对于更复杂的查询逻辑,我们可以使用<choose>、<when>和<otherwise>标签来实现多条件分支查询。

<select id="findUsersByCondition" resultType="User">SELECT * FROM userWHERE 1=1<choose><when test="searchType == 'username'">AND username LIKE CONCAT('%', #{keyword}, '%')</when><when test="searchType == 'email'">AND email LIKE CONCAT('%', #{keyword}, '%')</when><otherwise>AND (username LIKE CONCAT('%', #{keyword}, '%') OR email LIKE CONCAT('%', #{keyword}, '%'))</otherwise></choose>
</select>

这个例子展示了如何根据不同的搜索类型选择不同的查询条件,如果没有指定搜索类型,则默认搜索用户名和邮箱。

4. SQL语句优化

使用 <trim> 标签可以帮助我们优化生成的SQL语句,避免出现多余的AND或OR关键字。

<select id="findUsers" resultType="User">SELECT * FROM user<trim prefix="WHERE" prefixOverrides="AND |OR "><if test="username != null and username != ''">AND username LIKE CONCAT('%', #{username}, '%')</if><if test="email != null and email != ''">AND email = #{email}</if><if test="status != null">AND status = #{status}</if></trim>
</select>

在这个例子中,<trim>标签会自动去除第一个多余的AND或OR,并在有查询条件时添加WHERE关键字。

5. 自动生成主键

在插入操作中,我们经常需要获取数据库自动生成的主键。MyBatis提供了<selectKey>标签来实现这一功能。

<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id"><selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">SELECT 2531020</selectKey>INSERT INTO user (username, email, create_time)VALUES (#{username}, #{email}, #{createTime})
</insert>

在这个例子中,插入操作完成后,会自动执行SELECT 2531020获取新插入记录的ID,并将其赋值给传入的User对象的id属性。

6. 注解方式使用MyBatis

除了XML配置,MyBatis还支持使用注解来定义SQL操作,这种方式可以使代码更加简洁。

public interface UserMapper {@Select("SELECT * FROM user WHERE id = #{id}")User getUserById(Long id);@Insert("INSERT INTO user (username, email, create_time) VALUES (#{username}, #{email}, #{createTime})")@Options(useGeneratedKeys = true, keyProperty = "id")int insertUser(User user);@Update("UPDATE user SET username = #{username}, email = #{email} WHERE id = #{id}")int updateUser(User user);@Delete("DELETE FROM user WHERE id = #{id}")int deleteUser(Long id);
}

这种方式适合简单的CRUD操作,但对于复杂的SQL语句,仍然建议使用XML配置。

7. 高级映射

MyBatis提供了强大的对象关系映射功能,可以处理复杂的表关系。

一对多映射示例:

<resultMap id="userWithOrdersMap" type="User"><id property="id" column="user_id"/><result property="username" column="username"/><collection property="orders" ofType="Order"><id property="id" column="order_id"/><result property="orderNumber" column="order_number"/><result property="createTime" column="order_create_time"/></collection>
</resultMap><select id="getUserWithOrders" resultMap="userWithOrdersMap">SELECT u.id as user_id, u.username, o.id as order_id, o.order_number, o.create_time as order_create_timeFROM user uLEFT JOIN orders o ON u.id = o.user_idWHERE u.id = #{userId}
</select>

8. MyBatis-Plus集成

MyBatis-Plus是MyBatis的增强工具,它提供了许多便捷的CRUD操作和强大的条件构造器。

MyBatis-Plus使用示例:

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {public List<User> findUsersByCondition(String username, String email) {return this.list(new QueryWrapper<User>().like(StringUtils.isNotBlank(username), "username", username).eq(StringUtils.isNotBlank(email), "email", email));}
}

在这个例子中,我们使用MyBatis-Plus提供的条件构造器来动态构建查询条件,无需编写XML。

9. 事务管理

在Spring环境中,我们可以使用@Transactional注解来管理事务,确保数据的一致性。
事务管理示例:

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;@Transactionalpublic void createUserWithOrders(User user, List<Order> orders) {userMapper.insert(user);for (Order order : orders) {order.setUserId(user.getId());orderMapper.insert(order);}}
}

在这个例子中,创建用户和订单的操作被包装在一个事务中,如果任何一步失败,整个操作都会回滚。

10. 缓存机制

MyBatis提供了一级缓存和二级缓存,可以有效提高查询性能。

二级缓存配置示例:

<cacheeviction="LRU"flushInterval="60000"size="512"readOnly="true"/>

这个配置启用了LRU淘汰策略的二级缓存,缓存容量为512个对象,每60秒刷新一次。

11. 插件使用

MyBatis插件可以拦截核心方法的调用,实现如分页、性能分析等功能。
分页插件示例 (使用PageHelper):

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public PageInfo<User> getUserList(int pageNum, int pageSize) {PageHelper.startPage(pageNum, pageSize);List<User> users = userMapper.selectAll();return new PageInfo<>(users);}
}

这个例子展示了如何使用PageHelper插件实现简单的分页功能。

12. 多数据源配置

在某些场景下,我们需要在同一个应用中操作多个数据库。MyBatis支持配置多个数据源来实现这一需求。

多数据源配置示例:

@Configuration
public class DataSourceConfig {@Bean@ConfigurationProperties("spring.datasource.primary")public DataSource primaryDataSource() {return DataSourceBuilder.create().build();}@Bean@ConfigurationProperties("spring.datasource.secondary")public DataSource secondaryDataSource() {return DataSourceBuilder.create().build();}@Beanpublic SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();factoryBean.setDataSource(dataSource);return factoryBean.getObject();}@Beanpublic SqlSessionFactory secondarySqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();factoryBean.setDataSource(dataSource);return factoryBean.getObject();}
}

这个配置类定义了两个数据源和对应的SqlSessionFactory,可以在不同的Mapper中使用不同的数据源。

13. 读写分离

读写分离是提高数据库性能的常用策略。MyBatis可以通过配置多数据源来实现简单的读写分离。

读写分离配置示例:

@Configuration
public class DataSourceConfig {@Bean@ConfigurationProperties("spring.datasource.master")public DataSource masterDataSource() {return DataSourceBuilder.create().build();}@Bean@ConfigurationProperties("spring.datasource.slave")public DataSource slaveDataSource() {return DataSourceBuilder.create().build();}@Beanpublic DataSource routingDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,@Qualifier("slaveDataSource") DataSource slaveDataSource) {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put(DataSourceType.MASTER, masterDataSource);targetDataSources.put(DataSourceType.SLAVE, slaveDataSource);AbstractRoutingDataSource routingDataSource = new AbstractRoutingDataSource() {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceContextHolder.getDataSourceType();}};routingDataSource.setTargetDataSources(targetDataSources);routingDataSource.setDefaultTargetDataSource(masterDataSource);return routingDataSource;}
}

这个例子定义了一个动态数据源,可以根据上下文选择主库或从库。你需要实现一个DataSourceContextHolder来管理当前线程的数据源类型。

14. SQL分析和优化

MyBatis提供了SQL执行分析功能,可以帮助我们找出性能瓶颈。
SQL分析配置示例:

<plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"><!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 --><property name="offsetAsPageNum" value="true"/><!-- 设置为true时,使用RowBounds分页会进行count查询 --><property name="rowBoundsWithCount" value="true"/></plugin><plugin interceptor="org.apache.ibatis.plugin.Interceptor"><property name="properties">sqlCollector=com.example.SqlCollector</property></plugin>
</plugins>

在这个配置中,我们不仅加入了分页插件,还加入了一个自定义的SQL收集器,可以用于分析SQL执行情况。

总结

我们详细介绍了14种MyBatis的高级用法和技巧,涵盖了从基本的CRUD操作优化到复杂的多数据源配置和读写分离等高级主题。这些技巧可以帮助开发者更高效地使用MyBatis,构建出性能更好、可维护性更强的应用系统。

相关文章:

MyBatis写法汇总

Mybatis写法汇总 1. 批量操作 1.1 批量插入 <insert id"batchInsert" parameterType"java.util.List">INSERT INTO user (username, password, create_time) VALUES<foreach collection"list" item"item" separator"…...

【Linux学习】十五、Linux/CentOS 7 用户和组管理

文章目录 一、组的管理1.组的创建格式&#xff1a;参数&#xff1a; 2.组的删除格式&#xff1a;参数&#xff1a; 3.组的属性修改格式&#xff1a;参数&#xff1a; 4.查看组的信息①cat /etc/group 命令②getent group 命令③仅显示系统中所有组名 二、用户的管理①超级用户&…...

三维无人机航迹算法的目标函数如何确定

一、定义目标函数 在三维无人机航迹算法中,目标函数的确定通常基于具体的任务需求和飞行约束。以下是一个简单的例子,展示了如何为三维无人机航迹规划定义一个目标函数。 例子:最小化飞行时间和避障的三维无人机航迹规划 1.任务描述:无人机需要从起点飞到终点,同时避开一些…...

uniapp v-tabs修改了几项功能,根据自己需求自己改

根据自己的需求都可以改 这里写自定义目录标题 1.数组中的名字过长&#xff0c;导致滑动异常2.change 事件拿不到当前点击的数据&#xff0c;通过index在原数组中查找得到所需要的id 各种字段麻烦3.添加指定下标下新加红点显示样式 1.数组中的名字过长&#xff0c;导致滑动异常…...

用vscode,进行vue开发

使用Visual Studio Code&#xff08;VSCode&#xff09;进行Vue.js开发是一个很好的选择&#xff0c;因为VSCode提供了强大的编辑功能以及丰富的插件生态。以下是使用VSCode进行Vue开发的基本步骤&#xff1a; 1. 安装Node.js和npm 首先&#xff0c;确保你的计算机上安装了No…...

Kafka 磁道寻址过程详解

前言 Apache Kafka 是一款高吞吐、分布式的消息流平台&#xff0c;广泛应用于实时数据处理和事件驱动系统。在 Kafka 中&#xff0c;消息是存储在磁盘上的&#xff0c;这种高效的数据读写性能得益于 Kafka 独特的磁盘存储架构和寻址机制。本文将从 Kafka 的存储结构、磁道寻址…...

基于Spring Boot的社区药房系统

一、系统背景与目的 随着医疗改革的深入和社区医疗服务的不断完善&#xff0c;社区药房在居民健康保障中扮演着越来越重要的角色。然而&#xff0c;传统的药房管理方式存在着库存管理混乱、药品销售不透明、客户信息管理不规范等问题。为了解决这些问题&#xff0c;基于Spring…...

005 QT常用控件Qwidget_上

文章目录 前言控件概述QWidgetenable属性geometry属性windowTitle属性windowlcon属性 小结 前言 本文将会向你介绍常用的Qwidget属性 控件概述 Widget 是 Qt 中的核心概念. 英文原义是 “⼩部件”, 我们此处把它翻译为 “控件” . 控件是构成⼀个图形化界面的基本要素. QWi…...

机器学习之交叉熵

交叉熵&#xff08;Cross-Entropy&#xff09;是机器学习中用于衡量预测分布与真实分布之间差异的一种损失函数&#xff0c;特别是在分类任务中非常常见。它源于信息论&#xff0c;反映了两个概率分布之间的距离。 交叉熵的数学定义 对于分类任务&#xff0c;假设我们有&#…...

数据结构 ——前缀树查词典的实现

数据结构 ——前缀树查词典的实现 一、前缀树的概念 前缀树是一种多叉树结构&#xff0c;主要用于存储字符串。每个节点代表一个字符&#xff0c;路径从根节点到叶节点表示一个完整的字符串。前缀树的关键特征是 共享前缀&#xff0c;也就是说&#xff0c;如果两个字符串有相…...

MySQL 主从复制与高可用架构

一、MySQL 主从复制概述 &#xff08;一&#xff09;定义与作用 MySQL 主从复制是一种允许在多个 MySQL 数据库服务器之间进行数据同步的技术。简单来说&#xff0c;就是可以把数据从一个 MySQL 服务器&#xff08;主服务器、主节点&#xff09;复制到一个或多个从节点&#…...

【Golang】如何读取并解析SQL文件

一、背景 在数据库开发与维护过程中&#xff0c;我们经常需要执行大量的SQL语句。有时&#xff0c;这些SQL语句会被保存在一个文件中&#xff0c;以便于批量执行。为了方便地在Go语言中处理这些SQL文件&#xff0c;我们可以编写一个函数来读取并解析SQL文件中的语句。 二、实…...

git branch -r(--remotes )显示你本地仓库知道的所有 远程分支 的列表

好的&#xff0c;git branch -r 这个命令用于列出远程分支。让我详细解释一下&#xff1a; 命令&#xff1a; git branch -rdgqdgqdeMac-mini ProductAuthentication % git branch -rorigin/main作用&#xff1a; 这个命令会显示你本地仓库知道的所有 远程分支 的列表。它不…...

Typescript安装

建议全局安装npm i -g typescript安装好之后&#xff0c;就可以直接使用 tsc 来编译 ts 文件了可通过 tsc 回车查看 tsc 的各项配置信息&#xff0c;通过 tsc --version 查看版本号。编译我们现在可以创建一个 ts 文件&#xff0c;并将他编译成 js 文件&#xff0c;比如下面简单…...

使用C#在目录层次结构中搜索文件以查找目标字符串

例程以递归方式搜索目录层次结构中的文件以查找目标字符串。它可以搜索几乎任何类型的文件&#xff0c;即使它不包含 Windows 理解的文本。例如&#xff0c;它可以搜索 DLL 和可执行文件以查看它们是否恰好包含字符串。 下面的代码中显示的ListFiles 方法完成了大部分工作。 …...

基于Redis实现令牌桶算法

基于Redis实现令牌桶算法 令牌桶算法算法流程图优点缺点 实现其它限流算法 令牌桶算法 令牌桶是一种用于分组交换和电信网络的算法。它可用于检查数据包形式的数据传输是否符合定义的带宽和突发性限制&#xff08;流量不均匀或变化的衡量标准&#xff09;。它还可以用作调度算…...

[Java] 使用 VSCode 来开发 Java

目录 前言Java 环境怎么看自己是否已经配置完成&#xff1f;安装 JDK安装 Maven 环境修改 Maven 依赖源 完善 VS Code配置插件配置 Maven配置 Maven Settings配置 Maven 可执行文件地址 前言 由于使用 VSCode 编码已经成为习惯&#xff0c;并且它确实相对其他的 IDE 较为轻量化…...

奇怪的知识又增加了,ESP32下的Lisp编程:ULisp--Lisp for microcontrollers

ESP32下有MicroPython&#xff0c;那么我就在想&#xff0c;有Lisp语言支持吗&#xff1f;答案是果然有&#xff01;有ULisp&#xff0c;专门为MCU设计的Lisp&#xff01; 网址&#xff1a;uLisp - Lisp for microcontrollers 介绍&#xff1a;用于微控制器的 Lisp 适用于 Ar…...

STM32标准库学习之寄存器方法点亮LED灯

STM32C8T6最小系统开发板&#xff0c;点亮PC13引脚的LED灯 1.使能PC13引脚的定时器 PC13引脚为GPIOC组的第13个端口&#xff0c;GPIO的时钟使能定时器为RCC_APB2ENR&#xff0c;这是可以从手册中得出的&#xff0c;如下图所示 从下图可以得出&#xff0c;若要使能GPIOC端口&a…...

Jenkins:持续集成与持续部署的利器

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《未来已来&#xff1a;云原生之旅》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、什么是Jenkins 2、Jenkins的起源 二、Jenkins的核心…...

概率论得学习和整理30: 用EXCEL 描述泊松分布 poisson distribution

目录 1 泊松分布的基本内容 1.1 泊松分布的关键点 1.1.1 属于离散分布 1.1.2 泊松分布的特点&#xff1a;每个子区间内概率相等 &#xff0c; λ就是平均概率 1.2 核心参数 1.3 pmf公式 1.4 期望和方差 2 例1&#xff1a;用EXCEL计算泊松分布的概率 3 比较λ不同值时…...

汽车SoC芯片及其安全岛设计与未来发展趋势(学习笔记)

SoC系列已发布多篇文章&#xff0c;之前应该发布到4.3章节&#xff0c;后续还有包含常见汽车SoC&#xff0c;SoC评价指标&#xff0c;产业链及发展趋势等&#xff0c;均见已发布完整版本付费资源&#xff0c;链接如下&#xff1a; 汽车SoC芯片及其安全岛设计与未来发展趋势&am…...

【排序算法】——选择排序

前言 排序(Sorting) 是计算机程序设计中的一种重要操作&#xff0c;它的功能是将一个数据元素&#xff08;或记录&#xff09;的任意序列&#xff0c;重新排列成一个关键字有序的序列。所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#x…...

第十五章 Linux Shell 编程

15.1 Shell 变量 了解&#xff1a;Shell的功能 了解&#xff1a;Shell的种类 了解&#xff1a;Shell的调用 了解&#xff1a;Shell变量的概念 了解&#xff1a;Shell变量的定义 了解&#xff1a;Shell数组变量 了解&#xff1a;Shell内置变量 了解&#xff1a;双引号 和…...

【c++笔试强训】(第三十八篇)

目录 不相邻取数&#xff08;动态规划-线性dp&#xff09; 题目解析 讲解算法原理 编写代码 空调遥控&#xff08;⼆分/滑动窗⼝&#xff09; 题目解析 讲解算法原理 编写代码 不相邻取数&#xff08;动态规划-线性dp&#xff09; 题目解析 1.题目链接&#xff1a;不相…...

go 自己写序列化函数不转义

以map[int32]string转化为[]byte为例 背景&#xff1a;算法传给我一个map[int32]string类型的值&#xff08;map的值本身是json转化成的string&#xff09;&#xff0c;我需要把这个值生成一个文件上传到OSS&#xff0c;但是发现通过url下载下来的文件里面有转义字符。 原因&a…...

一般行业安全管理人员考试题库分享

1.在高速运转的机械飞轮外部安装防护罩&#xff0c;属于(B)安全技术措施。 A.限制能量 B.隔离 C.故障设计 D.设置薄弱环节 2.生产经营单位的(B)是本单位安全生产的第一责任人&#xff0c;对落实本单位安全生产主体责任全面负责&#xff0c;具体履行安全生产管理职责。 A.全员 B…...

Marketo REST API 批量修改邮件内容

以下是更加细化的 使用 Marketo REST API 批量修改邮件内容 的步骤&#xff0c;详细解释每个阶段的操作&#xff0c;包括 API 的请求、数据处理及潜在问题解决。 前期准备工作 确保 Marketo API 访问权限 你需要 Marketo REST API 用户 和 API Role&#xff0c;有权限访问邮件资…...

《云原生安全攻防》-- K8s安全框架:认证、鉴权与准入控制

从本节课程开始&#xff0c;我们将来介绍K8s安全框架&#xff0c;这是保障K8s集群安全比较关键的安全机制。接下来&#xff0c;让我们一起来探索K8s安全框架的运行机制。 在这个课程中&#xff0c;我们将学习以下内容&#xff1a; K8s安全框架&#xff1a;由认证、鉴权和准入控…...

淘宝获取sku详细信息 API

淘宝获取 SKU 详细信息的 API 主要是 taobao.item_sku 接口&#xff0c;以下是详细介绍&#xff1a; 公共参数 key&#xff1a;调用 key&#xff0c;是调用接口的身份验证信息&#xff0c;必须以 GET 方式拼接在 URL 中1.secret&#xff1a;调用密钥&#xff0c;与 key 配合使…...