MyBatis四大组件和SqlSession四大对象详解
MyBatis四大组件和SqlSession四大对象详解
MyBatis四大核心组件
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder的核心源码分析:
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(Reader reader) {
try {
// 解析配置文件,创建Configuration对象
XMLConfigBuilder parser = new XMLConfigBuilder(reader);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
}
}
// Configuration对象创建SqlSessionFactory
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
}
源码解析要点:
配置文件解析过程:
public Configuration parse() { if (parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } parsed = true; parseConfiguration(parser.evalNode("/configuration")); return configuration; }
Configuration类的重要属性:
public class Configuration { protected Environment environment; protected boolean lazyLoadingEnabled = false; protected boolean aggressiveLazyLoading = false; protected boolean multipleResultSetsEnabled = true; // ... 更多配置属性 }
SqlSessionFactory
DefaultSqlSessionFactory的核心实现:
public class DefaultSqlSessionFactory implements SqlSessionFactory {
private final Configuration configuration;
// 创建SqlSession的核心方法
@Override
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
// 从数据源创建SqlSession
private SqlSession openSessionFromDataSource(ExecutorType execType,
TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
// 获取环境配置
final Environment environment = configuration.getEnvironment();
// 创建事务工厂
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
// 创建事务
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
// 创建Executor
final Executor executor = configuration.newExecutor(tx, execType);
// 创建DefaultSqlSession
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
closeTransaction(tx);
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
}
}
}
SqlSession
DefaultSqlSession的关键源码:
public class DefaultSqlSession implements SqlSession {
private final Configuration configuration;
private final Executor executor;
private final boolean autoCommit;
// 查询操作的实现
@Override
public <E> List<E> selectList(String statement, Object parameter) {
try {
// 获取MappedStatement
MappedStatement ms = configuration.getMappedStatement(statement);
// 通过执行器查询
return executor.query(ms, wrapCollection(parameter),
RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);
}
}
// 获取Mapper接口的实现
@Override
public <T> T getMapper(Class<T> type) {
return configuration.getMapper(type, this);
}
}
Mapper接口
MapperProxy的动态代理实现:
public class MapperProxy<T> implements InvocationHandler, Serializable {
private final SqlSession sqlSession;
private final Class<T> mapperInterface;
private final Map<Method, MapperMethodInvoker> methodCache;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// Object方法直接调用
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
}
// 其他方法走代理
return cachedInvoker(method).invoke(proxy, method, args, sqlSession);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}
}
SqlSession的四大对象
Executor
Executor的核心实现和类型:
public interface Executor {
ResultHandler NO_RESULT_HANDLER = null;
// 更新方法
int update(MappedStatement ms, Object parameter) throws SQLException;
// 查询方法
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds,
ResultHandler resultHandler) throws SQLException;
// 事务方法
Transaction getTransaction();
void commit(boolean required) throws SQLException;
void rollback(boolean required) throws SQLException;
}
// SimpleExecutor的实现
public class SimpleExecutor extends BaseExecutor {
@Override
protected int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
Statement stmt = null;
try {
Configuration configuration = ms.getConfiguration();
// 创建StatementHandler
StatementHandler handler = configuration.newStatementHandler(this, ms, parameter,
RowBounds.DEFAULT, null, null);
// 准备语句
stmt = prepareStatement(handler, ms.getStatementLog());
// 执行更新
return handler.update(stmt);
} finally {
closeStatement(stmt);
}
}
}
ParameterHandler
参数处理器的实现:
public class DefaultParameterHandler implements ParameterHandler {
@Override
public void setParameters(PreparedStatement ps) {
ErrorContext.instance().activity("setting parameters")
.object(mappedStatement.getParameterMap().getId());
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
if (parameterMappings != null) {
for (int i = 0; i < parameterMappings.size(); i++) {
ParameterMapping parameterMapping = parameterMappings.get(i);
if (parameterMapping.getMode() != ParameterMode.OUT) {
Object value;
String propertyName = parameterMapping.getProperty();
// 获取参数值并设置
value = metaObject.getValue(propertyName);
TypeHandler typeHandler = parameterMapping.getTypeHandler();
typeHandler.setParameter(ps, i + 1, value, parameterMapping.getJdbcType());
}
}
}
}
}
ResultSetHandler
结果集处理器的核心实现:
public class DefaultResultSetHandler implements ResultSetHandler {
@Override
public List<Object> handleResultSets(Statement stmt) throws SQLException {
final List<Object> multipleResults = new ArrayList<>();
int resultSetCount = 0;
// 获取第一个结果集
ResultSetWrapper rsw = getFirstResultSet(stmt);
// 获取结果映射
List<ResultMap> resultMaps = mappedStatement.getResultMaps();
while (rsw != null && resultMaps.size() > resultSetCount) {
ResultMap resultMap = resultMaps.get(resultSetCount);
// 处理结果集
handleResultSet(rsw, resultMap, multipleResults, null);
// 获取下一个结果集
rsw = getNextResultSet(stmt);
resultSetCount++;
}
return multipleResults;
}
}
StatementHandler
StatementHandler的实现层次:
public interface StatementHandler {
Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException;
void parameterize(Statement statement) throws SQLException;
int update(Statement statement) throws SQLException;
<E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException;
}
// PreparedStatementHandler的实现
public class PreparedStatementHandler extends BaseStatementHandler {
@Override
public int update(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
return ps.getUpdateCount();
}
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
return resultSetHandler.handleResultSets(ps);
}
}
工作流程源码分析
完整的SQL执行流程:
// 1. 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2. 创建SqlSession
try (SqlSession session = sqlSessionFactory.openSession()) {
// 3. 获取Mapper接口
UserMapper mapper = session.getMapper(UserMapper.class);
// 4. 执行SQL(内部流程)
User user = mapper.getUserById(1);
// 4.1 MapperProxy拦截调用
// 4.2 SqlSession调用Executor
// 4.3 Executor创建StatementHandler
// 4.4 StatementHandler使用ParameterHandler设置参数
// 4.5 StatementHandler执行SQL
// 4.6 ResultSetHandler处理结果集
// 5. 提交事务
session.commit();
}
JDK 17特性应用:
// 使用Record定义简单的参数对象
public record UserQuery(String name, Integer age) {}
// 使用Switch表达式
public Object convertValue(Object value) {
return switch (value) {
case String s -> "String: " + s;
case Integer i -> "Integer: " + i;
case UserQuery q -> "Query: " + q.name() + ", " + q.age();
default -> throw new IllegalArgumentException("Unsupported type");
};
}
// 使用Text Blocks定义SQL
String sql = """
SELECT id, name, age
FROM users
WHERE name = #{name}
AND age > #{age}
""";
核心接口和实现类关系图
classDiagram
SqlSessionFactory <|-- DefaultSqlSessionFactory
SqlSession <|-- DefaultSqlSession
Executor <|-- BaseExecutor
BaseExecutor <|-- SimpleExecutor
BaseExecutor <|-- ReuseExecutor
BaseExecutor <|-- BatchExecutor
StatementHandler <|-- BaseStatementHandler
BaseStatementHandler <|-- SimpleStatementHandler
BaseStatementHandler <|-- PreparedStatementHandler
BaseStatementHandler <|-- CallableStatementHandler
class SqlSessionFactory {
+openSession() SqlSession
}
class Executor {
+update(MappedStatement, Object)
+query(MappedStatement, Object, RowBounds, ResultHandler)
}
class StatementHandler {
+prepare(Connection, Integer)
+parameterize(Statement)
+update(Statement)
+query(Statement, ResultHandler)
}
最佳实践和性能优化建议
- 合理使用缓存:
@CacheNamespace(
implementation = PerpetualCache.class,
eviction = LruCache.class,
size = 1024,
flushInterval = 120000
)
public interface UserMapper {
@Options(useCache = true)
User getUserById(Integer id);
}
- 批量操作优化:
try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
UserMapper mapper = session.getMapper(UserMapper.class);
for (User user : userList) {
mapper.insertUser(user);
}
session.commit();
}
- 动态SQL优化:
<select id="findUsers" resultType="User">
SELECT * FROM users
<where>
<if test="name != null">AND name LIKE #{name}</if>
<if test="age != null">AND age > #{age}</if>
</where>
</select>
总结
源码层面的组件协作:
- SqlSessionFactoryBuilder → Configuration → SqlSessionFactory
- SqlSessionFactory → Executor → StatementHandler
- StatementHandler → ParameterHandler/ResultSetHandler
性能优化关键点:
- 合理使用缓存机制
- 批量操作时使用BatchExecutor
- 动态SQL的优化
- 延迟加载的配置
JDK 17新特性的应用:
- Record类型简化参数对象
- Switch表达式增强
- Text Blocks优化SQL编写
这些组件通过精心的设计和实现,共同构成了MyBatis的核心功能,理解它们的源码实现对于进行框架定制和性能优化具有重要意义。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 孤寂灬无痕
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果