MyBatis之核心组件与配置详解
MyBatis之核心组件与配置详解
- 一、MyBatis的核心组件
- 1.1 核心组件及其关系
- 1.2 核心组件详解
- 1.2.1 SqlSessionFactoryBuilder
- 1.2.2 SqlSessionFactory
- 1.2.3 SqlSession
- 1.2.4 Mapper接口与映射器
- 二、MyBatis核心配置文件(mybatis-config.xml)
- 2.1 核心配置详解
- 2.1.1 properties:外部属性
- 2.1.2 settings:全局设置
- 2.1.3 typeAliases:类型别名
- 2.1.4 environments:环境配置
- 2.1.5 mappers:注册Mapper
- 三、Mapper映射器(SQL编写)
- 3.1 XML映射器(推荐)
- 3.2 注解映射器(简单SQL)
- 四、MyBatis的SQL执行流程
- 五、常见问题与避坑指南
- 5.1 Mapper注册失败(BindingException)
- 5.2 下划线列名与驼峰属性映射问题
- 5.3 SQL参数传递问题
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 mapperPUBLIC "-//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 configurationPUBLIC "-//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 mapperPUBLIC "-//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") // 返回自增IDint 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的完整流程如下:
-
初始化阶段:
SqlSessionFactoryBuilder
读取mybatis-config.xml
,构建SqlSessionFactory
;SqlSessionFactory
加载Mapper映射器,解析SQL语句和结果映射规则。
-
执行阶段:
- 从
SqlSessionFactory
获取SqlSession
(开启会话); - 通过
SqlSession
获取Mapper
接口(动态代理实现); - 调用
Mapper
方法执行SQL(MyBatis自动处理参数、执行SQL、映射结果)。
- 从
-
收尾阶段:
- 提交事务(
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代码分离和灵活的映射规则,核心组件和配置是实现这一优势的基础:
- 核心组件:
SqlSessionFactory
管理连接,SqlSession
处理会话,Mapper
执行SQL,分工明确,简化数据库操作;- 核心配置:通过
mybatis-config.xml
统一配置数据库、日志、别名等,降低维护成本;- Mapper映射器:XML或注解定义SQL,支持复杂查询和结果映射,兼顾灵活性和可读性。
若这篇内容帮到你,动动手指支持下!关注不迷路,干货持续输出!
ヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノ