Spring Boot数据访问之Mybatis的示例分析

发布时间:2021-12-30 09:51:13 作者:小新
来源:亿速云 阅读:167
# Spring Boot数据访问之Mybatis的示例分析

## 一、引言

### 1.1 Spring Boot与MyBatis概述
Spring Boot作为当前最流行的Java应用开发框架,通过自动配置和起步依赖极大简化了Spring应用的初始搭建和开发过程。其核心优势体现在:
- 内嵌式服务器支持(Tomcat/Jetty)
- 自动化的Spring配置
- 简化的依赖管理
- 生产级监控端点

MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。相较于Hibernate等全自动ORM框架,MyBatis的主要特点包括:
- SQL与代码分离(XML/注解两种方式)
- 低学习曲线
- 灵活的动态SQL支持
- 与Spring生态完美集成

### 1.2 技术选型背景
在实际企业级应用中,选择Spring Boot+MyBatis组合主要基于以下考量:
1. **性能需求**:对复杂查询需要精细控制SQL
2. **遗留系统**:已有大量MyBatis映射文件需要复用
3. **团队技能**:开发人员更熟悉SQL而非JPA
4. **灵活性**:需要混合使用ORM和原生SQL

## 二、环境搭建与基础配置

### 2.1 项目初始化
通过Spring Initializr创建项目时需选择:
- Spring Boot 2.7+(建议最新稳定版)
- 依赖项:
  - Spring Web
  - MyBatis Framework
  - MySQL Driver(或其他数据库驱动)
  - Lombok(简化实体类)

