网站建设方案汇报,哪些网站推广不收费,网站每天做多少外链合适,我做网站了圆通Mybatis 是一个流行的 Java 持久层框架#xff0c;它提供了一种半自动的 SQL 映射方式#xff0c;允许开发者在 Java 代码中以一种更加直观和灵活的方式来操作数据库。当你使用 Mybatis 调用 DAO 接口时#xff0c;背后的工作流程大致如下#xff1a; 接口定义#xff1a;…Mybatis 是一个流行的 Java 持久层框架它提供了一种半自动的 SQL 映射方式允许开发者在 Java 代码中以一种更加直观和灵活的方式来操作数据库。当你使用 Mybatis 调用 DAO 接口时背后的工作流程大致如下 接口定义首先你需要定义一个 DAO 接口这个接口中会包含一些方法这些方法对应于你想要执行的数据库操作。 Mapper XML对于 DAO 接口中的每一个方法你需要在 Mybatis 的映射文件通常是一个 XML 文件中定义一个 mapper 标签里面包含一个 select、insert、update 或 delete 标签对应于你想要执行的 SQL 语句。 配置文件在 Mybatis 的配置文件通常是 mybatis-config.xml中你需要指定你的 Mapper XML 文件的位置这样 Mybatis 才能找到并加载它们。 SqlSessionFactoryMybatis 使用 SqlSessionFactory 来创建 SqlSession 对象。SqlSessionFactory 是通过配置文件和映射文件构建的它包含了所有必要的信息来执行 SQL 语句。 SqlSessionSqlSession 是 Mybatis 中执行 SQL 语句的主要对象。它提供了执行 SQL 语句的方法例如 selectOne、selectList、insert、update 和 delete 等。 调用 DAO 接口当你调用 DAO 接口中的方法时实际上是 Mybatis 的动态代理机制在起作用。Mybatis 会为 DAO 接口创建一个代理对象当调用接口中的方法时代理对象会拦截这些调用然后根据方法名找到对应的 SQL 映射语句并执行。 执行 SQLMybatis 通过代理对象使用 SqlSession 来执行对应的 SQL 语句。执行完成后SqlSession 会返回结果给调用者。 关闭 SqlSession执行完毕后应该关闭 SqlSession 以释放数据库连接资源。
这个过程涉及到了 Mybatis 的核心组件和工作流程确保了 SQL 语句的执行和结果的返回。使用 Mybatis 的好处之一就是它允许开发者以一种声明式的方式来编写 SQL同时还能保持代码的清晰和易于维护。
Mybatis 的内部实现细节非常丰富下面我将通过一些关键类的源码片段来具体展示 Mybatis 的工作原理。
配置解析XMLConfigBuilder.java
Mybatis 使用 XMLConfigBuilder 来解析 mybatis-config.xml 文件
public Configuration parse() {parseConfiguration(parser.eval(Configuration.class));return configuration;
}这里parseConfiguration 方法会填充 Configuration 对象的属性比如数据库连接信息、类型别名、类型处理器等。 2. 创建 SqlSessionFactorySqlSessionFactoryBuilder.java
使用 XMLConfigBuilder 解析配置后SqlSessionFactoryBuilder 会创建 SqlSessionFactory
public SqlSessionFactory build(InputStream inputStream) {try {XMLConfigBuilder xmlParser new XMLConfigBuilder(inputStream, environment, reporter);return build(xmlParser.parse());} catch (Exception e) {throw new BuilderException(Error building SqlSession., e);}
}SqlSession 管理DefaultSqlSessionFactory.java
DefaultSqlSessionFactory 提供了创建 SqlSession 的方法
public SqlSession openSession() {return openSessionFromDataSource(configuration.getEnvironment().getDataSource(), null, false);
}Executor 执行器BaseExecutor.java
BaseExecutor 是 Executor 接口的抽象实现提供了事务和缓存管理的框架
public E ListE query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) {ErrorContext.instance().resource(ms.getResource()).activity(querying).object(ms.getId());if (closed) {throw new ExecutorException(Executor was closed.);}if (queryStack 0 ms.isFlushCacheRequired()) {clearLocalCache();}ListE list;try {queryStack;list resultHandler null ? (ListE) localCache.getObject(key) : null;if (list ! null resultHandler ! null) {resultHandler.handleRows(list);}if (list null) {list doQuery(ms, parameter, rowBounds, resultHandler, key, boundSql);}} finally {queryStack--;}return list;
}动态代理MapperProxy.java
MapperProxy 使用 JDK 动态代理来拦截 Mapper 接口方法的调用
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (Object.class.equals(method.getDeclaringClass())) {try {return method.invoke(this, args);} catch (Throwable t) {throw new RuntimeException(Error when attempting to invoke method method.getName() on Mapper Proxy., t);}} else {return mapperMethod.execute(sqlSession, args);}
}映射器 XML 解析XMLMapperBuilder.java
XMLMapperBuilder 负责解析 Mapper 的 XML 文件
public void parse() {if (!configuration.isResourceLoaded(resource)) {configurationElement(parser.evalNode(mapper));configuration.addLoadedResource(resource);bindMapperForNamespace();}
}缓存机制PerpetualCache.java
PerpetualCache 是 Mybatis 缓存的基本实现
public V get(Object key, CacheProvider provider) {V value (V) cache.get(key);if (value null) {value provider.apply(key);cache.put(key, value);}return value;
}TypeHandler 和 ParameterHandler
TypeHandler 接口定义了 Java 类型和 JDBC 类型之间的转换逻辑
public interface TypeHandlerT {void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;T getResult(ResultSet rs, int columnIndex) throws SQLException;T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}ParameterHandler 负责将方法参数映射到 SQL 语句的参数上
public void setParameters(PreparedStatement ps) throws SQLException {for (ParameterMapping parameter : boundSql.getParameterMappings()) {if (parameter.getMode() ! ParameterMode.OUT) {Object value parameter.getObject(value);TypeHandler typeHandler parameter.getTypeHandler();typeHandler.setParameter(ps, parameter.getI(), value, parameter.getJdbcType());}}
}结果映射DefaultResultSetHandler.java
DefaultResultSetHandler 负责将 ResultSet 中的数据映射到 Java 对象
public E ListE handleRowValues(ResultSet rs, ListE resultList, RowBounds rowBounds) throws SQLException {if (hasResultSetData(rs)) {int offset rowBounds null || rowBounds.getOffset() RowBounds.NO_ROW_OFFSET ? 0 : rowBounds.getOffset();int limit rowBounds null || rowBounds.getLimit() RowBounds.NO_ROW_LIMIT ? Integer.MAX_VALUE : rowBounds.getLimit();int rowNumber 0;while (rs.next()) {if (offset 0) {offset--;continue;}if (limit 0) {limit--;if (limit 0) {break;}}Object rowValue getRowValue(rs, null);resultList.add((E) rowValue);rowNumber;}}return resultList;
}这些代码片段展示了 Mybatis 核心组件的工作原理。然而由于 Mybatis 的复杂性这里只提供了部分关键代码的简要概述。要完全理解 Mybatis 的内部实现需要深入研究每个类和接口的实现细节以及它们之间的交互。关注威哥爱编程一起向全栈出发。