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 配置与使用的一个概览,具体应用时需要根据项目需求调整配置和代码实现。