MyBatis之核心组件与配置详解

#新星杯·14天创作挑战营·第13期#

MyBatis是一款优秀的持久层框架,它消除了JDBC繁琐的代码编写,通过XML或注解实现SQL与Java代码的分离,同时保持了SQL的灵活性,掌握MyBatis的核心组件和配置方式,是高效使用MyBatis进行数据库操作的基础。本文我将系统解析MyBatis的核心组件(如SqlSession、Mapper接口等),详细讲解核心配置文件和映射文件的配置规则,并结合实例演示其应用,带你快速上手MyBatis。

一、MyBatis的核心组件

MyBatis的核心组件围绕“SQL执行流程”设计,各组件分工明确,共同完成从数据库连接到结果映射的全流程。

1.1 核心组件及其关系

MyBatis的核心组件包括:

  • SqlSessionFactoryBuilder:构建SqlSessionFactory的工具类
  • SqlSessionFactory:创建SqlSession的工厂接口
  • SqlSession:数据库操作的会话接口(类似JDBC的Connection
  • Mapper接口:定义数据库操作方法的接口(无需实现类)
  • Mapper映射器:存储SQL语句和结果映射规则(XML或注解)
  • Executor:MyBatis的执行器(负责SQL执行和缓存管理)
  • StatementHandler:处理SQL语句的预编译和参数设置

各组件的执行流程:

SqlSessionFactoryBuilder → SqlSessionFactory → SqlSession → Mapper接口 → 数据库
(读取配置) (获取Mapper) (执行SQL)

1.2 核心组件详解

1.2.1 SqlSessionFactoryBuilder

SqlSessionFactoryBuilder的作用是读取MyBatis配置文件,构建SqlSessionFactory,创建完成后即可丢弃(生命周期短暂)。

// 读取XML配置文件构建SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
1.2.2 SqlSessionFactory

SqlSessionFactory创建SqlSession的工厂,一旦创建就应在应用生命周期内存在(单例模式),避免频繁创建(耗费资源)。

// 从SqlSessionFactory获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
1.2.3 SqlSession

SqlSession与数据库交互的会话对象,类似JDBC的Connection,负责获取Mapper接口、提交事务、关闭连接等。其生命周期为“一次请求”或“一次事务”,使用后需及时关闭。

try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
    // 获取Mapper接口
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    // 执行查询
    User user = userMapper.selectById(1);
} // 自动关闭SqlSession(try-with-resources语法)
1.2.4 Mapper接口与映射器

Mapper接口是定义数据库操作方法的接口(无实现类),Mapper映射器(XML或注解)定义对应的SQL语句和结果映射规则。MyBatis会动态生成Mapper接口的实现类,将SQL执行结果映射为Java对象。

// Mapper接口(定义方法)
public interface UserMapper {
    User selectById(Integer id); // 方法名对应XML中的SQL ID
}

// Mapper映射器(XML配置SQL,与接口同名同路径)
<?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">
    <!-- SQL ID与接口方法名一致 -->
    <select id="selectById" resultType="com.example.pojo.User">
        SELECT id, username, age FROM user WHERE id = #{id}
    </select>
</mapper>

二、MyBatis核心配置文件(mybatis-config.xml)

MyBatis核心配置文件(通常命名为mybatis-config.xml)是全局配置,用于配置数据库连接、Mapper映射器位置、插件、别名等。配置标签有严格的顺序(按以下顺序排列):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 1. 属性(外部配置,如数据库连接信息) -->
    <properties resource="db.properties"/>

    <!-- 2. 设置(全局配置参数) -->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 下划线转驼峰 -->
        <setting name="logImpl" value="STDOUT_LOGGING"/> <!-- 日志输出 -->
    </settings>

    <!-- 3. 类型别名(简化类名) -->
    <typeAliases>
        <package name="com.example.pojo"/> <!-- 批量别名:类名首字母小写 -->
    </typeAliases>

    <!-- 4. 环境配置(数据库连接信息) -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/> <!-- 事务管理 -->
            <dataSource type="POOLED"> <!-- 连接池 -->
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 5. Mapper映射器(注册Mapper) -->
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml"/> <!-- XML路径 -->
        <mapper class="com.example.mapper.UserMapper"/> <!-- 接口类(注解方式) -->
        <package name="com.example.mapper"/> <!-- 批量注册包下所有Mapper -->
    </mappers>
