MyBatis中的 10 个宝藏技巧!

大家好,我是苏三,又跟大家见面了。

前言

说到 MyBatis,很多小伙伴都会用,但未必用得“惊艳”。

实际上,这个轻量级的持久层框架还有很多隐藏的“宝藏技巧”。

如果你能掌握这些技巧,不但能让开发更高效,还能避免掉入一些常见的“坑”。

今天就从浅入深,分享 10 个让人眼前一亮的 MyBatis 开发技巧,每一个都配上具体的场景和代码示例,务求通俗易懂,希望对你会有所帮助。

1. 灵活使用动态 SQL

很多小伙伴在写 SQL 的时候,喜欢直接用拼接字符串的方式,比如:

String sql = "SELECT * FROM user WHERE 1=1";
if (name != null) {
    sql += " AND name = '" + name + "'";
}

这种写法不仅麻烦,而且安全性很差(容易引发 SQL 注入)。

MyBatis 的动态 SQL 是专门为解决这种问题设计的,你可以用 ifchooseforeach 等标签来动态构造 SQL。

示例:动态条件查询

<select id="findUser" resultType="User">
    SELECT * FROM user
    WHERE 1=1
    <if test="name != null and name != ''">
        AND name = #{name}
    </if>
    <if test="age != null">
        AND age = #{age}
    </if>
</select>

这个代码的好处是,SQL 逻辑清晰,不会因为某个参数为空就导致整个 SQL 报错。

2. 善用 resultMap 自定义结果映射

有些小伙伴会遇到这样的问题:数据库表字段是下划线命名,但 Java 对象是驼峰命名。比如 user_name 对应 userName。如果直接用默认的 resultType,MyBatis 是无法自动映射的。

这个时候,用 resultMap 就能完美解决。

示例:自定义结果映射

<resultMap id="userResultMap" type="User">
    <id column="id" property="id"/>
    <result column="user_name" property="userName"/>
    <result column="age" property="age"/>
</resultMap>

<select id="getUserById" resultMap="userResultMap">
    SELECT id, user_name, age FROM user WHERE id = #{id}
</select>

有了 resultMap,再复杂的字段映射都可以轻松搞定。

3. 利用 foreach 实现批量操作

有些小伙伴可能会遇到这种需求:传入一个 ID 列表,查询所有匹配的用户信息。如果用拼接字符串的方式生成 IN 条件,不但代码丑,还容易踩坑。

MyBatis 提供了 foreach 标签,可以优雅地处理这种场景。

示例:批量查询

<select id="findUsersByIds" resultType="User">
    SELECT * FROM user WHERE id IN
    <foreach item="id" collection="idList" open="(" separator="," close=")">
        #{id}
    </foreach>
</select>

传入的 idList 是一个 List 或数组,MyBatis 会自动帮你展开为 IN (1, 2, 3) 这样的格式,完全不用担心语法问题。

4. MyBatis-Plus 的分页功能

很多小伙伴在做分页的时候,习惯自己写 LIMIT 的 SQL,这样不仅麻烦,还容易出错。

其实,用 MyBatis-Plus 的分页插件能省不少事。

示例:MyBatis-Plus 分页功能

Page<User> page = new Page<>(1, 10); // 第 1 页,每页 10 条
IPage<User> userPage = userMapper.selectPage(page, null);
System.out.println("总记录数:" + userPage.getTotal());
System.out.println("当前页数据:" + userPage.getRecords());

只需引入分页插件,就能轻松完成分页操作,简直不要太爽。

5. 使用 @Mapper的接口代理

有些小伙伴觉得 XML 文件太多太麻烦,其实 MyBatis 支持纯注解的开发模式,尤其是对于简单的 SQL,非常方便。

示例:注解方式查询

@Mapper
public interface UserMapper {

    @Select("SELECT * FROM user WHERE id = #{id}")
    User getUserById(int id);

    @Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})")
    void addUser(User user);
}

用这种方式,可以完全省掉 XML 配置,代码更加简洁。

6. 二级缓存

MyBatis 内置了一级缓存(SqlSession 范围内),但对于多次查询的场景,可以开启二级缓存来提升性能。

示例:开启二级缓存

<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration>

<mapper namespace="com.example.mapper.UserMapper">
    <cache/>
    <select id="getUserById" resultType="User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>

开启二级缓存后,同一个 Mapper 下的查询会自动命中缓存,大幅提高性能。

7. 动态表名切换

有些多租户系统需要在运行时切换表名,比如按租户分表。这种情况下,可以用 MyBatis 的动态 SQL 特性来实现。

示例:动态表名

<select id="getDataFromDynamicTable" resultType="Map">
    SELECT * FROM ${tableName} WHERE id = #{id}
</select>

在调用时传入 tableName 参数,MyBatis 会动态替换表名。

8. 用 typeHandler 自定义类型处理

有些小伙伴可能遇到过这种场景:数据库存的是 1/0,但在代码里想用 true/false 表示。

