《请写一篇关于【MyBatis基础教程:Java持久层框架入门】的技术文章》

黄艳
2026-05-08 02:29
阅读 5506

去年十月的一个周五晚上,我坐在公司楼下那家24小时营业的麦当劳里,啃着已经凉透的巨无霸,盯着笔记本屏幕上最后一封邮件——“项目暂停,全员待岗通知”。

那是我创业公司倒闭前的最后一周。
月薪从15k降到8k,房租3500还压着没交,异地老婆在微信那头轻声说:“要不…回来吧?”

我没回话,只是默默关掉邮箱,打开了IDEA。

不是逃避现实,是真的得活下去。第二天早上十点,我就要去面试一家传统行业的Java后端岗位——而我对MyBatis几乎一窍不通。


从Vue到Mapper:一个前端被迫“返祖”的七天

是的,我原本是个纯正的前端开发。React/Vue/TypeScript玩得飞起,Webpack配置能闭着眼写。但创业失败后,市场太卷了,前端岗缩招严重。老婆建议我“试试全栈”,至少先找个工作稳住生活。

于是我咬牙买了本《MyBatis从入门到精通》(人民邮电出版社那本,封面是蓝色的),花了98块,在京东下单时手都在抖——这相当于我那时三天的饭钱。

那本书其实写得不错,但全是理论,没有实战。我翻到第三章就卡住了:“为什么XML里写个select就能查数据库?这玩意儿怎么和Spring Boot整合?”

绝望之际,我想起了GPT-4o。别笑,真不是偷懒。那时候我已经没钱报培训班了,GPT成了我的免费导师。

我问它:“用Spring Boot + MyBatis写一个用户查询接口,越简单越好。”

它秒回代码,还带注释。我照着敲,跑起来,居然真能查出MySQL里的数据!那一刻,我差点哭出来——不是因为感动,是因为终于看到一丝希望。


MyBatis到底是什么?说人话版

很多教程一上来就说“MyBatis是一个持久层框架”,听得人一头雾水。我后来才明白:它就是帮你把Java对象和SQL语句“粘”在一起的胶水

比如你有个User类:

public class User {
    private Long id;
    private String name;
    private String email;
    // getter/setter...
}

你想查数据库里的用户,传统JDBC得写一堆Connection、PreparedStatement、ResultSet……又臭又长。

而MyBatis让你只写两样东西:

  1. Mapper接口(Java接口)
  2. XML映射文件(或者用注解)

举个最简单的例子:

// UserMapper.java
@Mapper
public interface UserMapper {
    User findById(Long id);
}
<!-- UserMapper.xml -->
<select id="findById" resultType="com.example.User">
    SELECT id, name, email FROM users WHERE id = #{id}
</select>

然后在Service里直接@Autowired注入UserMapper,调userMapper.findById(1L),就拿到User对象了。

没了。就这么简单。

我当时在麦当劳敲出这段代码并成功返回JSON时,激动得差点把可乐打翻。这就是MyBatis的核心价值:让你专注业务逻辑,而不是和数据库API搏斗


实战踩坑:那些书里不会告诉你的事

书和GPT给的例子都太理想化。真实项目里,坑多得像北京早高峰的地铁。

坑1:Mapper扫描不到

我第一次整合Spring Boot,启动就报错:“No qualifying bean of type 'UserMapper'”。

查了半天,发现忘了在启动类加@MapperScan("com.example.mapper")
或者,也可以在每个Mapper接口上加@Mapper注解——但团队协作时容易漏,所以推荐用@MapperScan统一管理。

坑2:字段名和属性名对不上

数据库字段叫user_name,Java属性叫userName,结果查出来name是null。

解决方案有两个:

  • 在XML里写<resultMap>手动映射(麻烦但灵活)
  • 或者全局配置开启驼峰转换:
# application.yml
mybatis:
  configuration:
    map-underscore-to-camel-case: true

我选后者,省事。

坑3:动态SQL写得像天书

比如要根据条件查询用户:

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

第一次看<where><if>组合,我以为自己在写前端模板。但用熟了之后,发现比拼字符串安全多了——至少不会SQL注入。


为什么不用JPA?为什么不用Go?

面试官问我:“现在Spring Data JPA这么火,你为啥选MyBatis?”

我说实话:“因为可控。”

JPA抽象得太狠,复杂查询时反而绕不开原生SQL。而MyBatis让你既享受ORM的便利,又保留SQL的自由。尤其在传统企业,DBA写的SQL往往很“野”,MyBatis能无缝对接。

至于Go……我也研究过。去年冬天,我甚至用Go+Gin+GORM搭了个小demo,性能确实猛。但问题是:时间成本

我当时只有两周准备面试,Java生态的岗位更多,MyBatis资料更全,社区问题一搜就有答案。而Go虽然简洁,但国内中小企业用得少,异地找工作选择面窄。

老婆也劝我:“先稳住,别折腾新技术了。”
她说得对。生存面前,技术洁癖得放一放。


综合建议:给想转后端的朋友

如果你和我一样,从前端转向后端,或者需要快速掌握MyBatis,我的经验是:

  1. 先跑通一个最小例子:Spring Boot + MyBatis + MySQL,能增删改查就行。别一上来就搞分页、缓存、事务。
  2. 善用GPT-4o,但别依赖:让它生成骨架代码,自己理解每一行。我见过太多人复制粘贴后完全不懂原理,一改就崩。
  3. 买一本靠谱的书:比如前面提到的《MyBatis从入门到精通》,配合官方文档看。书的系统性是碎片化学习无法替代的。
  4. 动手改需求:比如把“查单个用户”改成“查多个用户并排序”,逼自己写动态SQL。
  5. 接受不完美:MyBatis有XML配置的“冗余感”,但这就是它的哲学——显式优于隐式。

现在的生活:从麦当劳到出租屋的灯光

现在我在一家做政务系统的公司做Java开发,月薪22k,虽然加班多,但至少稳定了。我和老婆还在异地,但每周五晚上的视频通话成了雷打不动的仪式。

上周她问我:“你还怀念做前端的日子吗?”

我说:“怀念啊。但人总得向前看。”

MyBatis不是什么高深技术,但它在我最狼狈的时候拉了我一把。它让我明白:技术人的价值,不在于你会多少框架,而在于你能不能用工具解决真实问题

创业失败不可怕,可怕的是失去解决问题的勇气。而MyBatis,就是我重新站起来的第一块砖。


最后一点思考

技术圈总在追逐新潮:云原生、AI编程、Rust、WASM……但有时候,最朴实的工具反而最救命

MyBatis诞生于2002年,比我还老。它没有炫酷的语法糖,没有自动化的魔法,但它稳、准、狠——就像一个沉默的老工人,默默地把数据从数据库搬到你的程序里。

在这个GPT-4o都能写完整CRUD的时代,我们更需要理解底层逻辑。因为AI可以生成代码,但不能替你承担生活的重量

所以,如果你也在低谷,请别嫌弃“老技术”。拿起那本积灰的书,打开IDE,写一行SELECT * FROM hope

说不定,下一次查询,就能查到光。


写于2024年6月,北京出租屋
老婆刚发来消息:“周末高铁票抢到了,周六见。”
我回了个“好”,然后继续调试MyBatis的二级缓存。
生活不易,但值得坚持。

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