首页 > 其他分享 >MyBatis中的 10 个宝藏技巧!

MyBatis中的 10 个宝藏技巧!

时间:2025-01-10 11:12:22浏览次数:1  
标签:10 name 示例 user SQL MyBatis 宝藏 id

前言

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

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

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

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

(我最近开源了一个基于 SpringBoot+Vue+uniapp 的商城项目,欢迎访问和star。)[https://gitee.com/dvsusan/susan_mall]

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,也让你的代码看起来更“惊艳”。

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

最后说一句(求关注,别白嫖我)

如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下我的同名公众号:苏三说技术,您的支持是我坚持写作最大的动力。

求一键三连:点赞、转发、在看。

关注公众号:【苏三说技术】,在公众号中回复:进大厂,可以免费获取我最近整理的10万字的面试宝典,好多小伙伴靠这个宝典拿到了多家大厂的offer。

标签:10,name,示例,user,SQL,MyBatis,宝藏,id
From: https://www.cnblogs.com/12lisu/p/18663607

相关文章

  • 10分钟白话call、apply、bind八股文
    主题:用最简单,通俗白话解说。目标1:学好一个call小目标,另外2个旁通soeasy正题入口:作用1:call函数的调用意思是函数的方法实践出真知:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metaname="viewport"cont......
  • IEC104的复位进程与心跳机制详解
    IEC104规约作为网络通信规约,广泛应用于厂站与配网主站之间的通信。在IEC104规约中,复位进程和心跳机制是确保通信稳定性和可靠性的重要环节。复位进程主要用于某些特殊情况下需要终端重启,一般用于数据重置;而心跳机制则用于检测通信链路的健康状态,防止因长时间无数据传输而导致的......
  • CefSharp.WinForms指定了低版本108.4.130,可是生成后的dll版却是121.3.7.0
    问题:CefSharp.WinForms指定了低版本108.4.130 生成的libcef.dll版本却是121.3.7.0,  分析:之前有指定版本121.3.7.0并生成过。怀疑用的是之前的版本,然后之前的版本的缓存在本地的哪个位置。于是删除项目底下packages\CefSharp.WinForms.108.4.130packages\CefSharp.Comm......
  • 题解:CF1031F Familiar Operations
    传送门Solution之前有遇到类似的题,第一步先考虑转化操作和问题。对于每个数质因数分解成\(\prod{p_i^{\alpha_i}}\),我们所需要的只有\(\alpha_i\),因为只要求因子个数相同。记其为\(S_i=\{\alpha_1,\alpha_2,\dots,\alpha_k\}\),其中\(\alpha_1\geq\alpha_2\geq\dots......
  • 解决 PbootCMS IP 黑名单只能填写 10 多条 IP 地址的问题
    在使用PbootCMS的IP黑名单功能时,如果发现只能添加10多条IP地址,多了保存不了,通常是因为 ay_config 表中存储IP黑名单的字段长度有限。通过修改数据库表结构,可以增加该字段的长度,从而支持更多的IP地址。以下是详细的解决步骤:一、问题分析字段长度限制:ay_config......
  • 在使用 PbootCMS 的 IP 黑名单功能时,如果发现只能添加 10 多条 IP 地址,多了保存不了,通
    1.备份数据库在进行任何数据库操作之前,请务必备份数据库,以防数据丢失。mysqldump-uyour_username-pyour_database_name>backup.sql2.登录数据库管理工具使用phpMyAdmin或其他数据库管理工具登录到您的MySQL数据库。3.修改 ay_config 表结构找到 ay_conf......
  • P1080 [NOIP2012 提高组] 国王游戏
    P1080[NOIP2012提高组]国王游戏题目恰逢H国国庆,国王邀请\(n\)位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这\(n\)位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的......
  • WiFi+4G摄像头拍照图传模块(夜视2K高清1080P)-基础功能-连接wifi路由器和开无线热点
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/product/audioCamera.html"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p> 说明这节测......
  • MyBatis 动态 SQL、多表查询与注解开发详解
    MyBatis动态SQL、多表查询与注解开发详解1.MyBatis动态SQLMyBatis提供了强大的动态SQL功能,允许我们根据不同的条件拼接SQL语句,避免了手动拼接SQL的繁琐和错误。常见的动态SQL标签包括:if:用于条件判断,根据条件是否成立来决定是否拼接SQL片段。choose(when,ot......
  • [20250109]dbms_xplan.display_cursor+peeked_binds无法查看绑定变量值.txt
    [20250109]dbms_xplan.display_cursor+peeked_binds无法查看绑定变量值.txt--//在我使用自己写的dpc.sql脚本中我会加入peeked_binds参数查看绑定变量值,但是有时候会遇到无法查看的情况。--//以前自己很少关注这个细节,应该有别的途径获取绑定变量值,最近在优化一条sql语句正好遇到,......