这种情况可以通过自定义 typeHandler 来实现。

示例:自定义 TypeHandler

@MappedTypes(Boolean.class)
@MappedJdbcTypes(JdbcType.INTEGER)
public class BooleanTypeHandler extends BaseTypeHandler<Boolean> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Boolean parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i, parameter ? 1 : 0);
    }

    @Override
    public Boolean getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return rs.getInt(columnName) == 1;
    }
}

在 MyBatis 配置中注册这个 typeHandler,就可以实现自动类型转换了。

9. 日志调试,快速排查问题

开发中经常需要排查 SQL 执行的问题,这时 MyBatis 的日志功能非常好用。

通过配置,可以轻松打印出完整的 SQL 和参数。

示例:开启日志

<configuration>
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
</configuration>

日志会输出类似下面的内容:

==>  Preparing: SELECT * FROM user WHERE id = ?
==> Parameters: 1(Integer)
<==      Total: 1

有了这些日志,排查问题再也不头疼了。

10. 多数据源支持

当系统需要连接多个数据库时,可以通过 MyBatis 的多数据源配置轻松搞定。

示例:配置多数据源

@Configuration
@MapperScan(basePackages = "com.example.mapper", sqlSessionTemplateRef = "sqlSessionTemplate1")
public class DataSourceConfig1 {
    @Bean(name = "dataSource1")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "sqlSessionFactory1")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource1") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
    }

    @Bean(name = "sqlSessionTemplate1")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

通过类似的配置,就可以轻松切换多个数据源。

总结

MyBatis 的魅力在于简单、高效,但很多时候我们用得太“基础”,没有发挥它的全部潜力。

希望这 10 个技巧能帮你更高效地使用 MyBatis,也让你的代码看起来更“惊艳”。

如果觉得有帮助,记得收藏分享!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智能座舱进阶-应用框架层-Jetpack主要组件

Jetpack的分类 1. DataBinding&#xff1a;以声明方式将可观察数据绑定到界面元素&#xff0c;通常和ViewModel配合使用。 2. Lifecycle&#xff1a;用于管理Activity和Fragment的生命周期&#xff0c;可帮助开发者生成更易于维护的轻量级代码。 3. LiveData: 在底层数据库更…

登山第十六梯:深度恢复——解决机器人近视问题

文章目录 一 摘要 二 资源 三 内容 一 摘要 深度感知是基于 3D 视觉的机器人技术的一个重要问题。然而&#xff0c;现实世界的主动立体或 ToF 深度相机经常会产生嘈杂且深度不完整&#xff0c;从而成为机器人性能的瓶颈。在这项工作中&#xff0c;提出了 一个基于学习的立体…

【Jenkins】持久化

文章目录 持续集成CI持续部署CD部署部署到linux服务器 持续集成好处&#xff1a; 持续集成CI 持续集成&#xff08;Continuous integration&#xff0c;简称CI&#xff09;指的是频繁地&#xff08;一天多次&#xff09;将代码集成到主干。 持续集成的目的就是让产品可以快速…

小红书飞书素材库 | AI改写 | 无水印下载 | 多维表格 | 采集同步 | 影刀RPA

小红书飞书素材库 | AI改写 | 无水印下载 | 多维表格 | 采集同步 | 影刀RPA 模板准备 进入【小红书】素材采集库_荷逸模板&#xff0c;点击使用模板 创建文档应用 在开发者后台 - 飞书开放平台创建 企业自建应用 (需要账号有相应的权限, 如果没有权限向管理员申请) 获取 Ap…

layui动态拼接生成下拉框验证必填项失效问题

利用 jQuery 动态拼接下拉框时&#xff0c;lay-verify"required" 失效了&#xff0c;有以下几种原因。 1. <form></form>标签 加入 layui 类&#xff0c;class"layui-form" 。提交按钮上加自动提交&#xff0c;lay-submit ""; 。需…

合合信息:探索视觉内容安全新前沿

2024年12月13日-15日&#xff0c;中国图象图形学学会在杭州召开。大会期间&#xff0c;来自合合信息的图像算法研发总监郭丰俊进行了主题为“视觉内容安全技术的前沿进展与应用”的演讲&#xff0c;介绍了视觉内容安全问题&#xff0c;并总结了现今的技术发展&#xff0c;对我很…

阿里云cdn稳定吗?

阿里云CDN&#xff08;内容分发网络&#xff09;是阿里云提供的一项全球加速服务&#xff0c;它的稳定性通常被认为是非常高的&#xff0c;尤其在国内市场。九河云给大家总结了阿里云CDN的稳定性情况&#xff1a; 1. 全球节点覆盖广泛 阿里云CDN在全球范围内拥有数百个加速节…

本地部署webrtc应用怎么把http协议改成https协议?

