MyBatis开发中常用总结
文章目录
- 常用MyBatis参数映射
- 单个参数
- 多个参数
- 使用索引【不推荐】
- @Param注解
- Map传参
- POJO【推荐】
- List
- 数组
- 动态标签
- \<if>标签
- \<trim>标签
- \<where>标签
- \<set>标签
- \<foreach>标签
- MyBatis查询
- 一对一
- 一对多
常用MyBatis参数映射
单个参数
XML中可以通过 #{xxx}, #{param1} 来获取Mapper接口中的单个参数没有任何限制,即使前后名字不一致的同时也没有@Param注解别名也能传入给XML
但为了开发规范尽量使用和入参时一样,使用@Param注解约定好名称
// Mapper
User selectUserById(Long id);// XML
<select id="selectUserById" parameterType="long" resultMap="BaseResultMap">SELECT * FROM user WHERE id = #{123}
</select>
多个参数
使用索引【不推荐】
// Mapper
User selectUserByIdAndName(Long id, String username);// XML
<select id="selectUserByIdAndName" resultMap="BaseResultMap">SELECT * FROM user WHERE id = #{param1} AND username = #{param2}
</select>
@Param注解
// Mapper
User selectUserByIdAndName(@Param(value = "id") Long id, @Param(value = "username") String username);// XML
<select id="selectUserByIdAndName" resultMap="BaseResultMap">SELECT * FROM user WHERE id = #{id} AND username = #{username}
</select>
Map传参
Mybatis底层也是通过 Map 传参,因此传入也可以一个 Map 作为参数。Map 中的 key 就对应 XML 中 #{key}
单Map参数
// Mapper
User selectUserByIdAndNameMap(Map<String, Object> map);// XML
<select id="selectUserByIdAndNameMap" parameterType="map" resultMap="BaseResultMap">SELECT * FROM user WHERE id = #{id} AND username = #{username}
</select>
简单类型+map
// Mapper
User selectUserByIdAndNameMap(@Param(value = "id") Long id, Map<String, Object> map);// XML
<select id="selectUserByIdAndNameMap" resultMap="BaseResultMap">SELECT * FROM user WHERE id = #{id} AND username = #{map.username}
</select>
简单类型+map
// Mapper
User selectUserByIdAndNameMap(@Param(value = "id") Long id, @Param(value = "map") Map<String, Object> map);// XML
<select id="selectUserByIdAndNameMap" resultMap="BaseResultMap">SELECT * FROM user WHERE id = #{id} AND username = #{map.username}
</select>
测试
Map<String, Object> map=new HashMap<>();
map.put("id", 1);
map.put("username", "Jack");
// 单 map 参数
User user = userMapper.selectUserByIdAndNameMap(map);
// 简单参数+map
User user = userMapper.selectUserByIdAndNameMap(2L, map);
POJO【推荐】
多个参数可以使用实体类封装,key就是属性名,实体类需要有 getXXX()方法
不使用@Param注解
// Mapper
User selectUserByEntity(User user);// XML
<select id="selectUserByEntity" parameterType="app.domain.po.User" resultMap="BaseResultMap">SELECT * FROM user WHERE id = #{id} AND username = #{username}
</select>
使用@Para注解
// Mapper
User selectUserByEntity(@Param(value = "user") User user);// XML
<select id="selectUserByEntity" parameterType="app.domain.po.User" resultMap="BaseResultMap">SELECT * FROM user WHERE id = #{user.id} AND username = #{user.username}
</select>
测试
User user=new User();
user.setId(1L);
user.setUsername("Jack");
User entity = userMapper.selectUserByEntity(user);
List
// Mapper
List<User> selectList(@Param(value = "ids") List<Long> ids);// XML
<select id="selectList" parameterType="list" resultMap="BaseResultMap">SELECT * FROM user WHERE id IN<foreach collection="ids" item="item" separator=", " open="(" close=")">#{item}</foreach>
</select>
测试
List<Long> ids = List.of(1L, 2L, 3L);
List<User> userList = userMapper.selectList(ids);
数组
// Mapper
List<User> selectArray(@Param(value = "ids") Long[] ids);// XML
<select id="selectArray" parameterType="arraylist" resultMap="BaseResultMap">SELECT * FROM user WHERE id IN<foreach collection="ids" item="item" separator=", " open="(" close=")">#{item}</foreach>
</select>
测试
Long[] idsArray = ids.toArray(new Long[0]);
userList = userMapper.selectArray(idsArray);
动态标签
<if>标签
- if标签中的test是传入对象的属性
mapper
int addUser(@Param(value = "userInfo") UserInfo userInfo);
xml
<insert id="addUser" useGeneratedKeys="true" parameterType="app.model.UserInfo" keyColumn="id" keyProperty="id">INSERT INTO userinfo(username,password<if test="userInfo.photo != null">,photo</if>)VALUES(#{userInfo.name},#{userInfo.password}<if test="userInfo.photo != null">,#{userInfo.photo}</if>)
</insert>
<trim>标签
- prefix:表示整个语句块,以prefix的值作为前
缀 - suffix:表示整个语句块,以suffix的值作为后缀
- prefixOverrides:表示整个语句块要去除掉的前
缀 - suffixOverrides:表示整个语句块要去除掉的后缀
mapper
int addUser(@Param(value = "userInfo") UserInfo userInfo);
xml
<insert id="addUser" useGeneratedKeys="true" parameterType="app.model.UserInfo" keyColumn="id" keyProperty="id">INSERT INTO userinfo<trim prefix="(" suffix=")" suffixOverrides=",">username,password,<if test="userInfo.photo != null">photo,</if></trim>VALUES<trim prefix="(" suffix=")" suffixOverrides=",">#{userInfo.name},#{userInfo.password},<if test="userInfo.photo != null">#{userInfo.photo}</if></trim>
</insert>
<where>标签
- where标签会自动清除掉第一个if标签中第一个多余的 and字符串,因此也可以用
<trim prefix="where" preffixOverrides="and"></trim>替换掉where标签。但一般不这么用
List<UserInfo> selectUserByCondition(@Param(value = "userInfo") UserInfo userInfo);
xml
<select id="selectUserByCondition" parameterType="app.model.UserInfo" resultMap="BaseMap">SELECT *FROM userinfo<where><if test="userInfo.name != null">and username = #{userInfo.name}</if><if test="userInfo.photo != null">and photo = #{userInfo.photo}</if><if test="userInfo.createTime != null">and DATE_FORMAT(createtime, '%Y-%m-%d %H:%i:%s') >= DATE_FORMAT(#{userInfo.createTime}, '%Y-%m-%d %H:%i:%s')</if><if test="userInfo.updateTime != null">and DATE_FORMAT(updatetime, '%Y-%m-%d %H:%i:%s') >= DATE_FORMAT(#{userInfo.updateTime}, '%Y-%m-%d %H:%i:%s')</if><if test="userInfo.state != null">and state = #{userInfo.state}</if></where>
</select>
<set>标签
- set标签会自动去除掉最后一个SQL的逗号:“,”。同理,也可以是用
<trime prefix="set" suffixOverridex=",></trim>替换掉set标签。但一般不这么做
mapper
int updateUserByCondition(@Param("userInfo") UserInfo userInfo);
xml
<update id="updateUserByCondition">UPDATE userinfo<set><if test="userInfo.name != null">username = #{userInfo.name},</if><if test="userInfo.photo != null">photo = #{userInfo.photo},</if></set><where><if test="userInfo.id != null">and id >= #{userInfo.id}</if><if test="userInfo.createTime != null">and DATE_FORMAT(createtime, '%Y-%m-%d %H:%i:%s') >= DATE_FORMAT(#{userInfo.createTime}, '%Y-%m-%d %H:%i:%s')</if></where>
</update>
<foreach>标签
- collection:绑定方法参数中的集合的名称,如 List,Set,Map或数组对象「一般配合@Param注解搭配名称使用」
- open:语句块开头的字符串
- close:语句块结束的字符串
- item:遍历时的每一个对象
- separator:每次遍历之间间隔的字符串
mapper
int deleteUserByIds(@Param("idList") List<Integer> idList);
xml
<delete id="deleteUserByIds">DELETEFROM userinfoWHERE id IN<foreach collection="idList" open="(" close=")" item="id" separator=",">#{id}</foreach>
</delete>
MyBatis查询
一对一
数据库
CREATE TABLE `orders` (`id` int NOT NULL AUTO_INCREMENT,`amount` decimal(11,2) DEFAULT NULL,`uid` int NOT NULL,PRIMARY KEY (`id`,`uid`) USING BTREE
)CREATE TABLE `user` (`id` int NOT NULL AUTO_INCREMENT,`username` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,PRIMARY KEY (`id`)
)
一个用户有多个订单【这里只查询一个订单,一对多中会查询多个订单】,一个订单只从属于一个用户
SELECT o.id o_id,o.amount,o.uid o_uid,u.id u_id,u.username
FROM orders oLEFT JOIN `user` u ON o.uid = u.id;
用户实体类
import lombok.Data;@Data
public class User {private Long id;private String username;
}
订单实体类
import lombok.Data;@Data
public class Order {private Long id;private Double amount;private Long uid;// 一对一: 当前订单从属于哪个用户private User user;
}
XML方案一:通过构造新的实体类,resultMap 完成数据封装返回
<?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="app.mapper.OrderMapper"><resultMap id="OrderResultMap" type="app.domain.po.Order"><!--id: 主键property: 实体类属性column: 查询出来的数据库字段--><id property="id" column="o_id"/><result property="amount" column="amount"/><result property="uid" column="o_uid"/><!-- 一对一 --><result property="user.id" column="u_id"/><result property="user.username" column="username"/></resultMap><select id="selectAllOrder" resultMap="OrderResultMap">SELECT o.id o_id,o.amount,o.uid o_uid,u.id u_id,u.usernameFROM orders oLEFT JOIN `user` u ON o.uid = u.id;</select>
</mapper>
XML方案二:使用 resultMap 中的 association 完成封装
<?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="app.mapper.OrderMapper"><resultMap id="OrderResultMap" type="app.domain.po.Order"><id property="id" column="o_id"/><result property="amount" column="amount"/><result property="uid" column="o_uid"/><!-- 一对一 --><association property="user"><id property="id" column="u_id"/><result property="username" column="username"/></association></resultMap><select id="selectAllOrder" resultMap="OrderResultMap">SELECT o.id o_id,o.amount,o.uid o_uid,u.id u_id,u.usernameFROM orders oLEFT JOIN `user` u ON o.uid = u.id;</select>
</mapper>
Mapper接口
List<Order> selectAll();
一对多
数据库
CREATE TABLE `orders` (`id` int NOT NULL AUTO_INCREMENT,`amount` decimal(11,2) DEFAULT NULL,`uid` int NOT NULL,PRIMARY KEY (`id`,`uid`) USING BTREE
)CREATE TABLE `user` (`id` int NOT NULL AUTO_INCREMENT,`username` varchar(256) COLLATE utf8mb4_general_ci DEFAULT NULL,PRIMARY KEY (`id`)
)
一个用户有多个订单,一个订单只从属于一个用户
SELECT u.id u_id,u.username,o.id o_id,o.amount,o.uid o_uid
FROM `user` uLEFT JOIN orders o ON u.id = o.uid;
用户实体类
import lombok.Data;import java.util.List;@Data
public class User {private Long id;private String username;// 一对多: 当前用户有哪些订单private List<Order> orderList;
}
订单实体类
import lombok.Data;@Data
public class Order {private Long id;private Double amount;private Long uid;// 一对一: 当前订单从属于哪个用户private User user;
}
XML
<?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="app.mapper.UserMapper"><resultMap id="UserResultMap" type="app.domain.po.User"><id property="id" column="u_id"/><result property="username" column="username"/><!-- 一对多ofType: 指定集合中的数据类型--><collection property="orderList" ofType="app.domain.po.Order"><id property="id" column="o_id"/><result property="amount" column="amount"/><result property="uid" column="o_uid"/></collection></resultMap><select id="selectAll" resultMap="UserResultMap">SELECT u.id u_id,u.username,o.id o_id,o.amount,o.uid o_uidFROM `user` uLEFT JOIN orders o ON u.id = o.uid</select>
</mapper>
Mapper
List<User> selectAll();
相关文章:
MyBatis开发中常用总结
文章目录 常用MyBatis参数映射单个参数多个参数使用索引【不推荐】Param注解Map传参POJO【推荐】List数组 动态标签\<if>标签\<trim>标签\<where>标签\<set>标签\<foreach>标签 MyBatis查询一对一一对多 常用MyBatis参数映射 单个参数 XML中可…...
Git基本使用教程(学习记录)
参考文章链接: Git教程(超详细,一文秒懂) RUNOOB Git教程 Git学习记录 1Git概述 1.1版本控制软件功能 版本管理:更新或回退到历史上任何版本,数据备份共享代码:团队间共享代码,…...
【Linux-RTC】
Linux-RTC ■ rtc_device 结构体■ RTC 时间查看与设置■ 1、时间 RTC 查看■ 2、设置 RTC 时间 ■ rtc_device 结构体 Linux 内核将 RTC 设备抽象为 rtc_device 结构体 rtc_device 结构体,此结构体定义在 include/linux/rtc.h 文件中 ■ RTC 时间查看与设置 ■ 1…...
机器学习目录
文章目录 基本概念有监督学习回归问题分类问题 无监督学习聚类问题异常检测 基本概念 pass 有监督学习 回归问题 通过拟合函数,解决连续值的预测问题梯度下降法优化;最小二乘法求解;度量指标 均方误差;均方根误差;平…...
React开发环境配置详细讲解-04
环境简介 前端随着规范化,可以说规范和环境插件配置满天飞,笔者最早接触的是jquery,那个开发非常简单,只要引入jquery就可以了,当时还写了一套UI框架,至今在做小型项目中还在使用,show一张效果…...
Go 如何通过 Kafka 客户端库 生产与消费消息
文章目录 0.前置说明1. confluent-kafka-go2. sarama3. segmentio/kafka-go4. franz-go选择建议 1.启动 kafka 集群2.安装 confluent-kafka-go 库3.创建生产者特殊文件说明如何查看.log文件内容 4.创建消费者 0.前置说明 Go 语言中有一些流行的 Kafka 客户端库。以下是几个常用…...
【设计模式深度剖析】【B】【结构型】【对比】| 主要区别包装的不同
👈️上一篇:享元模式 回 顾:结构型设计模式 1.代理模式👈️ 2.装饰器模式👈️ 3.适配器模式👈️ 4.组合模式👈️ 5.桥接模式👈️ 6.外观模式👈️ 7.享元模式&#x…...
信息学奥赛初赛天天练-17-阅读理解-浮点数精准输出与海伦公式的巧妙应用
PDF文档公众号回复关键字:20240531 1 2023 CSP-J 阅读程序1 阅读程序(程序输入不超过数组成字符串定义的范围:判断题正确填√,错误填;除特殊说明外,判断题1.5分,选择题3分,共计40分࿰…...
mysql - 为什么MySQL不建议使用NULL作为列默认值?
为什么MySQL不建议使用NULL作为列默认值? InnoDB有4中行格式: Redundant : 非紧凑格式,5.0 版本之前用的行格式,目前很少使用,Compact : 紧凑格式,5.1 版本之后默认行格式,可以存储更多的数据Dynamic , Compressed : 和Compact类似,5.7 版本之后默认使…...
数据分析案例-在线食品订单数据可视化分析与建模分类
🤵♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞Ǵ…...
构建LangChain应用程序的示例代码:2、使用LangChain库实现的AutoGPT示例:查找马拉松获胜成绩
AutoGPT 示例:查找马拉松获胜成绩 实现 https://github.com/Significant-Gravitas/Auto-GPT,使用LangChain基础组件(大型语言模型(LLMs)、提示模板(PromptTemplates)、向量存储(VectorStores)、嵌入(Embeddings)、工具(Tools))。…...
代码随想录算法训练营第三十四 |● 1005.K次取反后最大化的数组和 ● 134. 加油站 ● 135. 分发糖果
今天的解析写在了代码注释中 1005.K次取反后最大化的数组和 讲解链接:https://programmercarl.com/1005.K%E6%AC%A1%E5%8F%96%E5%8F%8D%E5%90%8E%E6%9C%80%E5%A4%A7%E5%8C%96%E7%9A%84%E6%95%B0%E7%BB%84%E5%92%8C.html class Solution { public:static bool cmp(i…...
GB-T 43206-2023 信息安全技术 信息系统密码应用测评要求
GB-T 43206-2023 信息安全技术 信息系统密码应用测评要求 编写背景 随着信息技术的飞速发展,信息系统在社会经济活动中扮演着越来越重要的角色。信息安全问题也随之成为社会关注的焦点。GB-T 43206-2023《信息安全技术 信息系统密码应用测评要求》是针对信息系统中…...
线程进阶-1 线程池
一.说一下线程池的执行原理 1.线程池的七大核心参数 (1)int corePoolSize:核心线程数。默认情况下核心线程会一直存活,当设置allowCoreThreadTimeout为true时,核心线程也会被超时回收。 (2)i…...
LabVIEW中PID控制器系统的噪声与扰动抑制策略
在LabVIEW中处理PID控制器系统中的噪声和外部扰动,需要从信号处理、控制算法优化、硬件滤波和系统设计四个角度入手。采用滤波技术、调节PID参数、增加前馈控制和实施硬件滤波器等方法,可以有效减少噪声和扰动对系统性能的影响,提高控制系统的…...
JavaWeb笔记整理+图解——Listener监听器
欢迎大家来到这一篇章——Listener监听器 监听器和过滤器都是JavaWeb服务器三大组件(Servlet、监听器、过滤器)之一,他们对于Web开发起到了不可缺少的作用。 ps:想要补充Java知识的同学们可以移步我已经完结的JavaSE笔记&#x…...
AIGC智能办公实战 课程,祝你事业新高度
在数字化时代,人工智能(AI)已经渗透到我们生活的方方面面,从智能家居到自动驾驶,从医疗诊断到金融分析,AI助手正在改变我们的工作方式和生活质量。那么,你是否想过自己也能从零开始,…...
专科生听劝 这种情况你就不要专转本了
罗翔老师说过,读书学习主要作用是提高人的下限 我们能掌握的只有学习,以确保学历不会太差再去等机遇让自己活得更好 大部分情况来说,专科生努力去专转本挺好的提升自己准没错,我当年也是一心这样想的,但今天不得不说点…...
MySQL增删查改初阶
目录 一,数据库操作 1.关键字 show 显示当前数据库有哪些:show databases; 2.创建数据库 3.选中数据库 4.删除数据库 二,表的操作,在选中数据库的基础之上 1.查看表的结构 2.创建表 3.查看当前选中的数据库中…...
IService 接口中定义的常用方法
文心一言生成 以下是一些 IService 接口中定义的常用方法(以你提供的 UserSQL 类为例,该类继承自 ServiceImpl,因此也会拥有这些方法): 插入(新增) boolean save(T entity): 插入一条记录&…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