</configuration>

2.1 核心配置详解

2.1.1 properties:外部属性

通过properties标签引入外部配置文件(如数据库连接信息),避免硬编码,支持动态替换。

<!-- db.properties -->
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456

在核心配置中引用:

<properties resource="db.properties"/>
<!-- 使用${key}引用 -->
<property name="driver" value="${jdbc.driver}"/>
2.1.2 settings:全局设置

settings是MyBatis的核心配置,控制MyBatis的运行行为,常用设置:

设置名作用默认值
mapUnderscoreToCamelCase数据库下划线列名自动转为Java驼峰属性false
logImpl指定日志实现(如STDOUT_LOGGING、LOG4J)未设置
cacheEnabled全局开启二级缓存true
lazyLoadingEnabled开启延迟加载(按需加载关联对象)false
2.1.3 typeAliases:类型别名

为Java类定义别名,简化Mapper映射器中的类名书写(如resultType="User"替代resultType="com.example.pojo.User")。

<!-- 方式1:单个类别名 -->
<typeAlias type="com.example.pojo.User" alias="User"/>

<!-- 方式2:批量别名(推荐) -->
<typeAliases>
    <package name="com.example.pojo"/> <!-- 别名默认为类名首字母小写(User→user) -->
</typeAliases>
2.1.4 environments:环境配置

配置数据库连接环境(支持多环境,如开发、测试、生产),default指定默认环境。

  • transactionManager:事务管理器,JDBC(依赖数据库事务)或MANAGED(交给容器管理);
  • dataSource:数据源,POOLED(连接池,推荐)、UNPOOLED(无连接池)、JNDI(容器数据源)。
2.1.5 mappers:注册Mapper

mappers用于注册Mapper映射器,MyBatis才能找到SQL语句,常用注册方式:

方式语法适用场景
resource<mapper resource="路径"/>XML映射器(路径需正确)
class<mapper class="接口类"/>注解映射器或XML与接口同路径
package<package name="包名"/>批量注册包下所有Mapper(推荐)

三、Mapper映射器(SQL编写)

Mapper映射器是MyBatis的核心,用于定义SQL语句和结果映射规则,有两种实现方式:XML映射器和注解映射器。

3.1 XML映射器(推荐)

XML映射器将SQL与Java代码分离,适合复杂SQL,结构清晰。

