MyBatis 解析运行原理

 2023-09-18 阅读 28 评论 0

摘要:提供一个接口 package com.ming.MyBatis;import com.ming.MyBatis.POJO.Role; import com.ming.MyBatis.POJO.Student; import com.ming.MyBatis.POJO.StudentCard; import org.apache.ibatis.annotations.Param; import java.util.List; import java.util.Map;public interfa

提供一个接口

package com.ming.MyBatis;import com.ming.MyBatis.POJO.Role;
import com.ming.MyBatis.POJO.Student;
import com.ming.MyBatis.POJO.StudentCard;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;public interface RoleMapper {/*** @param id* @return*/public Role getRole(int id);/*** 查询Map* @param params* @return*/public List<Role> findRoleByteMap(Map<String, String> params);/*** @param roleName* @param note* @return*/public List<Role> findRoleByteMap1(@Param("roleName") String roleName, @Param("note") String note);public List<StudentCard> findStudentSelfCardByStudentId(@Param("studentId") int studentId);public List<Student> getStudent(@Param("uid")int uid);
}

接口如何生成对象,采用jdk的动态代理技术,生成对象

CGLB

使用CGLB动态代理可以实现在不提供接口的时候,生成对象

构建SqlSessionFactory过程

在源代码中是

sqlSessionFactory = new SqlSessionFactoryBuilder().build(cfgReader, properties);

通过new 出一个 SqlSessionFactoryBuilder对象,然后调用build方法.

计算机运行原理、进入 SqlSessionFactoryBuilder

/***    Copyright 2009-2019 the original author or authors.**    Licensed under the Apache License, Version 2.0 (the "License");*    you may not use this file except in compliance with the License.*    You may obtain a copy of the License at**       http://www.apache.org/licenses/LICENSE-2.0**    Unless required by applicable law or agreed to in writing, software*    distributed under the License is distributed on an "AS IS" BASIS,*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*    See the License for the specific language governing permissions and*    limitations under the License.*/
package org.apache.ibatis.session;import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Properties;import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.exceptions.ExceptionFactory;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;/*** Builds {@link SqlSession} instances.** @author Clinton Begin*/
public class SqlSessionFactoryBuilder {public SqlSessionFactory build(Reader reader) {return build(reader, null, null);}public SqlSessionFactory build(Reader reader, String environment) {return build(reader, environment, null);}public SqlSessionFactory build(Reader reader, Properties properties) {return build(reader, null, properties);}public SqlSessionFactory build(Reader reader, String environment, Properties properties) {try {XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);return build(parser.parse());} catch (Exception e) {throw ExceptionFactory.wrapException("Error building SqlSession.", e);} finally {ErrorContext.instance().reset();try {reader.close();} catch (IOException e) {// Intentionally ignore. Prefer previous error.}}}public SqlSessionFactory build(InputStream inputStream) {return build(inputStream, null, null);}public SqlSessionFactory build(InputStream inputStream, String environment) {return build(inputStream, environment, null);}public SqlSessionFactory build(InputStream inputStream, Properties properties) {return build(inputStream, null, properties);}public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {try {XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);return build(parser.parse());} catch (Exception e) {throw ExceptionFactory.wrapException("Error building SqlSession.", e);} finally {ErrorContext.instance().reset();try {inputStream.close();} catch (IOException e) {// Intentionally ignore. Prefer previous error.}}}public SqlSessionFactory build(Configuration config) {return new DefaultSqlSessionFactory(config);}}

重写的方法
通过这一句配置文件读入

XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);

所有的都将会调用该方法

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {try {XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);return build(parser.parse());} catch (Exception e) {throw ExceptionFactory.wrapException("Error building SqlSession.", e);} finally {ErrorContext.instance().reset();try {inputStream.close();} catch (IOException e) {// Intentionally ignore. Prefer previous error.}}}

这一段中

XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);

这一句
XML配置读入进入

由于返回的是XMLConfigBuilder对象 所以是使用该对象去创建SqlSessionFactory对象

maven详解,其中SqlSessionFactory为接口

/***    Copyright 2009-2019 the original author or authors.**    Licensed under the Apache License, Version 2.0 (the "License");*    you may not use this file except in compliance with the License.*    You may obtain a copy of the License at**       http://www.apache.org/licenses/LICENSE-2.0**    Unless required by applicable law or agreed to in writing, software*    distributed under the License is distributed on an "AS IS" BASIS,*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*    See the License for the specific language governing permissions and*    limitations under the License.*/
package org.apache.ibatis.session;import java.sql.Connection;/*** Creates an {@link SqlSession} out of a connection or a DataSource** @author Clinton Begin*/
public interface SqlSessionFactory {SqlSession openSession();SqlSession openSession(boolean autoCommit);SqlSession openSession(Connection connection);SqlSession openSession(TransactionIsolationLevel level);SqlSession openSession(ExecutorType execType);SqlSession openSession(ExecutorType execType, boolean autoCommit);SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);SqlSession openSession(ExecutorType execType, Connection connection);Configuration getConfiguration();}

其中根据源码可以看到XMLConfigBuilder对象继承于BaseBuilder, BaseBuilder为抽象类 其中的BaseBuilder 继承 XMLConfigBuilder

所以,这两句成立

private volatile static SqlSessionFactory sqlSessionFactory = null;
sqlSessionFactory = new SqlSessionFactoryBuilder().build(cfgReader, properties);

最后就有了SqlSessionFactory实现类

这种创建为Builder创建

进入XMLConfigBuilder 可以看到第115行

      // read it after objectFactory and objectWrapperFactory issue #631environmentsElement(root.evalNode("environments"));

cpu原理、可以看到读入配置文件environments节点

其中还可以看到

  private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {super(new Configuration());ErrorContext.instance().resource("SQL Mapper Configuration");this.configuration.setVariables(props);this.parsed = false;this.environment = environment;this.parser = parser;}

使用的是super 所以进入 Configuration()对象
可以看到这是所有的配置文件

public Configuration() {typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);typeAliasRegistry.registerAlias("FIFO", FifoCache.class);typeAliasRegistry.registerAlias("LRU", LruCache.class);typeAliasRegistry.registerAlias("SOFT", SoftCache.class);typeAliasRegistry.registerAlias("WEAK", WeakCache.class);typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class);typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class);typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class);typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class);typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class);languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class);languageRegistry.register(RawLanguageDriver.class);}

配置文件信息将会在这个类中保存

该类中的方法MappedStatement 为获取映射器的节点

  public MappedStatement getMappedStatement(String id, boolean validateIncompleteStatements) {if (validateIncompleteStatements) {buildAllStatements();}return mappedStatements.get(id);}
public final class MappedStatement {private String resource;private Configuration configuration;private String id;private Integer fetchSize;private Integer timeout;private StatementType statementType;private ResultSetType resultSetType;private SqlSource sqlSource;private Cache cache;private ParameterMap parameterMap;private List<ResultMap> resultMaps;private boolean flushCacheRequired;private boolean useCache;private boolean resultOrdered;private SqlCommandType sqlCommandType;private KeyGenerator keyGenerator;private String[] keyProperties;private String[] keyColumns;private boolean hasNestedResultMaps;private String databaseId;private Log statementLog;private LanguageDriver lang;private String[] resultSets;

这里进入的是映射器的节点信息

tomcat底层原理。在插件中可以通过MappedStatement类,来获取到映射器的节点,即,获取到映射器的信息.在Tomcat编译成为class文件的时候,会写死在class文件中…

其中MappedStatement为final类型

在映射类的第43行有一个重要的属性

  private SqlSource sqlSource;

进入该接口

public interface SqlSource {BoundSql getBoundSql(Object parameterObject);}

其接口有方法

  BoundSql getBoundSql(Object parameterObject);

进入该类的查看BoundSql

public class BoundSql {private final String sql;private final List<ParameterMapping> parameterMappings;private final Object parameterObject;private final Map<String, Object> additionalParameters;private final MetaObject metaParameters;public BoundSql(Configuration configuration, String sql, List<ParameterMapping> parameterMappings, Object parameterObject) {this.sql = sql;this.parameterMappings = parameterMappings;this.parameterObject = parameterObject;this.additionalParameters = new HashMap<>();this.metaParameters = configuration.newMetaObject(additionalParameters);}public String getSql() {return sql;}public List<ParameterMapping> getParameterMappings() {return parameterMappings;}public Object getParameterObject() {return parameterObject;}public boolean hasAdditionalParameter(String name) {String paramName = new PropertyTokenizer(name).getName();return additionalParameters.containsKey(paramName);}public void setAdditionalParameter(String name, Object value) {metaParameters.setValue(name, value);}public Object getAdditionalParameter(String name) {return metaParameters.getValue(name);}
}

java lambda表达式原理。BoundSql有三个属性,

    this.sql = sql;this.parameterMappings = parameterMappings;// 传递进入的参数 根据Param注解this.parameterObject = parameterObject;this.additionalParameters = new HashMap<>();this.metaParameters = configuration.newMetaObject(additionalParameters);

SqlSession运行

SqlSession通过动态代理的方式运行

首先 SqlSessionFactory sqlSessionFactory 是SqlSessionFactory接口
SqlSession类如下

/***    Copyright 2009-2019 the original author or authors.**    Licensed under the Apache License, Version 2.0 (the "License");*    you may not use this file except in compliance with the License.*    You may obtain a copy of the License at**       http://www.apache.org/licenses/LICENSE-2.0**    Unless required by applicable law or agreed to in writing, software*    distributed under the License is distributed on an "AS IS" BASIS,*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*    See the License for the specific language governing permissions and*    limitations under the License.*/
package org.apache.ibatis.session;import java.sql.Connection;/*** Creates an {@link SqlSession} out of a connection or a DataSource** @author Clinton Begin*/
public interface SqlSessionFactory {SqlSession openSession();SqlSession openSession(boolean autoCommit);SqlSession openSession(Connection connection);SqlSession openSession(TransactionIsolationLevel level);SqlSession openSession(ExecutorType execType);SqlSession openSession(ExecutorType execType, boolean autoCommit);SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);SqlSession openSession(ExecutorType execType, Connection connection);Configuration getConfiguration();}

首先try里面的第四行

            sqlSession = SqlSessionFactoryUtil.openSqlSesion();roleMapper = sqlSession.getMapper(RoleMapper.class);students = roleMapper.getStudent(1);students1 = roleMapper.getStudent(1);sqlSession.commit();

进入getMapper

/***    Copyright 2009-2019 the original author or authors.**    Licensed under the Apache License, Version 2.0 (the "License");*    you may not use this file except in compliance with the License.*    You may obtain a copy of the License at**       http://www.apache.org/licenses/LICENSE-2.0**    Unless required by applicable law or agreed to in writing, software*    distributed under the License is distributed on an "AS IS" BASIS,*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.*    See the License for the specific language governing permissions and*    limitations under the License.*/
package org.apache.ibatis.session;import java.io.Closeable;
import java.sql.Connection;
import java.util.List;
import java.util.Map;import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.executor.BatchResult;/*** The primary Java interface for working with MyBatis.* Through this interface you can execute commands, get mappers and manage transactions.** @author Clinton Begin*/
public interface SqlSession extends Closeable {/*** Retrieve a single row mapped from the statement key.* @param <T> the returned object type* @param statement* @return Mapped object*/<T> T selectOne(String statement);/*** Retrieve a single row mapped from the statement key and parameter.* @param <T> the returned object type* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @return Mapped object*/<T> T selectOne(String statement, Object parameter);/*** Retrieve a list of mapped objects from the statement key and parameter.* @param <E> the returned list element type* @param statement Unique identifier matching the statement to use.* @return List of mapped object*/<E> List<E> selectList(String statement);/*** Retrieve a list of mapped objects from the statement key and parameter.* @param <E> the returned list element type* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @return List of mapped object*/<E> List<E> selectList(String statement, Object parameter);/*** Retrieve a list of mapped objects from the statement key and parameter,* within the specified row bounds.* @param <E> the returned list element type* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @param rowBounds  Bounds to limit object retrieval* @return List of mapped object*/<E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);/*** The selectMap is a special case in that it is designed to convert a list* of results into a Map based on one of the properties in the resulting* objects.* Eg. Return a of Map[Integer,Author] for selectMap("selectAuthors","id")* @param <K> the returned Map keys type* @param <V> the returned Map values type* @param statement Unique identifier matching the statement to use.* @param mapKey The property to use as key for each value in the list.* @return Map containing key pair data.*/<K, V> Map<K, V> selectMap(String statement, String mapKey);/*** The selectMap is a special case in that it is designed to convert a list* of results into a Map based on one of the properties in the resulting* objects.* @param <K> the returned Map keys type* @param <V> the returned Map values type* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @param mapKey The property to use as key for each value in the list.* @return Map containing key pair data.*/<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);/*** The selectMap is a special case in that it is designed to convert a list* of results into a Map based on one of the properties in the resulting* objects.* @param <K> the returned Map keys type* @param <V> the returned Map values type* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @param mapKey The property to use as key for each value in the list.* @param rowBounds  Bounds to limit object retrieval* @return Map containing key pair data.*/<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);/*** A Cursor offers the same results as a List, except it fetches data lazily using an Iterator.* @param <T> the returned cursor element type.* @param statement Unique identifier matching the statement to use.* @return Cursor of mapped objects*/<T> Cursor<T> selectCursor(String statement);/*** A Cursor offers the same results as a List, except it fetches data lazily using an Iterator.* @param <T> the returned cursor element type.* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @return Cursor of mapped objects*/<T> Cursor<T> selectCursor(String statement, Object parameter);/*** A Cursor offers the same results as a List, except it fetches data lazily using an Iterator.* @param <T> the returned cursor element type.* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @param rowBounds  Bounds to limit object retrieval* @return Cursor of mapped objects*/<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds);/*** Retrieve a single row mapped from the statement key and parameter* using a {@code ResultHandler}.* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @param handler ResultHandler that will handle each retrieved row*/void select(String statement, Object parameter, ResultHandler handler);/*** Retrieve a single row mapped from the statement* using a {@code ResultHandler}.* @param statement Unique identifier matching the statement to use.* @param handler ResultHandler that will handle each retrieved row*/void select(String statement, ResultHandler handler);/*** Retrieve a single row mapped from the statement key and parameter* using a {@code ResultHandler} and {@code RowBounds}.* @param statement Unique identifier matching the statement to use.* @param rowBounds RowBound instance to limit the query results* @param handler ResultHandler that will handle each retrieved row*/void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);/*** Execute an insert statement.* @param statement Unique identifier matching the statement to execute.* @return int The number of rows affected by the insert.*/int insert(String statement);/*** Execute an insert statement with the given parameter object. Any generated* autoincrement values or selectKey entries will modify the given parameter* object properties. Only the number of rows affected will be returned.* @param statement Unique identifier matching the statement to execute.* @param parameter A parameter object to pass to the statement.* @return int The number of rows affected by the insert.*/int insert(String statement, Object parameter);/*** Execute an update statement. The number of rows affected will be returned.* @param statement Unique identifier matching the statement to execute.* @return int The number of rows affected by the update.*/int update(String statement);/*** Execute an update statement. The number of rows affected will be returned.* @param statement Unique identifier matching the statement to execute.* @param parameter A parameter object to pass to the statement.* @return int The number of rows affected by the update.*/int update(String statement, Object parameter);/*** Execute a delete statement. The number of rows affected will be returned.* @param statement Unique identifier matching the statement to execute.* @return int The number of rows affected by the delete.*/int delete(String statement);/*** Execute a delete statement. The number of rows affected will be returned.* @param statement Unique identifier matching the statement to execute.* @param parameter A parameter object to pass to the statement.* @return int The number of rows affected by the delete.*/int delete(String statement, Object parameter);/*** Flushes batch statements and commits database connection.* Note that database connection will not be committed if no updates/deletes/inserts were called.* To force the commit call {@link SqlSession#commit(boolean)}*/void commit();/*** Flushes batch statements and commits database connection.* @param force forces connection commit*/void commit(boolean force);/*** Discards pending batch statements and rolls database connection back.* Note that database connection will not be rolled back if no updates/deletes/inserts were called.* To force the rollback call {@link SqlSession#rollback(boolean)}*/void rollback();/*** Discards pending batch statements and rolls database connection back.* Note that database connection will not be rolled back if no updates/deletes/inserts were called.* @param force forces connection rollback*/void rollback(boolean force);/*** Flushes batch statements.* @return BatchResult list of updated records* @since 3.0.6*/List<BatchResult> flushStatements();/*** Closes the session.*/@Overridevoid close();/*** Clears local session cache.*/void clearCache();/*** Retrieves current configuration.* @return Configuration*/Configuration getConfiguration();/*** Retrieves a mapper.* @param <T> the mapper type* @param type Mapper interface class* @return a mapper bound to this SqlSession*/<T> T getMapper(Class<T> type);/*** Retrieves inner database connection.* @return Connection*/Connection getConnection();
}

这是一个接口
其中DefaultSqlSession为旧版本,新版本使用的是SqlSessionManager
进入SqlSessionManager

  @Overridepublic <T> T getMapper(Class<T> type) {return getConfiguration().getMapper(type, this);}

tomcat原理详解。可以看到使用getConfiguration().getMapper(type, this);
getConfiguration()为获取配置信息,mapperRegistry为映射配置类的映射注册表,进入getMapper

  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);if (mapperProxyFactory == null) {throw new BindingException("Type " + type + " is not known to the MapperRegistry.");}try {return mapperProxyFactory.newInstance(sqlSession);} catch (Exception e) {throw new BindingException("Error getting mapper instance. Cause: " + e, e);}}

如下

 @SuppressWarnings("unchecked")public <T> T getMapper(Class<T> type, SqlSession sqlSession) {final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);if (mapperProxyFactory == null) {throw new BindingException("Type " + type + " is not known to the MapperRegistry.");}try {return mapperProxyFactory.newInstance(sqlSession);} catch (Exception e) {throw new BindingException("Error getting mapper instance. Cause: " + e, e);}}

然后进入代理工厂类

public class MapperProxyFactory<T> {private final Class<T> mapperInterface;private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<>();public MapperProxyFactory(Class<T> mapperInterface) {this.mapperInterface = mapperInterface;}public Class<T> getMapperInterface() {return mapperInterface;}public Map<Method, MapperMethod> getMethodCache() {return methodCache;}@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, methodCache);return newInstance(mapperProxy);}}

有这么一句

  @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, methodCache);return newInstance(mapperProxy);}

在MapperProxy中有如下几个

  @Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {try {if (Object.class.equals(method.getDeclaringClass())) {return method.invoke(this, args);} else if (isDefaultMethod(method)) {return invokeDefaultMethod(proxy, method, args);}} catch (Throwable t) {throw ExceptionUtil.unwrapThrowable(t);}final MapperMethod mapperMethod = cachedMapperMethod(method);return mapperMethod.execute(sqlSession, args);}

docker底层实现原理,通过动态代理生成该对象
然后接着查看execute源码

 public Object execute(SqlSession sqlSession, Object[] args) {Object result;switch (command.getType()) {case INSERT: {Object param = method.convertArgsToSqlCommandParam(args);result = rowCountResult(sqlSession.insert(command.getName(), param));break;}case UPDATE: {Object param = method.convertArgsToSqlCommandParam(args);result = rowCountResult(sqlSession.update(command.getName(), param));break;}case DELETE: {Object param = method.convertArgsToSqlCommandParam(args);result = rowCountResult(sqlSession.delete(command.getName(), param));break;}case SELECT:if (method.returnsVoid() && method.hasResultHandler()) {executeWithResultHandler(sqlSession, args);result = null;} else if (method.returnsMany()) {result = executeForMany(sqlSession, args);} else if (method.returnsMap()) {result = executeForMap(sqlSession, args);} else if (method.returnsCursor()) {result = executeForCursor(sqlSession, args);} else {Object param = method.convertArgsToSqlCommandParam(args);result = sqlSession.selectOne(command.getName(), param);if (method.returnsOptional()&& (result == null || !method.getReturnType().equals(result.getClass()))) {result = Optional.ofNullable(result);}}break;case FLUSH:result = sqlSession.flushStatements();break;default:throw new BindingException("Unknown execution method for: " + command.getName());}if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {throw new BindingException("Mapper method '" + command.getName()+ " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");}return result;}

这里就能看到sql啦

接着任意进入一个