环境&#xff1a; WSL2 Ubuntu22.04 webrtc视频聊天应用 问题描述&#xff1a; 本地部署webrtc应用怎么把http协议改成https协议&#xff1f; http协议在安卓手机浏览器上用不了麦克风本&#xff0c;来地应用webrtc 本来是http协议&#xff0c;在安卓手机上浏览器不支持使…

Qt creator ,语言家功能缺失解决方法

1、找到工具->外部->配置 2、添加目录&#xff0c;双击命名语言家 3、在语言家目录下&#xff0c;添加工具 双击重命名lupdate&#xff0c;即更新翻译 %{CurrentDocument:Project:QT_INSTALL_BINS}\lupdate%{CurrentDocument:Project:FilePath}%{CurrentDocument:Projec…

用于UISystem的工具集

简介&#xff1a;上篇文章用于管理Unity中UGUI的工具系统UISystem-CSDN博客讲了UISystem&#xff0c;为了更加方便使用&#xff0c;我给他写了一个编辑器工具&#xff0c;下面展示代码和使用说明&#xff0c;具体详情不难看一下就看懂了。 一、代码部分 using QFramework; us…

onlyoffice连接器 二次开发 合同等制式模板化技术开发方案【三】

一、期望效果 目前曹瑞版本onlyoffice已经实现&#xff1a;书签模式 和 控件模式&#xff0c;用以支持该方案。 【图1】字段绑定 【图2】模板发起 【图3】接入表单 思路讲解&#xff1a; 业务系统开发中通常希望能够通过绑定form字段给word&#xff0c;从而达到双向同步效果&am…

WPF+MVVM案例实战与特效(四十五)- 打造优雅交互:ListBox 的高级定制与行为触发(侧边菜单交互面板)

文章目录 1、引言2、案例效果3、案例实现1、依赖安装2、文件创建3、代码实现1、依赖引用与上下文2、个性化视觉效果:自定义 ItemContainerStyle3、页面样式与布局完整代码4、ViewModel 逻辑实现5、子界面代码:3、实现效果4、源代码获取5、总结1、引言 在WPF应用程序开发中,…

【优选算法】复写零

链接&#xff1a;1089. 复写零 - 力扣&#xff08;LeetCode&#xff09; 算法原理&#xff1a; 解法&#xff1a;双指针算法 根据“异地”操作&#xff0c;然后优化成双指针下的“就地”操作 1.先找到最后一个“复写”的数 1.先判断 cur 位置的值 2.决定 dest 向后移动一步或…

moviepy将图片序列制作成视频并加载字幕 - python 实现

DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(free)” -------------------------------------------------------------…

ubuntu20.04安装imwheel实现鼠标滚轮调速

ubuntu20.04安装imwheel实现鼠标滚轮调速 Ubuntu 系统自带的设置中仅具备调节鼠标速度的功能&#xff0c;而无调节鼠标滚轮速度的功能。其默认的鼠标滚轮速度较为缓慢&#xff0c;在查看文档时影响尚可接受&#xff0c;但在快速浏览网页时&#xff0c;滚轮速度过慢会给用户带来…

ubuntu开机进入initramfs状态

虚拟机卡死成功起后进入了initramfs状态&#xff0c;可能是跟文件系统有问题或者检索不到根文件系统&#xff0c;或者是配置错误&#xff0c;系统磁盘等硬件问题导致 开机后进入如下图的界面&#xff0c; 文中有一条提示 要手动fsck 命令修复 /dev/sda1 命令如下 fsck /de…

STL格式转换为OBJ格式

STL格式与OBJ格式简介 STL格式 STL&#xff08;Stereo Lithography&#xff09;文件是一种用于3D打印和计算机辅助制造&#xff08;CAM&#xff09;的文件格式。它最初由3D Systems公司开发&#xff0c;主要用于立体光刻技术。STL文件通常分为二进制和ASCII两种格式&#xff…

git命令恢复/还原某个文件、删除远程仓库中的文件

有时刚创建的远程仓库&#xff0c;可能无意中把一些没用的文件上传到仓库&#xff0c;本文介绍一下怎么删除这些文件。 一、git命令恢复某个文件 第一步&#xff1a;拉取最新代码 git pull 第二步&#xff1a; 查看git 修改的文件状态 git status 第三步&#xff1a;查看…

Chapter 3-1. Detecting Congestion in Fibre Channel Fabrics

Chapter 3. Detecting Congestion in Fibre Channel Fabrics This chapter covers the following topics: 本章包括以下主题: Congestion detection workflow. Congestion detection metrics. Congestion detection metrics and commands on Cisco MDS switches. Automatic A…

音视频入门基础:MPEG2-TS专题(20)——ES流简介

《T-REC-H.222.0-202106-S!!PDF-E.pdf》第27页对ES进行了定义。ES流是PES packets&#xff08;PES包&#xff09;中编码的视频、编码的音频或其他编码的比特流。一个ES流&#xff08;elementary stream&#xff09;在具有且只有一个stream_id的PES packets序列中携带&#xff1…