<?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">
<!-- namespace必须与Mapper接口全类名一致 -->
<mapper namespace="com.example.mapper.UserMapper">

    <!-- 1. 查询:根据ID查询用户 -->
    <select id="selectById" parameterType="Integer" resultType="User">
        SELECT id, username, age FROM user WHERE id = #{id}
    </select>

    <!-- 2. 新增:插入用户(返回自增ID) -->
    <insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO user (username, age) VALUES (#{username}, #{age})
    </insert>

    <!-- 3. 更新:根据ID更新 -->
    <update id="update" parameterType="User">
        UPDATE user SET username = #{username}, age = #{age} WHERE id = #{id}
    </update>

    <!-- 4. 删除:根据ID删除 -->
    <delete id="deleteById" parameterType="Integer">
        DELETE FROM user WHERE id = #{id}
    </delete>

    <!-- 5. 复杂查询:结果映射(数据库列与Java属性映射) -->
    <resultMap id="UserMap" type="User">
        <id column="id" property="id"/> <!-- 主键映射 -->
        <result column="user_name" property="username"/> <!-- 列名与属性名不同 -->
        <result column="user_age" property="age"/>
    </resultMap>
    <select id="selectAll" resultMap="UserMap">
        SELECT id, user_name, user_age FROM user
    </select>
</mapper>

3.2 注解映射器(简单SQL)

对于简单SQL,可直接在Mapper接口上用注解定义,无需XML:

public interface UserMapper {
    // 查询
    @Select("SELECT id, username, age FROM user WHERE id = #{id}")
    User selectById(Integer id);

    // 新增
    @Insert("INSERT INTO user (username, age) VALUES (#{username}, #{age})")
    @Options(useGeneratedKeys = true, keyProperty = "id") // 返回自增ID
    int insert(User user);

    // 更新
    @Update("UPDATE user SET username = #{username}, age = #{age} WHERE id = #{id}")
    int update(User user);

    // 删除
    @Delete("DELETE FROM user WHERE id = #{id}")
    int deleteById(Integer id);
}

适用场景:简单SQL(单表CRUD);复杂SQL(多表关联、动态SQL)仍推荐XML方式。

四、MyBatis的SQL执行流程

结合核心组件和配置,MyBatis执行SQL的完整流程如下:

  1. 初始化阶段

    • SqlSessionFactoryBuilder读取mybatis-config.xml,构建SqlSessionFactory
    • SqlSessionFactory加载Mapper映射器,解析SQL语句和结果映射规则。
  2. 执行阶段

    • SqlSessionFactory获取SqlSession(开启会话);
    • 通过SqlSession获取Mapper接口(动态代理实现);
    • 调用Mapper方法执行SQL(MyBatis自动处理参数、执行SQL、映射结果)。
  3. 收尾阶段

    • 提交事务(sqlSession.commit())或回滚(sqlSession.rollback());
    • 关闭SqlSession(释放资源)。

五、常见问题与避坑指南

5.1 Mapper注册失败(BindingException)

错误信息org.apache.ibatis.binding.BindingException: Type interface com.example.mapper.UserMapper is not known to the MapperRegistry

原因

  • Mapper未在mybatis-config.xml<mappers>中注册;
  • XML映射器的namespace与Mapper接口全类名不一致;
  • XML文件名与接口名不一致(如UserMapper.xml对应UserMapper.java)。

解决方案

  • 确保Mapper已注册(<mapper resource="..."<package name="...">);
  • 检查namespace是否正确(namespace="com.example.mapper.UserMapper");
  • 保持XML与接口文件名一致,并放在同一包下(编译后路径相同)。

5.2 下划线列名与驼峰属性映射问题

问题:数据库列名user_name无法映射到Java属性username(结果为null)。

解决方案

  • 开启全局下划线转驼峰配置:
<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
  • 或在resultMap中手动映射:
<resultMap id="UserMap" type="User">
    <result column="user_name" property="username"/>
</resultMap>

5.3 SQL参数传递问题

问题:多参数传递时,#{param}无法获取参数(报Parameter 'xxx' not found)。

解决方案

  • 方式1:用@Param注解指定参数名:
User selectByUsernameAndAge(@Param("username") String username, @Param("age") Integer age);
<select id="selectByUsernameAndAge" resultType="User">
    SELECT * FROM user WHERE username = #{username} AND age = #{age}
</select>
  • 方式2:使用对象传递参数(推荐):
User selectByUser(User user); // 参数为对象
<select id="selectByUser" resultType="User">
    SELECT * FROM user WHERE username = #{username} AND age = #{age}
</select>

总结
MyBatis的核心优势在于SQL与Java代码分离灵活的映射规则,核心组件和配置是实现这一优势的基础:

  1. 核心组件SqlSessionFactory管理连接,SqlSession处理会话,Mapper执行SQL,分工明确,简化数据库操作;
  2. 核心配置:通过mybatis-config.xml统一配置数据库、日志、别名等,降低维护成本;
  3. Mapper映射器:XML或注解定义SQL,支持复杂查询和结果映射,兼顾灵活性和可读性。

若这篇内容帮到你,动动手指支持下!关注不迷路,干货持续输出!
ヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值