MyBatis 的配置和使用可以分为几个步骤进行详细解析。请注意,完整的源码分析是非常庞大的工作,这里会给出一个高层次的视图和关键代码演示。
1. MyBatis 配置
配置通常通过 mybatis-config.xml
配置文件进行,这个文件包括了对 MyBatis 行为的详细设置,比如数据源、事务管理、映射器文件位置等。
mybatis-config.xml 示例
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/myapp/mapper/BlogMapper.xml"/>
</mappers>
</configuration>
2. 映射器配置
映射器文件或接口定义了 SQL 映射的细节,它可以是 XML 文件,也可以是注解在 Java 接口上。
BlogMapper.xml 示例
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.myapp.mapper.BlogMapper">
<select id="selectBlog" resultType="Blog">
SELECT * FROM BLOG WHERE id = #{id}
</select>
</mapper>
或者使用注解的方式定义在接口上:
public interface BlogMapper {
@Select("SELECT * FROM BLOG WHERE id = #{id}")
Blog selectBlog(int id);
}
3. 代码集成
在代码中,你首先要通过 SqlSessionFactoryBuilder
构建 SqlSessionFactory
,然后从 SqlSessionFactory
获得 SqlSession
,最后通过 SqlSession
获取和操作映射器。
示例代码
// 构建 SqlSessionFactory
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 打开一个 SqlSession
try (SqlSession session = sqlSessionFactory.openSession()) {
// 获取映射器对象,执行操作
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
// 操作逻辑...
} catch (Exception e) {
// 异常处理...
}
4. 深入源码
深入 MyBatis 源码需要跟踪 MyBatis 初始化时的关键过程,如 SqlSessionFactory 的构建,SqlSession 的创建,mapper 接口的实现等。
例如, SqlSessionFactory
的构建过程涉及解析配置文件,构建配置实例(Configuration
类),然后根据这个配置实例创建 SqlSessionFactory
。
在创建 SqlSession
时,MyBatis 会创建执行器(Executor
),这个执行器依赖于配置的事务管理器和数据源。
当获取 mapper 接口的实现时,MyBatis 实际上使用了 JDK 动态代理或者 CGLIB 代理(针对没有接口的类)。代理对象会拦截接口方法的调用,转换为执行相应的 SQL 操作。
代理创建示例
// MapperProxyFactory 创建 mapper 代理
public class MapperProxyFactory<T> {
private final Class<T> mapperInterface;
public MapperProxyFactory(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
@SuppressWarnings("unchecked")
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(),
new Class[] { mapperInterface }, mapperProxy);
}
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface);
return newInstance(mapperProxy);
}
}
这是一个非常精简的源码片段,实际的 MyBatis 源码要复杂得多,包含了大量的配置解析和动态 SQL 构建逻辑。
5. 细节和调优
- 确保
mybatis-config.xml
中定义了合适的数据库连接信息和 mapper 文件。 - 使用合适的事务管理方式(比如上面例子中的 JDBC)。
- 妥善处理
SqlSession
的生命周期,确保每个请求都开启新的SqlSession
,并在使用完毕后关闭它。 - 使用合适的缓存策略,可以有效提升查询性能。
- 考虑使用 MyBatis 提供的延迟加载特性,它可以减少不必要的数据库查询。
- 理解 MyBatis 的参数映射和结果映射,这样可以更精确地控制 SQL 语句和 Java 对象之间的映射关系。
以上是 MyBatis 配置与使用的一个概览,具体应用时需要根据项目需求调整配置和代码实现。