Spring Boot集成MyBatis与MySQL

Spring Boot集成MyBatis与MySQL开发全攻略

一、前言:现代Java持久层开发的选择

在微服务架构盛行的今天,Spring Boot以其"约定优于配置"的理念成为Java开发的事实标准。结合MyBatis这一灵活高效的ORM框架和MySQL这一成熟稳定的关系型数据库,构成了企业级应用开发的黄金三角组合。本文将深入探讨三者的整合之道,通过实战案例揭示其核心技术要点。

二、核心技术解析

2.1 Spring Boot的自动配置魔法

  • 启动原理:通过@SpringBootApplication注解触发自动配置
  • 依赖管理:starter机制简化依赖版本管理
  • 嵌入式容器:默认集成Tomcat/Jetty等Web容器

2.2 MyBatis的核心竞争力

  • SQL可见性:完整掌控SQL语句编写
  • 动态SQL:支持if/choose/when等条件语句
  • 插件扩展:支持分页、性能分析等插件
java 复制代码
// 动态SQL示例
public interface UserMapper {
    @SelectProvider(type = UserSqlBuilder.class, method = "buildGetUsersByCriteria")
    List<User> getByCriteria(UserCriteria criteria);
    
    class UserSqlBuilder {
        public String buildGetUsersByCriteria(UserCriteria criteria) {
            return new SQL(){{
                SELECT("*");
                FROM("users");
                if (criteria.getUsername() != null) {
                    WHERE("username = #{username}");
                }
                if (criteria.getEmail() != null) {
                    WHERE("email LIKE CONCAT(#{email}, '%')");
                }
                ORDER_BY("create_time DESC");
            }}.toString();
        }
    }
}

2.3 MySQL的工程实践优势

  • 事务支持:完整ACID特性实现
  • 存储引擎:InnoDB与MyISAM的选型策略
  • 性能优化:索引策略与查询优化器

三、系统集成架构

3.1 分层架构设计

复制代码
┌─────────────┐
│   Client    │
└──────┬──────┘
       │
┌──────▼──────┐
│ Controller  │
└──────┬──────┘
       │
┌──────▼──────┐
│   Service   │
└──────┬──────┘
       │
┌──────▼──────┐
│   Mapper    │
└──────┬──────┘
       │
┌──────▼──────┐
│   MySQL     │
└─────────────┘

3.2 数据流向示意图

Client Controller Service Mapper MySQL HTTP Request 调用业务方法 执行数据操作 发送SQL指令 返回数据集 封装领域对象 返回处理结果 HTTP Response Client Controller Service Mapper MySQL

四、详细实现步骤

4.1 项目初始化(IntelliJ IDEA版)

  1. 创建Spring Boot项目(2.7.x+)
  2. 选择依赖:Web、MyBatis、MySQL Driver
  3. 配置pom.xml验证依赖项
xml 复制代码
<!-- 关键依赖示例 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

4.2 数据库配置进阶

yaml 复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/app_db?characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
    username: app_user
    password: s3cr3tP@ss
    hikari:
      connection-timeout: 3000
      maximum-pool-size: 20

mybatis:
  configuration:
    default-fetch-size: 100
    default-statement-timeout: 30
    map-underscore-to-camel-case: true
  type-aliases-package: com.example.domain

4.3 领域模型设计

java 复制代码
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Long id;
    private String username;
    private String encryptedPassword;
    private String email;
    private UserStatus status;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}

public enum UserStatus {
    ACTIVE, INACTIVE, LOCKED
}

4.4 数据访问层实现

注解方式
java 复制代码
@Mapper
public interface UserMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    @Results({
        @Result(property = "createTime", column = "create_time"),
        @Result(property = "updateTime", column = "update_time")
    })
    User selectById(Long id);
}
XML映射方式
xml 复制代码
<!-- resources/mapper/UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper">
    <resultMap id="userResultMap" type="User">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="encryptedPassword" column="encrypted_password"/>
        <result property="email" column="email"/>
        <result property="status" column="status" 
                typeHandler="org.apache.ibatis.type.EnumTypeHandler"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>

    <select id="selectAll" resultMap="userResultMap">
        SELECT * FROM users
    </select>
</mapper>

4.5 事务管理实践

java 复制代码
@Service
@RequiredArgsConstructor
public class UserRegistrationService {
    private final UserMapper userMapper;
    private final AuditLogMapper auditLogMapper;

    @Transactional(rollbackFor = Exception.class)
    public void registerUser(User user) {
        userMapper.insert(user);
        auditLogMapper.logEvent("USER_REGISTER", user.getId());
        // 其他业务操作...
    }
}

五、高级特性应用

5.1 MyBatis插件开发

实现SQL执行时间监控:

java 复制代码
@Intercepts({
    @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
    @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
})
public class SqlCostInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        long start = System.currentTimeMillis();
        try {
            return invocation.proceed();
        } finally {
            long cost = System.currentTimeMillis() - start;
            System.out.println("SQL执行耗时:" + cost + "ms");
        }
    }
}

5.2 多数据源配置

java 复制代码
@Configuration
@MapperScan(basePackages = "com.example.primary.mapper", 
           sqlSessionFactoryRef = "primarySqlSessionFactory")
public class PrimaryDataSourceConfig {
    
    @Bean
    @ConfigurationProperties("spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public SqlSessionFactory primarySqlSessionFactory(
            @Qualifier("primaryDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource);
        factory.setMapperLocations(
            new PathMatchingResourcePatternResolver()
                .getResources("classpath:mapper/primary/*.xml"));
        return factory.getObject();
    }
}

六、性能优化策略

6.1 查询优化方案

优化手段 实施方法 预期效果
二级缓存 配置标签 减少数据库访问
批量插入 使用foreach标签 提升写入性能
延迟加载 配置lazyLoadingEnabled=true 减少内存消耗
分页插件 集成PageHelper 简化分页操作

6.2 索引优化示例

sql 复制代码
-- 创建复合索引
CREATE INDEX idx_users_username_email ON users(username, email);

-- 执行计划分析
EXPLAIN SELECT * FROM users WHERE username = 'john' AND email LIKE '%@example.com';

七、测试验证方案

7.1 单元测试示例

java 复制代码
@SpringBootTest
class UserMapperTest {
    
    @Autowired
    private UserMapper userMapper;

    @Test
    @Sql(scripts = "/test-data.sql")
    void testSelectById() {
        User user = userMapper.selectById(1L);
        assertThat(user.getUsername()).isEqualTo("testuser");
    }
}

7.2 API测试脚本

bash 复制代码
# 创建测试用户
curl -X POST -H "Content-Type: application/json" \
-d '{"username":"devuser","email":"dev@example.com"}' \
http://localhost:8080/api/users

# 查询用户信息
curl -X GET http://localhost:8080/api/users/1

八、生产环境建议

8.1 安全配置

yaml 复制代码
spring:
  datasource:
    password: ${DB_PASSWORD} # 从环境变量读取
    hikari:
      connection-init-sql: SELECT 1 FROM DUAL # 连接验证

8.2 监控配置

java 复制代码
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
    return registry -> registry.config().commonTags(
            "application", "user-service",
            "datasource", "mysql"
    );
}

附完整项目结构:

复制代码
src/main/java
├── com.example
│   ├── config       # 配置类
│   ├── controller   # Web层
│   ├── service      # 业务层
│   ├── mapper       # 数据访问层
│   └── domain       # 领域模型
resources/
├── application.yml  # 主配置文件
└── mapper/          # XML映射文件
生产级应用的优化策略

未来可探索方向:
- 结合Redis实现缓存层
- 集成MyBatis-Plus增强功能
- 实现多租户数据隔离
- 探索分布式事务解决方案

附完整项目结构:

src/main/java

├── com.example

│ ├── config # 配置类

│ ├── controller # Web层

│ ├── service # 业务层

│ ├── mapper # 数据访问层

│ └── domain # 领域模型

resources/

├── application.yml # 主配置文件

└── mapper/ # XML映射文件

复制代码
相关推荐
用户8307196840822 小时前
MySQL 查询优化 30 条封神技巧:用好索引,少耗资源,查询快到飞起
mysql
Nyarlathotep01134 小时前
事务隔离级别
sql·mysql
Nyarlathotep01136 小时前
SQL的事务控制
sql·mysql
用户908324602737 小时前
Spring AI 1.1.2 + Neo4j:用知识图谱增强 RAG 检索(上篇:图谱构建)
java·spring boot
用户86178277365187 小时前
MySQL 8.0从库宕机排查实录:中继日志膨胀引发的连锁故障复盘
mysql
用户8307196840821 天前
Spring Boot 集成 RabbitMQ :8 个最佳实践,杜绝消息丢失与队列阻塞
spring boot·后端·rabbitmq
Java水解1 天前
Spring Boot 视图层与模板引擎
spring boot·后端
Java水解1 天前
一文搞懂 Spring Boot 默认数据库连接池 HikariCP
spring boot·后端
随风飘的云1 天前
mysql的innodb引擎对可重复读做了那些优化,可以避免幻读
mysql
洋洋技术笔记1 天前
Spring Boot Web MVC配置详解
spring boot·后端