当前位置: 首页 > article >正文

Spring Boot整合MyBatis全攻略:原理剖析与最佳实践

MyBatis作为Java生态中最流行的ORM框架之一,与Spring Boot的结合极大地简化了数据库访问层的开发。本文将深入剖析Spring Boot整合MyBatis的核心机制,详细介绍各种使用方式,并分享实际开发中的高级技巧和最佳实践。

一、Spring Boot与MyBatis整合概述

1.1 整合背景与优势

传统Spring项目中整合MyBatis需要配置大量XML和Bean,而Spring Boot通过自动配置和starter机制,实现了"开箱即用"的MyBatis集成体验。主要优势包括:

  • 零XML配置:基于注解和Java Config的配置方式

  • 自动配置:自动发现DataSource、SqlSessionFactory等

  • 简化分页:内置分页插件支持

  • 强大扩展:支持通用Mapper、MyBatis-Plus等增强工具

1.2 官方支持的整合方式

Spring Boot官方提供了两种MyBatis整合方式:

  1. 经典模式:使用mybatis-spring-boot-starter

  2. 注解模式:使用mybatis-spring-boot-starter + 注解配置

二、快速整合实战

2.1 基础环境搭建

步骤1:添加Maven依赖

<dependencies><!-- Spring Boot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- MyBatis Starter --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.0</version></dependency><!-- 数据库驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- 其他必要依赖 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
</dependencies>

步骤2:配置数据源

spring:datasource:url: jdbc:mysql://localhost:3306/mybatis_demo?useSSL=false&serverTimezone=UTC&characterEncoding=utf8username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver

2.2 自动配置原理剖析

Spring Boot通过MybatisAutoConfiguration类实现自动配置,核心机制包括:

  1. SqlSessionFactory自动创建:基于配置的DataSource

  2. Mapper扫描注册:通过@MapperScan@Mapper注解

  3. 事务管理集成:与Spring事务无缝整合

关键自动配置属性:

mybatis:config-location: classpath:mybatis/mybatis-config.xml  # 全局配置文件路径mapper-locations: classpath:mybatis/mapper/*.xml      # Mapper XML文件位置type-aliases-package: com.example.model              # 类型别名包configuration:                                       # MyBatis配置项map-underscore-to-camel-case: true                 # 下划线转驼峰default-fetch-size: 100default-statement-timeout: 30

三、MyBatis基础使用

3.1 注解方式开发

实体类

@Data
public class User {private Long id;private String username;private String email;private LocalDateTime createTime;
}

Mapper接口

@Mapper
public interface UserMapper {@Select("SELECT * FROM user WHERE id = #{id}")User selectById(Long id);@Insert("INSERT INTO user(username, email, create_time) " +"VALUES(#{username}, #{email}, #{createTime})")@Options(useGeneratedKeys = true, keyProperty = "id")int insert(User user);@Update("UPDATE user SET username=#{username}, email=#{email} WHERE id=#{id}")int update(User user);@Delete("DELETE FROM user WHERE id=#{id}")int delete(Long id);@Select("SELECT * FROM user")List<User> selectAll();
}

3.2 XML方式开发

Mapper接口

@Mapper
public interface UserMapper {User selectById(Long id);int insert(User user);int update(User user);int delete(Long id);List<User> selectAll();
}

XML映射文件 (resources/mapper/UserMapper.xml):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper"><resultMap id="userResultMap" type="User"><id property="id" column="id"/><result property="username" column="username"/><result property="email" column="email"/><result property="createTime" column="create_time"/></resultMap><select id="selectById" resultMap="userResultMap">SELECT * FROM user WHERE id = #{id}</select><insert id="insert" useGeneratedKeys="true" keyProperty="id">INSERT INTO user(username, email, create_time)VALUES(#{username}, #{email}, #{createTime})</insert><update id="update">UPDATE user SET username=#{username}, email=#{email}WHERE id=#{id}</update><delete id="delete">DELETE FROM user WHERE id=#{id}</delete><select id="selectAll" resultMap="userResultMap">SELECT * FROM user</select>
</mapper>

3.3 动态SQL应用

MyBatis提供了强大的动态SQL功能:

