做Java开发的朋友,十有八九都用过MyBatis。这东西确实方便,SQL写得顺手,映射也灵活。但很多人用着用着就发现,明明代码逻辑没问题,数据库配置也照着文档来的,可系统一上生产,响应速度就是上不去,动不动就卡死、超时。这时候别急着甩锅给数据库或者硬件,先回头看看MyBatis那几行配置文件,问题往往出在这里。我见过太多团队,把精力花在优化SQL语句上,却忽略了MyBatis本身的配置细节,结果SQL再漂亮,底层配置没跟上,照样白搭。今天咱就聊五个容易忽略但效果立竿见影的配置优化点,看完你就能动手改。

先说第一个,连接池参数。很多人用MyBatis默认的POOLED数据源,觉得开箱即用省事儿。但默认参数真的适合你的业务吗?比如poolMaximumActiveConnections,默认值是10,这在小项目里凑合用,一旦流量上来,十个连接瞬间被抢光,后面的请求只能排队等着。我见过一个电商项目,双十一当天数据库连接池一直满负荷,请求堆积到几百,全部超时。后来把最大值调到50,同时调了poolMaximumIdleConnections和poolMaximumCheckoutTime,情况立马改善。记住,连接池不是越大越好,太大反而拖垮数据库,得根据并发量和数据库吞吐量反复试。
第二个细节,缓存配置。MyBatis自带二级缓存,很多人觉得开了就万事大吉,结果数据不一致、缓存穿透轮着来。问题出在哪儿?一是缓存策略没选对,比如用默认的LRU,但业务场景是频繁更新,缓存命中率极低还占内存。二是刷新间隔没设好,flushInterval设得太长,数据脏读;设得太短,缓存形同虚设。我建议你根据业务特点来:读多写少的场景,比如报表查询,开二级缓存很有用;但高频写入的订单系统,不如直接关掉,省得瞎折腾。还有一点,缓存别用默认的HashMap,生产环境至少换成EhCache或Redis,否则内存迟早炸。
第三个容易被忽视的,是延迟加载。MyBatis的延迟加载默认是关闭的,但很多人为了省事,在配置里把lazyLoadingEnabled设成true,觉得这样能减少数据库查询。想法没错,但实现容易翻车。比如你查用户列表,每个用户关联订单,延迟加载意味着你遍历用户时会触发N+1次SQL查询,性能反而暴跌。我处理过一个案例,一个简单的用户列表页面,因为延迟加载,页面加载时间从200毫秒飙升到8秒。解决方案很简单:要么显式关闭延迟加载,用联表查询一次性取数据;要么用批量抓取,比如设置aggressiveLazyLoading为false,配合fetchType控制粒度。千万别一刀切。
第四个细节,类型处理器的自定义。很多人对typeHandlers视而不见,觉得MyBatis内置的够用。但碰到特殊类型,比如枚举、JSON、自定义对象,默认处理器要么抛异常,要么把数据存成字符串,查询时还得手动转换。我见过一个项目,把状态字段存成整数0和1,业务代码里到处写if判断,代码又臭又长。其实你只需要写一个自定义类型处理器,把枚举和数据库字段做映射,代码瞬间清爽。更关键的是,自定义处理器能避免隐式转换,减少数据库端的计算压力。比如日期类型,默认的DateTypeHandler会把Java的Date和数据库的TIMESTAMP做转换,但如果你用LocalDateTime,就得单独配个处理器,否则每次查询都会多一次类型转换,性能损耗虽小,积少成多也很可观。
第五个,也是很多人最想不到的,是MyBatis的全局配置里那些开关。比如mapUnderscoreToCamelCase,这个开关能把数据库的下划线命名自动映射成驼峰。看起来很美好,但开启后,MyBatis会在每次查询时做一次额外的字段名转换。如果你数据库字段少还好,字段一多,比如几十个列的大表,这个转换的开销就上来了。我做过测试,一个100列的查询,开启这个开关后,映射时间增加了15%左右。所以,如果你的数据库字段命名规范,或者你已经在结果映射里显式配置了字段对应关系,不如关掉这个开关。类似的还有callSettersOnNulls、returnInstanceForEmptyRow这些,每个开关背后都有代价,别盲目全开。
说完这五个点,你可能会觉得,MyBatis配置优化不就是调几个参数吗?但实际工作中,我见过太多团队栽在这些细节上。比如连接池参数,有人照着网上的配置抄,结果跟自己的数据库版本不兼容,连接泄露。再比如缓存,有人开了二级缓存后,更新操作没清缓存,导致用户看到脏数据,被投诉。所以,优化不是抄参数,而是理解每个配置背后的逻辑。你改一个参数,得知道它会影响连接回收、SQL执行、内存占用,甚至事务隔离级别。建议你先在测试环境压一把,把每个参数调到一个极端值,观察数据库CPU、内存、连接数的变化,心里有数了再上生产。
另外,别把配置优化当成一次性工作。系统上线后,业务流量会变,数据量会涨,数据库负载也会变。比如半年后,你的用户量从1万涨到10万,当初调的连接池最大值可能就不够用了。缓存策略也得跟着调,原来用LRU没问题,但现在数据访问模式变了,可能得换成FIFO或者基于时间的策略。我建议你每个月抽时间看一眼MyBatis的监控指标,比如连接池活跃数、缓存命中率、SQL执行耗时,发现异常就及时调整。如果你懒得自己搭监控,至少把MyBatis的日志输出到文件,定期翻翻,也能发现一些苗头。
最后想说,配置优化只是MyBatis性能提升的一个环节,别指望改了这五个点就能解决所有问题。SQL语句的写法、索引的设计、数据库的硬件配置,这些都跟MyBatis配置相辅相成。比如你连接池调得再好,但SQL里用了全表扫描,性能照样上不去。反过来,SQL再快,连接池扛不住并发,也是白搭。所以,把配置优化当成一个起点,而不是终点。下次遇到性能问题,别急着骂数据库,先打开MyBatis的配置文件,看看这五个细节有没有踩坑。改完你会发现,原来性能飙升就这么简单。