private <E> Object executeForMany(SqlSession sqlSession, Object[] args) {List<E> result;Object param = method.convertArgsToSqlCommandParam(args);if (method.hasRowBounds()) {RowBounds rowBounds = method.extractRowBounds(args);result = sqlSession.selectList(command.getName(), param, rowBounds);} else {result = sqlSession.selectList(command.getName(), param);}// issue #510 Collections & arrays supportif (!method.getReturnType().isAssignableFrom(result.getClass())) {if (method.getReturnType().isArray()) {return convertToArray(result);} else {return convertToDeclaredCollection(sqlSession.getConfiguration(), result);}}return result;}

不想看了…反正就是最后调用sqlsession的


/*** The primary Java interface for working with MyBatis.* Through this interface you can execute commands, get mappers and manage transactions.** @author Clinton Begin*/
public interface SqlSession extends Closeable {/*** Retrieve a single row mapped from the statement key.* @param <T> the returned object type* @param statement* @return Mapped object*/<T> T selectOne(String statement);/*** Retrieve a single row mapped from the statement key and parameter.* @param <T> the returned object type* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @return Mapped object*/<T> T selectOne(String statement, Object parameter);/*** Retrieve a list of mapped objects from the statement key and parameter.* @param <E> the returned list element type* @param statement Unique identifier matching the statement to use.* @return List of mapped object*/<E> List<E> selectList(String statement);/*** Retrieve a list of mapped objects from the statement key and parameter.* @param <E> the returned list element type* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @return List of mapped object*/<E> List<E> selectList(String statement, Object parameter);/*** Retrieve a list of mapped objects from the statement key and parameter,* within the specified row bounds.* @param <E> the returned list element type* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @param rowBounds  Bounds to limit object retrieval* @return List of mapped object*/<E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);/*** The selectMap is a special case in that it is designed to convert a list* of results into a Map based on one of the properties in the resulting* objects.* Eg. Return a of Map[Integer,Author] for selectMap("selectAuthors","id")* @param <K> the returned Map keys type* @param <V> the returned Map values type* @param statement Unique identifier matching the statement to use.* @param mapKey The property to use as key for each value in the list.* @return Map containing key pair data.*/<K, V> Map<K, V> selectMap(String statement, String mapKey);/*** The selectMap is a special case in that it is designed to convert a list* of results into a Map based on one of the properties in the resulting* objects.* @param <K> the returned Map keys type* @param <V> the returned Map values type* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @param mapKey The property to use as key for each value in the list.* @return Map containing key pair data.*/<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);/*** The selectMap is a special case in that it is designed to convert a list* of results into a Map based on one of the properties in the resulting* objects.* @param <K> the returned Map keys type* @param <V> the returned Map values type* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @param mapKey The property to use as key for each value in the list.* @param rowBounds  Bounds to limit object retrieval* @return Map containing key pair data.*/<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);/*** A Cursor offers the same results as a List, except it fetches data lazily using an Iterator.* @param <T> the returned cursor element type.* @param statement Unique identifier matching the statement to use.* @return Cursor of mapped objects*/<T> Cursor<T> selectCursor(String statement);/*** A Cursor offers the same results as a List, except it fetches data lazily using an Iterator.* @param <T> the returned cursor element type.* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @return Cursor of mapped objects*/<T> Cursor<T> selectCursor(String statement, Object parameter);/*** A Cursor offers the same results as a List, except it fetches data lazily using an Iterator.* @param <T> the returned cursor element type.* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @param rowBounds  Bounds to limit object retrieval* @return Cursor of mapped objects*/<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds);/*** Retrieve a single row mapped from the statement key and parameter* using a {@code ResultHandler}.* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @param handler ResultHandler that will handle each retrieved row*/void select(String statement, Object parameter, ResultHandler handler);/*** Retrieve a single row mapped from the statement* using a {@code ResultHandler}.* @param statement Unique identifier matching the statement to use.* @param handler ResultHandler that will handle each retrieved row*/void select(String statement, ResultHandler handler);/*** Retrieve a single row mapped from the statement key and parameter* using a {@code ResultHandler} and {@code RowBounds}.* @param statement Unique identifier matching the statement to use.* @param rowBounds RowBound instance to limit the query results* @param handler ResultHandler that will handle each retrieved row*/void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);/*** Execute an insert statement.* @param statement Unique identifier matching the statement to execute.* @return int The number of rows affected by the insert.*/int insert(String statement);/*** Execute an insert statement with the given parameter object. Any generated* autoincrement values or selectKey entries will modify the given parameter* object properties. Only the number of rows affected will be returned.* @param statement Unique identifier matching the statement to execute.* @param parameter A parameter object to pass to the statement.* @return int The number of rows affected by the insert.*/int insert(String statement, Object parameter);/*** Execute an update statement. The number of rows affected will be returned.* @param statement Unique identifier matching the statement to execute.* @return int The number of rows affected by the update.*/int update(String statement);/*** Execute an update statement. The number of rows affected will be returned.* @param statement Unique identifier matching the statement to execute.* @param parameter A parameter object to pass to the statement.* @return int The number of rows affected by the update.*/int update(String statement, Object parameter);/*** Execute a delete statement. The number of rows affected will be returned.* @param statement Unique identifier matching the statement to execute.* @return int The number of rows affected by the delete.*/int delete(String statement);/*** Execute a delete statement. The number of rows affected will be returned.* @param statement Unique identifier matching the statement to execute.* @param parameter A parameter object to pass to the statement.* @return int The number of rows affected by the delete.*/int delete(String statement, Object parameter);/*** Flushes batch statements and commits database connection.* Note that database connection will not be committed if no updates/deletes/inserts were called.* To force the commit call {@link SqlSession#commit(boolean)}*/void commit();/*** Flushes batch statements and commits database connection.* @param force forces connection commit*/void commit(boolean force);/*** Discards pending batch statements and rolls database connection back.* Note that database connection will not be rolled back if no updates/deletes/inserts were called.* To force the rollback call {@link SqlSession#rollback(boolean)}*/void rollback();/*** Discards pending batch statements and rolls database connection back.* Note that database connection will not be rolled back if no updates/deletes/inserts were called.* @param force forces connection rollback*/void rollback(boolean force);/*** Flushes batch statements.* @return BatchResult list of updated records* @since 3.0.6*/List<BatchResult> flushStatements();/*** Closes the session.*/@Overridevoid close();/*** Clears local session cache.*/void clearCache();/*** Retrieves current configuration.* @return Configuration*/Configuration getConfiguration();/*** Retrieves a mapper.* @param <T> the mapper type* @param type Mapper interface class* @return a mapper bound to this SqlSession*/<T> T getMapper(Class<T> type);/*** Retrieves inner database connection.* @return Connection*/Connection getConnection();
}

映射器的本质是动态代理对象

最后都是调用sqlsession接口的定义的方法完成和数据库的交互

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/74677.html

上一篇:thinkphp 请求

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息