```xml
<!-- pom.xml关键依赖 -->
<dependencies>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.2</version>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

2.2 数据库配置

application.yml典型配置示例:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/example_db?useSSL=false&serverTimezone=UTC
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.example.entity
  configuration:
    map-underscore-to-camel-case: true

2.3 实体类与Mapper接口

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

@Mapper
public interface UserMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    User findById(Long id);
    
    @Insert("INSERT INTO users(username,email) VALUES(#{username},#{email})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(User user);
}

三、核心功能实现

3.1 XML映射文件开发

resources/mapper/UserMapper.xml示例:

<mapper namespace="com.example.mapper.UserMapper">
    <resultMap id="BaseResultMap" type="User">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="email" property="email"/>
        <result column="create_time" property="createTime"/>
    </resultMap>

    <select id="selectUsersByCondition" resultMap="BaseResultMap">
        SELECT * FROM users
        <where>
            <if test="username != null">
                AND username LIKE CONCAT('%',#{username},'%')
            </if>
            <if test="email != null">
                AND email = #{email}
            </if>
        </where>
        ORDER BY create_time DESC
    </select>
</mapper>

3.2 动态SQL实践

MyBatis提供多种动态SQL元素:

<!-- 复杂条件查询示例 -->
<select id="dynamicQuery" resultType="User">
    SELECT * FROM users
    <trim prefix="WHERE" prefixOverrides="AND|OR">
        <choose>
            <when test="ids != null and ids.size() > 0">
                id IN
                <foreach collection="ids" item="id" open="(" separator="," close=")">
                    #{id}
                </foreach>
            </when>
            <otherwise>
                status = 1
            </otherwise>
        </choose>
    </trim>
</select>

3.3 关联查询处理

一对一关联

<resultMap id="OrderWithUser" type="Order">
    <id property="id" column="order_id"/>
    <association property="user" javaType="User">
        <id property="id" column="user_id"/>
        <result property="username" column="username"/>
    </association>
</resultMap>

一对多关联

<resultMap id="UserWithOrders" type="User">
    <collection property="orders" ofType="Order">
        <id property="id" column="order_id"/>
        <result property="orderNo" column="order_no"/>
    </collection>
</resultMap>

四、高级特性应用

4.1 插件开发(Interceptor)

实现分页插件示例:

@Intercepts(@Signature(type= StatementHandler.class, 
        method="prepare", 
        args={Connection.class, Integer.class}))
public class PaginationInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler handler = (StatementHandler) invocation.getTarget();
        MetaObject metaObject = SystemMetaObject.forObject(handler);
        
        // 判断是否需要分页
        if (metaObject.hasGetter("delegate.boundSql.parameterObject.page")) {
            // 修改SQL加入LIMIT语句
            String originalSql = (String) metaObject.getValue("delegate.boundSql.sql");
            metaObject.setValue("delegate.boundSql.sql", originalSql + " LIMIT ?,?");
        }
        return invocation.proceed();
    }
}

4.2 二级缓存配置

Ehcache集成示例:

<!-- mapper.xml中配置 -->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

<!-- ehcache.xml配置 -->
<ehcache>
    <diskStore path="java.io.tmpdir"/>
    <defaultCache
        maxElementsInMemory="1000"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"/>
</ehcache>

4.3 批量操作优化

public interface BatchMapper {
    @Insert("<script>" +
            "INSERT INTO users(username, email) VALUES " +
            "<foreach collection='list' item='item' separator=','>" +
            "(#{item.username}, #{item.email})" +
            "</foreach>" +
            "</script>")
    void batchInsert(List<User> users);
}

五、性能优化实践

5.1 SQL执行监控

使用P6Spy进行SQL日志格式化:

# application.properties
spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
spring.datasource.url=jdbc:p6spy:mysql://localhost:3306/db

5.2 连接池配置

HikariCP最佳实践配置:

spring:
  datasource:
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000
      pool-name: MyHikariPool

5.3 延迟加载策略

mybatis:
  configuration:
    lazy-loading-enabled: true
    aggressive-lazy-loading: false
    proxy-target-class: true

六、常见问题解决方案

6.1 类型处理器问题

自定义枚举处理器示例:

@MappedTypes(StatusEnum.class)
public class StatusEnumHandler implements TypeHandler<StatusEnum> {
    @Override
    public void setParameter(PreparedStatement ps, int i, 
            StatusEnum parameter, JdbcType jdbcType) {
        ps.setInt(i, parameter.getCode());
    }
    // 其他方法实现...
}

6.2 事务管理

声明式事务配置:

@Configuration
@EnableTransactionManagement
public class TransactionConfig {
    
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

@Service
@Transactional
public class UserService {
    // 业务方法...
}

6.3 多数据源配置

@Configuration
@MapperScan(basePackages = "com.example.mapper.primary", 
           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 bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(
            new PathMatchingResourcePatternResolver()
                .getResources("classpath:mapper/primary/*.xml"));
        return bean.getObject();
    }
}

七、测试与验证

7.1 单元测试示例

@SpringBootTest
@Transactional
@Rollback
class UserMapperTest {
    
    @Autowired
    private UserMapper userMapper;
    
    @Test
    void testInsert() {
        User user = new User(null, "test", "test@example.com", null);
        int affected = userMapper.insert(user);
        assertEquals(1, affected);
        assertNotNull(user.getId());
    }
}

7.2 性能测试建议

使用JMeter进行基准测试时关注: - 单查询响应时间 - 并发查询吞吐量 - 批量插入效率 - 长时间运行的稳定性

八、总结与最佳实践

8.1 技术总结

经过本文的详细探讨,我们可以得出以下关键结论: 1. 配置简化:Spring Boot的自动配置极大简化了MyBatis集成 2. 灵活选择:注解与XML映射可根据场景灵活选用 3. 性能平衡:合理的缓存策略能显著提升性能

8.2 架构建议

对于大型项目推荐采用: - 分层架构:Controller -> Service -> Mapper - 领域划分:按业务模块组织Mapper接口 - 统一异常处理:自定义MyBatis异常转换器

8.3 未来演进

技术组合的演进方向: - 向MyBatis-Plus过渡(增强功能) - 结合Kotlin协程实现异步IO - 探索GraalVM原生镜像支持


附录:参考资源 1. MyBatis官方文档 2. Spring Boot Reference Guide 3. 《MyBatis从入门到精通》- 刘增辉著 “`

注:本文实际约8500字(含代码),完整8700字版本可扩展以下内容: 1. 增加各章节的详细原理分析 2. 补充更多实际生产案例 3. 添加性能对比数据表格 4. 扩展异常处理场景示例 5. 增加安全相关配置说明

推荐阅读:
  1. Spring Boot 整合 MyBatis
  2. spring boot DAO之Mybatis的示例分析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springboot mybatis

上一篇:activemq死信队列的消息处理方法是什么

下一篇:怎么在Yarn集群中分配Container

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》