1. MyBatis数据操作基础回顾在开始实战之前我们先快速回顾下MyBatis的核心概念。作为Java生态中最受欢迎的ORM框架之一MyBatis通过简单的XML或注解配置就能轻松实现数据库操作。我刚开始接触MyBatis时最让我惊喜的就是它既保留了SQL的灵活性又避免了JDBC的繁琐样板代码。在博客系统这类典型应用中我们最常打交道的就是用户表和博客表。假设现在有个需求当用户修改个人信息时需要同步更新关联的博客数据当用户注销账号时要级联删除其所有博客。这种多表联动操作正是检验MyBatis功力的好场景。先看下基础配置。mybatis-config.xml文件是全局配置入口这里我们配置了类型别名、数据源环境和Mapper接口扫描。注意数据库连接字符串中的useUnicode参数这个细节在中文环境特别重要我曾经因为漏掉这个参数导致中文乱码排查了半天才发现问题。2. 注解方式实现数据更新2.1 Update注解基础用法MyBatis的注解方式让代码更加简洁。先看用户信息更新的实现Update({update t_user set userId #{userId} where userName #{userName}}) int updateUserId(Param(userName) String userName, Param(userId) int userId);这个简单的注解完成了用户ID的更新操作。有几个细节值得注意SQL语句直接写在注解中用#{}引用方法参数Param注解明确指定参数名避免参数顺序问题返回值int表示受影响的行数方便业务判断2.2 多表联动更新实战真正的业务场景往往更复杂。比如用户修改ID后需要同步更新博客表中的用户IDUpdate({update t_blog set userId #{userId2} where userId #{userId1}}) int updateBlog(Param(userId1) int oldUserId, Param(userId2) int newUserId);这里有个坑我踩过更新顺序很重要。正确的做法是先查询原用户ID再执行两个更新操作最后统一提交事务。就像这样User user mapper.selectUserId(userName); mapper.updateUserId(userName, userId); mapper.updateBlog(user.getUserId(), userId); sqlSession.commit();如果不按这个顺序可能会出现数据不一致的情况。我曾经在线上环境就遇到过因为顺序错误导致的部分数据更新失败。3. 数据删除操作详解3.1 单表删除基础删除操作看似简单但需要注意的地方不少。先看基本的用户删除Delete({delete from t_user where userId #{userId}}) boolean deleteUser(int userId);这里我选择返回boolean类型表示删除是否成功。实际开发中你可能还需要考虑删除前检查数据是否存在添加Transactional注解确保事务性记录操作日志3.2 级联删除实现在博客系统中删除用户通常需要级联删除其所有博客Delete({delete from t_blog where userId #{userId}}) boolean deleteBlog(int userId);关键点在于事务控制。必须确保两个删除操作在同一个事务中try { sqlSession sqlSessionFactory.openSession(); UserMapper mapper sqlSession.getMapper(UserMapper.class); mapper.deleteUser(userId); mapper.deleteBlog(userId); sqlSession.commit(); } catch (Exception e) { sqlSession.rollback(); throw e; } finally { sqlSession.close(); }这里我强烈建议添加try-catch块进行异常处理和事务回滚。曾经有个线上事故就是因为没做回滚导致用户删除了但博客还留着造成了数据不一致。4. 事务管理与性能优化4.1 SqlSession的生命周期管理MyBatis的事务管理主要靠SqlSession。新手常犯的错误是忘记关闭SqlSession导致连接泄漏。正确的做法是SqlSession sqlSession null; try { sqlSession sqlSessionFactory.openSession(); // 业务操作 sqlSession.commit(); } finally { if(sqlSession ! null) { sqlSession.close(); } }建议使用try-with-resources语法Java 7try (SqlSession sqlSession sqlSessionFactory.openSession()) { // 业务操作 sqlSession.commit(); }4.2 批量操作优化当需要处理大量数据时单个SQL效率很低。MyBatis提供了批量操作支持try (SqlSession sqlSession sqlSessionFactory.openSession(ExecutorType.BATCH)) { UserMapper mapper sqlSession.getMapper(UserMapper.class); for (User user : users) { mapper.updateUser(user); } sqlSession.commit(); }这种模式下MyBatis会缓存SQL语句最后一次性执行性能可以提升数倍。我在处理用户数据迁移时用这种方式将处理时间从2小时缩短到了15分钟。5. 实战中的常见问题排查5.1 SQL注入防范虽然MyBatis的#{}语法默认可以防止SQL注入但有些场景仍需注意不要使用${}拼接SQL特别是用户输入LIKE查询要特别注意Select(select * from t_user where userName like concat(%, #{name}, %)) ListUser searchUsers(String name);动态SQL中的条件判断也要用#{}5.2 日志调试技巧MyBatis的日志输出非常详细建议在开发环境开启DEBUG日志logger nameorg.mybatis levelDEBUG/ logger namejava.sql levelDEBUG/通过日志可以看到实际执行的SQL语句参数绑定情况事务提交/回滚状态我曾经通过日志发现一个N1查询问题优化后接口响应时间从2s降到了200ms。6. 扩展应用动态SQL注解除了基本的CRUDMyBatis还支持动态SQL。虽然XML方式更强大但注解方式也能实现一些常见场景Update({ script, update t_user, set, if testuserName ! nulluserName#{userName},/if, if testemail ! nullemail#{email},/if, /set, where userId#{userId}, /script }) int updateUserSelective(User user);这种动态更新特别适合前端只传部分字段的场景避免不必要的字段更新。7. 最佳实践总结经过多个项目的实践我总结了以下MyBatis操作建议简单的CRUD优先使用注解复杂SQL考虑XML多表操作一定要放在同一事务中批量操作使用BATCH模式的SqlSession生产环境一定要配置合理的连接池参数重要的删除操作建议先备份再执行定期检查慢查询优化高频SQL在博客系统这类典型应用中用户和博客的关联操作非常频繁。掌握好MyBatis的更新和删除操作能让你在开发后台管理系统时事半功倍。特别是事务控制和性能优化这两块往往是区分新手和老手的关键指标。