<select id="selectByCondition" resultMap="userResultMap">SELECT * FROM user<where><if test="username != null and username != ''">AND username LIKE CONCAT('%', #{username}, '%')</if><if test="email != null and email != ''">AND email = #{email}</if><if test="startTime != null">AND create_time >= #{startTime}</if><if test="endTime != null">AND create_time <= #{endTime}</if></where>ORDER BY id DESC
</select>

对应Mapper接口:

List<User> selectByCondition(@Param("username") String username,@Param("email") String email,@Param("startTime") LocalDateTime startTime,@Param("endTime") LocalDateTime endTime);

四、高级特性与集成

4.1 分页插件集成

步骤1:添加PageHelper依赖

<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.6</version>
</dependency>

步骤2:配置分页参数

pagehelper:helper-dialect: mysqlreasonable: truesupport-methods-arguments: true

步骤3:使用分页查询

public PageInfo<User> getUsers(int pageNum, int pageSize) {PageHelper.startPage(pageNum, pageSize);List<User> users = userMapper.selectAll();return new PageInfo<>(users);
}

4.2 多数据源配置

@Configuration
@MapperScan(basePackages = "com.example.mapper.primary", sqlSessionFactoryRef = "primarySqlSessionFactory")
public class PrimaryDataSourceConfig {@Bean@Primary@ConfigurationProperties("spring.datasource.primary")public DataSource primaryDataSource() {return DataSourceBuilder.create().build();}@Bean@Primarypublic SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();factoryBean.setDataSource(dataSource);factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/primary/*.xml"));return factoryBean.getObject();}@Bean@Primarypublic DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
}// 类似配置第二个数据源(去掉@Primary注解)

4.3 事务管理

Spring Boot自动配置了基于Spring的事务管理,只需使用@Transactional注解:

@Service
public class UserService {private final UserMapper userMapper;private final LogMapper logMapper;public UserService(UserMapper userMapper, LogMapper logMapper) {this.userMapper = userMapper;this.logMapper = logMapper;}@Transactionalpublic void createUserWithLog(User user, String operation) {userMapper.insert(user);Log log = new Log();log.setOperation(operation);log.setCreateTime(LocalDateTime.now());logMapper.insert(log);// 如果此处抛出异常,两个插入操作都会回滚}
}

五、性能优化与最佳实践

5.1 SQL优化建议

  1. **避免SELECT ***:只查询需要的字段

  2. 合理使用索引:通过EXPLAIN分析SQL执行计划

  3. 批量操作:使用<foreach>标签实现批量插入/更新

<insert id="batchInsert">INSERT INTO user(username, email, create_time) VALUES<foreach collection="users" item="user" separator=",">(#{user.username}, #{user.email}, #{user.createTime})</foreach>
</insert>

5.2 缓存配置

一级缓存:SqlSession级别,默认开启
二级缓存:Mapper级别,需要显式开启:

<mapper namespace="com.example.mapper.UserMapper"><cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>...
</mapper>

与Spring Cache集成

@CacheConfig(cacheNames = "users")
public interface UserMapper {@Cacheable(key = "#id")@Select("SELECT * FROM user WHERE id = #{id}")User selectById(Long id);@CacheEvict(allEntries = true)@Update("UPDATE user SET username=#{username} WHERE id=#{id}")int updateUsername(@Param("id") Long id, @Param("username") String username);
}

5.3 监控与诊断

  1. 慢SQL监控:配置mybatis.configuration.log-impl为SLF4J

  2. SQL执行时间统计:使用P6Spy或Druid的Filter

  3. MyBatis指标:与Spring Boot Actuator集成

management:endpoints:web:exposure:include: health,info,metricsmetrics:tags:application: ${spring.application.name}

六、常见问题解决方案

6.1 映射问题

问题:数据库字段与Java属性不匹配
解决

  1. 使用@Result注解或<resultMap>显式映射

  2. 配置mybatis.configuration.map-underscore-to-camel-case=true

6.2 事务不生效

问题@Transactional注解无效
排查

  1. 检查是否在同一个类中调用

  2. 确认方法是否为public

  3. 检查异常类型是否被捕获未抛出

6.3 性能问题

问题:批量操作性能差
优化

  1. 使用ExecutorType.BATCH模式

  2. 合理设置batchSize

  3. 考虑使用MyBatis-Plus的AR模式

@Autowired
private SqlSessionTemplate sqlSessionTemplate;public void batchInsert(List<User> users) {SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);try {UserMapper mapper = session.getMapper(UserMapper.class);for (User user : users) {mapper.insert(user);}session.commit();} finally {session.close();}
}

七、MyBatis-Plus扩展

MyBatis-Plus是MyBatis的增强工具,提供了更多便捷功能:

7.1 快速入门

添加依赖

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version>
</dependency>

实体类

@Data
@TableName("user")
public class User {@TableId(type = IdType.AUTO)private Long id;private String username;private String email;private LocalDateTime createTime;
}

Mapper接口

public interface UserMapper extends BaseMapper<User> {// 已包含基本的CRUD方法
}

7.2 强大功能

  1. 条件构造器

QueryWrapper<User> query = new QueryWrapper<>();
query.like("username", "张").between("create_time", startDate, endDate).orderByDesc("id");
List<User> users = userMapper.selectList(query);

      2.Lambda表达式

LambdaQueryWrapper<User> lambdaQuery = new LambdaQueryWrapper<>();
lambdaQuery.like(User::getUsername, "张").ge(User::getCreateTime, startDate).select(User::getId, User::getUsername);
List<User> users = userMapper.selectList(lambdaQuery);

      3.自动填充 

@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;

 

结语

Spring Boot与MyBatis的整合为Java开发者提供了高效、灵活的数据访问解决方案。通过本文的介绍,您应该已经掌握了从基础配置到高级特性的全面知识。在实际项目中,建议:

  1. 根据项目规模选择合适的开发模式(注解/XML)

  2. 合理利用MyBatis的动态SQL能力

  3. 关注性能优化,特别是批量操作场景

  4. 考虑使用MyBatis-Plus等增强工具提升开发效率

希望本文能帮助您在Spring Boot项目中更好地使用MyBatis,构建健壮高效的数据访问层。

    相关文章:

    Spring Boot整合MyBatis全攻略:原理剖析与最佳实践

    MyBatis作为Java生态中最流行的ORM框架之一&#xff0c;与Spring Boot的结合极大地简化了数据库访问层的开发。本文将深入剖析Spring Boot整合MyBatis的核心机制&#xff0c;详细介绍各种使用方式&#xff0c;并分享实际开发中的高级技巧和最佳实践。 一、Spring Boot与MyBati…...

    十天学会嵌入式技术之51单片机—day-10

    第 20 章 18B20 温度检测 20.1 18B20 概述 20.1.1 简介 18B20 是一种常用的数字温度传感器&#xff0c;广泛应用于环境监测、工业控制、家居自动化 和设备温度监控等领域。 20.1.2 引脚功能 18B20 引脚功能如下图所示&#xff0c;需要特别强调的是&#xff0c;18B20 采用 1-…...

    【C++】17. 多态

    上一章节中我们讲了C三大特性的继承&#xff0c;这一章节我们接着来讲另一个特性——多态 1. 多态的概念 多态(polymorphism)的概念&#xff1a;通俗来说&#xff0c;就是多种形态。多态分为编译时多态(静态多态)和运行时多态(动态多态)&#xff0c;这里我们重点讲运行时多态…...

    Excel的详细使用指南

    ### **一、Excel基础操作** #### **1. 界面与基本概念** - **工作簿&#xff08;Workbook&#xff09;**&#xff1a;一个Excel文件&#xff08;扩展名.xlsx&#xff09;。 - **工作表&#xff08;Worksheet&#xff09;**&#xff1a;工作簿中的单个表格&#xff08;默认名…...

    没经过我同意,flink window就把数据存到state里的了?

    欢迎关注我 不知道大家在初次使用Flink的时候&#xff0c;是否对Flink中定义本地变量和状态比较好奇&#xff0c;这俩有啥区别&#xff1f; 而且在使用Window API时明明没有显式地创建状态&#xff0c;也没调用getState()&#xff0c;却依然把每个窗口里的所有元素都自动缓存…...

    Python+OpenCV打造AR/VR基础框架:从原理到实战的全链路解析

    引言&#xff1a;重新定义数字与现实的边界 在元宇宙概念持续升温的当下&#xff0c;AR&#xff08;增强现实&#xff09;与VR&#xff08;虚拟现实&#xff09;技术正成为连接物理世界与数字世界的桥梁。Python凭借其丰富的计算机视觉生态&#xff08;尤其是OpenCV库&#xf…...

    家用或办公 Windows 电脑玩人工智能开源项目配备核显的必要性(含 NPU 及显卡类型补充)

    一、GPU 与显卡的概念澄清 首先需要明确一个容易误解的概念&#xff1a;GPU 不等同于显卡。 显卡和GPU是两个不同的概念。 【概念区分】 在讨论图形计算领域时&#xff0c;需首先澄清一个常见误区&#xff1a;GPU&#xff08;图形处理单元&#xff09;与显卡&#xff08;视…...

    实现一个简单的 TCP 客户端/服务器

    注意&#xff1a; TCP 三次握手建立连接建立连接后&#xff0c;TCP 提供全双工的通信服务&#xff0c;也就是在同一个连接中&#xff0c;通信双方 可以在同一时刻同时写数据&#xff0c;相对的概念叫做半双工&#xff0c;同一个连接的同一时刻&#xff0c;只能由一方来写数据T…...

    对抗帕金森:在疾病阴影下,如何重掌生活主动权?

    帕金森病&#xff0c;一种影响全球超 1000 万人的神经退行性疾病&#xff0c;正无声地改变着患者的生活轨迹。随着大脑中多巴胺分泌减少&#xff0c;患者逐渐出现肢体震颤、肌肉僵硬、步态迟缓等症状&#xff0c;甚至连扣纽扣、端水杯这类日常动作都变得艰难。更棘手的是&#…...

    鸿蒙 UIAbility组件与UI的数据同步和窗口关闭

    使用 EventHub 进行数据通信 Stage模型概念图 根据 Stage 模型概念图 UIAbility 先于 ArkUI Page 创建 所以&#xff0c;事件要先 .on 订阅 再 emit 发布 假如现在有页面 Page1 和他的 UIAbility // src/main/ets/page1ability/Page1Ability.ets onCreate(want: Want, laun…...

    DeepSeek 赋能汽车全生态:从产品到服务的智能化跃迁

    目录 一、引言二、DeepSeek 助力汽车产品介绍与推广2.1 新车性能参数与技术亮点宣传文案2.2 汽车品牌故事与文化内涵挖掘2.3 汽车广告创意与宣传方案设计 三、DeepSeek 赋能汽车售后服务支持3.1 汽车维修保养知识科普文章创作3.2 常见故障诊断与解决方案生成3.3 汽车用户个性化…...

    MQTT 在Spring Boot 中的使用

    在 Spring Boot 中使用 MQTT 通常会借助 Spring Integration 项目提供的 MQTT 支持。这使得 MQTT 的集成可以很好地融入 Spring 的消息驱动和企业集成模式。 以下是如何在 Spring Boot 中集成和使用 MQTT 的详细步骤&#xff1a; 前提条件&#xff1a; MQTT Broker&#xff…...

    Vue3学习(组合式API——计算属性computed详解)

    目录 一、计算属性computed。 Vue官方提供的案例。(普通写法与计算属性写法) 使用计算属性computed重构——>简化描述响应式状态的复杂逻辑。 &#xff08;1&#xff09;计算属性computed小案例。 <1>需求说明。&#xff08;筛选原数组——>得新数组&#xff09; &…...

    Spring 中的 @ComponentScan注解详解

    在 Spring 框架中,@ComponentScan 是一个非常重要的注解,它用于自动扫描和注册 Bean。通过该注解,Spring 能够自动发现并管理标注了特定注解的类(如 @Component, @Service, @Repository 等),从而实现依赖注入和容器管理。 本文将详细介绍 @ComponentScan 的作用、常见搭…...

    MySQL 数据库故障排查指南

    MySQL 数据库故障排查指南 本指南旨在帮助您识别和解决常见的 MySQL 数据库故障。我们将从问题识别开始&#xff0c;逐步深入到具体的故障类型和排查步骤。 1. 问题识别与信息收集 在开始排查之前&#xff0c;首先需要清晰地了解问题的现象和范围。 故障现象&#xff1a; 数…...

    Android Studio 模拟器配置方案

    Android Studio 模拟器配置方案 1.引言2.使用Android Studio中的模拟器3.使用国产模拟器1.引言 前面介绍【React Native基础环境配置】的时候需要配置模拟器,当时直接使用了USB调试方案,但是有些时候可能不太方便连接手机调试,比如没有iPhone调不了ios。接下来说明另外两种可…...

    k8s中ingress-nginx介绍

    1. 介绍 Ingress是一种Kubernetes资源&#xff0c;用于将外部流量路由到Kubernetes集群内的服务。与NodePort相比&#xff0c;它提供了更高级别的路由功能和负载平衡&#xff0c;可以根据HTTP请求的路径、主机名、HTTP方法等来路由流量。可以说Ingress是为了弥补NodePort在流量…...

    键盘输出希腊字符方法

    在不同操作系统中&#xff0c;输出希腊字母的方法有所不同。以下是针对 Windows 和 macOS 系统的详细方法&#xff0c;以及一些通用技巧&#xff1a; 1.Windows 系统 1.1 使用字符映射表 字符映射表是一个内置工具&#xff0c;可以方便地找到并插入希腊字母。 • 步骤&#xf…...

    字节DeerFlow开源框架:多智能体深度研究框架,实现端到端自动化研究流程

    &#x1f98c; DeerFlow DeerFlow&#xff08;Deep Exploration and Efficient Research Flow&#xff09;是一个社区驱动的深度研究框架&#xff0c;它建立在开源社区的杰出工作基础之上。目标是将语言模型与专业工具&#xff08;如网络搜索、爬虫和Python代码执行&#xff0…...

    MySQL 存储函数[特殊字符] VS 存储过程[特殊字符]

    1、存储函数&#x1f638; 一、存储函数概述 存储函数是MySQL中一种特殊的存储程序&#xff0c;具有以下特点&#xff1a; 返回单个值&#xff1a;必须通过RETURN语句返回明确的结果SQL表达式使用&#xff1a;可以直接在SQL语句中调用输入参数&#xff1a;只接受输入参数(隐…...

    reactor实现TCP遇到的问题和探究

    struct conn{ int fd; char rbuffer[1024]; char wbuffer[1024]; int wlength; int rlength; int (*recv_cb)(int); int (*send_cb)(int); }; int (*recv_cb)(int); recv_cb&#xff1a;函数指针的名称*recv_cb&#xff1a;星号 * 表示 recv_cb 是一个指针。(*recv_cb)&#…...

    ElasticSearch重启之后shard未分配问题的解决

    以下是Elasticsearch重启后分片未分配问题的完整解决方案&#xff0c;结合典型故障场景与最新实践&#xff1a; 一、快速诊断定位 ‌检查集群状态 GET /_cluster/health?pretty # status为red/yellow时需关注unassigned_shards字段值 ‌ 2.查看未分配分片详情 …...

    算法第十八天|530. 二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

    530. 二叉搜索树的最小绝对差 题目 思路与解法 第一想法&#xff1a; 一个二叉搜索树的最小绝对差&#xff0c;从根结点看&#xff0c;它的结点与它的最小差值一定出现在 左子树的最右结点&#xff08;左子树最大值&#xff09;和右子树的最左结点&#xff08;右子树的最小值…...

    QMK键盘编码器(Encoder)(理论部分)

    QMK键盘编码器(Encoder)(理论部分) 前言 作为一名深耕机械键盘DIY多年的老司机,我发现很多键盘爱好者对QMK编码器的配置总是一知半解。今天我就把多年积累的经验毫无保留地分享给大家,从硬件接线到软件配置,从基础应用到高阶玩法,一文全搞定!保证看完就能让你的编码…...

    微服务调试问题总结

    本地环境调试。 启动本地微服务&#xff0c;使用公共nacos配置。利用如apifox进行本地代码调试解决调试问题。除必要的业务微服务依赖包需要下载到本地。使用mvn clean install -DskipTests进行安装启动前选择好profile环境进行启动&#xff0c;启动前记得mvn clean清理项目。…...

    C++(2)

    二、面向对象基础 1. 类与对象 1.1 核心概念 类&#xff08;Class&#xff09; ​​定义​​&#xff1a;抽象描述具有共同特征和行为的对象模板​​本质​​&#xff1a;代码复用的蓝图&#xff0c;定义数据&#xff08;属性&#xff09;与操作&#xff08;行为&#xff0…...

    美SEC主席:探索比特币上市证券交易所

    作者/演讲者&#xff1a;美SEC主席Paul S. Atkins 编译&#xff1a;Liam 5月12日&#xff0c;由美国SEC加密货币特别工作组发起的主题为《资产上链&#xff1a;TradFi与DeFi的交汇点》系列圆桌会议如期举行。 会议期间&#xff0c;现任美SEC主席Paul S. Atkins发表了主旨演讲。…...

    @Controller 与 @RestController-笔记

    1.Controller与RestController对比 Spring MVC 中 Controller 与 RestController 的功能对比&#xff1a; Controller是Spring MVC中用于标识一个类作为控制器的标准注解。它允许处理HTTP请求&#xff0c;并返回视图名称&#xff0c;通常和视图解析器一起使用来渲染页面。而R…...

    JavaScript篇:揭秘函数式与命令式编程的思维碰撞

    大家好&#xff0c;我是江城开朗的豌豆&#xff0c;一名拥有6年以上前端开发经验的工程师。我精通HTML、CSS、JavaScript等基础前端技术&#xff0c;并深入掌握Vue、React、Uniapp、Flutter等主流框架&#xff0c;能够高效解决各类前端开发问题。在我的技术栈中&#xff0c;除了…...

    c++和c的不同

    c:面向对象&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09;&#xff0c;STL&#xff0c;模板 一、基础定义与背景 C语言 诞生年代&#xff1a;20世纪70年代&#xff0c;Dennis Ritchie在贝尔实验室开发。主要特点&#xff1a; 过程式、结构化编程面向系统底层…...