摘要:提供一個(gè)接口查詢接口如何生成對(duì)象采用的動(dòng)態(tài)代理技術(shù)生成對(duì)象使用動(dòng)態(tài)代理可以實(shí)現(xiàn)在不提供接口的時(shí)候生成對(duì)象構(gòu)建過(guò)程在源代碼中是通過(guò)出一個(gè)對(duì)象然后調(diào)用方法進(jìn)入重寫(xiě)的方法通過(guò)這一句配置文件讀入所有的都將會(huì)調(diào)用該方法這一段中這一句配置讀入進(jìn)入由
提供一個(gè)接口
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 ListfindRoleByteMap(Map params); /** * @param roleName * @param note * @return */ public List findRoleByteMap1(@Param("roleName") String roleName, @Param("note") String note); public List findStudentSelfCardByStudentId(@Param("studentId") int studentId); public List getStudent(@Param("uid")int uid); }
接口如何生成對(duì)象,采用jdk的動(dòng)態(tài)代理技術(shù),生成對(duì)象
CGLB使用CGLB動(dòng)態(tài)代理可以實(shí)現(xiàn)在不提供接口的時(shí)候,生成對(duì)象
構(gòu)建SqlSessionFactory過(guò)程在源代碼中是
sqlSessionFactory = new SqlSessionFactoryBuilder().build(cfgReader, properties);
通過(guò)new 出一個(gè) SqlSessionFactoryBuilder對(duì)象,然后調(diào)用build方法.
進(jìn)入 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); } }
重寫(xiě)的方法
通過(guò)這一句配置文件讀入
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
所有的都將會(huì)調(diào)用該方法
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配置讀入進(jìn)入
由于返回的是XMLConfigBuilder對(duì)象 所以是使用該對(duì)象去創(chuàng)建SqlSessionFactory對(duì)象
其中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(); }
其中根據(jù)源碼可以看到XMLConfigBuilder對(duì)象繼承于BaseBuilder, BaseBuilder為抽象類 其中的BaseBuilder 繼承 XMLConfigBuilder
所以,這兩句成立
private volatile static SqlSessionFactory sqlSessionFactory = null; sqlSessionFactory = new SqlSessionFactoryBuilder().build(cfgReader, properties);
最后就有了SqlSessionFactory實(shí)現(xiàn)類
這種創(chuàng)建為Builder創(chuàng)建
進(jìn)入XMLConfigBuilder 可以看到第115行
// read it after objectFactory and objectWrapperFactory issue #631 environmentsElement(root.evalNode("environments"));
可以看到讀入配置文件environments節(jié)點(diǎn)
其中還可以看到
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 所以進(jìn)入 Configuration()對(duì)象
可以看到這是所有的配置文件
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); }
配置文件信息將會(huì)在這個(gè)類中保存
該類中的方法MappedStatement 為獲取映射器的節(jié)點(diǎn)
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 ListresultMaps; 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;
這里進(jìn)入的是映射器的節(jié)點(diǎn)信息
在插件中可以通過(guò)MappedStatement類,來(lái)獲取到映射器的節(jié)點(diǎn),即,獲取到映射器的信息.在Tomcat編譯成為class文件的時(shí)候,會(huì)寫(xiě)死在class文件中..
其中MappedStatement為final類型
在映射類的第43行有一個(gè)重要的屬性
private SqlSource sqlSource;
進(jìn)入該接口
public interface SqlSource { BoundSql getBoundSql(Object parameterObject); }
其接口有方法
BoundSql getBoundSql(Object parameterObject);
進(jìn)入該類的查看BoundSql
public class BoundSql { private final String sql; private final ListparameterMappings; private final Object parameterObject; private final Map additionalParameters; private final MetaObject metaParameters; public BoundSql(Configuration configuration, String sql, List 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 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); } }
BoundSql有三個(gè)屬性,
this.sql = sql; this.parameterMappings = parameterMappings; // 傳遞進(jìn)入的參數(shù) 根據(jù)Param注解 this.parameterObject = parameterObject; this.additionalParameters = new HashMap<>(); this.metaParameters = configuration.newMetaObject(additionalParameters);SqlSession運(yùn)行
SqlSession通過(guò)動(dòng)態(tài)代理的方式運(yùn)行
首先 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();
進(jìn)入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. * @paramthe returned object type * @param statement * @return Mapped object */ T selectOne(String statement); /** * Retrieve a single row mapped from the statement key and parameter. * @param 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 selectOne(String statement, Object parameter); /** * Retrieve a list of mapped objects from the statement key and parameter. * @param the returned list element type * @param statement Unique identifier matching the statement to use. * @return List of mapped object */ List selectList(String statement); /** * Retrieve a list of mapped objects from the statement key and parameter. * @param 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 */ List selectList(String statement, Object parameter); /** * Retrieve a list of mapped objects from the statement key and parameter, * within the specified row bounds. * @param 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 */ List 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 the returned Map keys type * @param 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. */ Map 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 the returned Map keys type * @param 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. */ Map 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 the returned Map keys type * @param 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. */ Map 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 the returned cursor element type. * @param statement Unique identifier matching the statement to use. * @return Cursor of mapped objects */ Cursor selectCursor(String statement); /** * A Cursor offers the same results as a List, except it fetches data lazily using an Iterator. * @param 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 */ Cursor selectCursor(String statement, Object parameter); /** * A Cursor offers the same results as a List, except it fetches data lazily using an Iterator. * @param 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 */ Cursor 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 flushStatements(); /** * Closes the session. */ @Override void close(); /** * Clears local session cache. */ void clearCache(); /** * Retrieves current configuration. * @return Configuration */ Configuration getConfiguration(); /** * Retrieves a mapper. * @param the mapper type * @param type Mapper interface class * @return a mapper bound to this SqlSession */ T getMapper(Class type); /** * Retrieves inner database connection. * @return Connection */ Connection getConnection(); }
這是一個(gè)接口
其中DefaultSqlSession為舊版本,新版本使用的是SqlSessionManager
進(jìn)入SqlSessionManager
@Override publicT getMapper(Class type) { return getConfiguration().getMapper(type, this); }
可以看到使用getConfiguration().getMapper(type, this);
getConfiguration()為獲取配置信息,mapperRegistry為映射配置類的映射注冊(cè)表,進(jìn)入getMapper
publicT getMapper(Class type, SqlSession sqlSession) { final MapperProxyFactory mapperProxyFactory = (MapperProxyFactory ) 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") publicT getMapper(Class type, SqlSession sqlSession) { final MapperProxyFactory mapperProxyFactory = (MapperProxyFactory ) 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); } }
然后進(jìn)入代理工廠類
public class MapperProxyFactory{ private final Class mapperInterface; private final Map methodCache = new ConcurrentHashMap<>(); public MapperProxyFactory(Class mapperInterface) { this.mapperInterface = mapperInterface; } public Class getMapperInterface() { return mapperInterface; } public Map getMethodCache() { return methodCache; } @SuppressWarnings("unchecked") protected T newInstance(MapperProxy mapperProxy) { return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy); } public T newInstance(SqlSession sqlSession) { final MapperProxy mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache); return newInstance(mapperProxy); } }
有這么一句
@SuppressWarnings("unchecked") protected T newInstance(MapperProxymapperProxy) { return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy); }
調(diào)用的是這一句
public T newInstance(SqlSession sqlSession) { final MapperProxymapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache); return newInstance(mapperProxy); }
在MapperProxy中有如下幾個(gè)
@Override public 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); }
通過(guò)動(dòng)態(tài)代理生成該對(duì)象
然后接著查看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啦
接著任意進(jìn)入一個(gè)
privateObject executeForMany(SqlSession sqlSession, Object[] args) { List 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 support if (!method.getReturnType().isAssignableFrom(result.getClass())) { if (method.getReturnType().isArray()) { return convertToArray(result); } else { return convertToDeclaredCollection(sqlSession.getConfiguration(), result); } } return result; }
不想看了.....反正就是最后調(diào)用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. * @paramthe returned object type * @param statement * @return Mapped object */ T selectOne(String statement); /** * Retrieve a single row mapped from the statement key and parameter. * @param 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 selectOne(String statement, Object parameter); /** * Retrieve a list of mapped objects from the statement key and parameter. * @param the returned list element type * @param statement Unique identifier matching the statement to use. * @return List of mapped object */ List selectList(String statement); /** * Retrieve a list of mapped objects from the statement key and parameter. * @param 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 */ List selectList(String statement, Object parameter); /** * Retrieve a list of mapped objects from the statement key and parameter, * within the specified row bounds. * @param 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 */ List 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 the returned Map keys type * @param 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. */ Map 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 the returned Map keys type * @param 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. */ Map 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 the returned Map keys type * @param 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. */ Map 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 the returned cursor element type. * @param statement Unique identifier matching the statement to use. * @return Cursor of mapped objects */ Cursor selectCursor(String statement); /** * A Cursor offers the same results as a List, except it fetches data lazily using an Iterator. * @param 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 */ Cursor selectCursor(String statement, Object parameter); /** * A Cursor offers the same results as a List, except it fetches data lazily using an Iterator. * @param 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 */ Cursor 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 flushStatements(); /** * Closes the session. */ @Override void close(); /** * Clears local session cache. */ void clearCache(); /** * Retrieves current configuration. * @return Configuration */ Configuration getConfiguration(); /** * Retrieves a mapper. * @param the mapper type * @param type Mapper interface class * @return a mapper bound to this SqlSession */ T getMapper(Class type); /** * Retrieves inner database connection. * @return Connection */ Connection getConnection(); }
映射器的本質(zhì)是動(dòng)態(tài)代理對(duì)象
最后都是調(diào)用sqlsession接口的定義的方法完成和數(shù)據(jù)庫(kù)的交互
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/74305.html
摘要:前言嗨,小伙伴們,這篇博文將帶大家手寫(xiě),讓大家對(duì)的核心原理以及工作流程有更加深刻的理解。模塊顧名思義,就是框架配置類,用于解析配置文件加載相關(guān)環(huán)境。配置模塊這里的對(duì)框架的配置使用了簡(jiǎn)單的,主要原因還是簡(jiǎn)單易懂然后節(jié)省時(shí)間。 前言 (????)??嗨,小伙伴們,這篇博文將帶大家手寫(xiě)mybatis,讓大家對(duì)mybaits的核心原理以及工作流程有更加深刻的理解。在上篇Spring-Mybat...
摘要:的解析和運(yùn)行原理構(gòu)建過(guò)程提供創(chuàng)建的核心接口。在構(gòu)造器初始化時(shí)會(huì)根據(jù)和的方法解析為命令。數(shù)據(jù)庫(kù)會(huì)話器定義了一個(gè)對(duì)象的適配器,它是一個(gè)接口對(duì)象,構(gòu)造器根據(jù)配置來(lái)適配對(duì)應(yīng)的對(duì)象。它的作用是給實(shí)現(xiàn)類對(duì)象的使用提供一個(gè)統(tǒng)一簡(jiǎn)易的使用適配器。 MyBatis的解析和運(yùn)行原理 構(gòu)建SqlSessionFactory過(guò)程 SqlSessionFactory提供創(chuàng)建MyBatis的核心接口SqlSess...
摘要:目錄其中每個(gè)章節(jié)知識(shí)點(diǎn)都是相關(guān)連由淺入深的一步步全面分析了技術(shù)原理以及實(shí)戰(zhàn)由于文案較長(zhǎng)想深入學(xué)習(xí)以及對(duì)于該文檔感興趣的朋友們可以加群免費(fèi)獲取。這些場(chǎng)景在大量的編碼中使用,具備較強(qiáng)的實(shí)用價(jià)值,這些內(nèi)容都是通過(guò)實(shí)戰(zhàn)得來(lái)的,供讀者們參考。 前言系統(tǒng)掌握MyBatis編程技巧已經(jīng)成了用Java構(gòu)建移動(dòng)互聯(lián)網(wǎng)網(wǎng)站的必要條件 本文主要講解了Mybatis的應(yīng)用,解析了其原理,從而形成一個(gè)完整的知識(shí)...
摘要:執(zhí)行沒(méi)有,批處理不支持,將所有都添加到批處理中,等待統(tǒng)一執(zhí)行,它緩存了多個(gè)對(duì)象,每個(gè)對(duì)象都是完畢后,等待逐一執(zhí)行批處理。 Mybatis常見(jiàn)面試題 #{}和${}的區(qū)別是什么? #{}和${}的區(qū)別是什么? 在Mybatis中,有兩種占位符 #{}解析傳遞進(jìn)來(lái)的參數(shù)數(shù)據(jù) ${}對(duì)傳遞進(jìn)來(lái)的參數(shù)原樣拼接在SQL中 #{}是預(yù)編譯處理,${}是字符串替換。 使用#{}可以有效的防止...
摘要:我認(rèn)為學(xué)習(xí)框架源碼分為兩步抓住主線,掌握框架的原理和流程理解了處理思路之后,再去理解面向?qū)ο笏枷牒驮O(shè)計(jì)模式的用法目前第一步尚有問(wèn)題,需要多走幾遍源碼,加深下理解,一起加油 這篇文章我們來(lái)深入閱讀下Mybatis的源碼,希望以后可以對(duì)底層框架不那么畏懼,學(xué)習(xí)框架設(shè)計(jì)中好的思想; 架構(gòu)原理 架構(gòu)圖 showImg(https://segmentfault.com/img/remote/...
摘要:避免了幾乎所有的代碼和手動(dòng)設(shè)置參數(shù)以及獲取結(jié)果集。這個(gè)對(duì)象主要是獲取方法對(duì)應(yīng)的命令和執(zhí)行相應(yīng)操作等的處理,具體細(xì)節(jié)同學(xué)們可以抽空研究。所以這里的方法主要使用了和對(duì)象幫助我們處理語(yǔ)句集和參數(shù)的處理。 博文目標(biāo):希望大家看了這篇博文后,對(duì)Mybatis整體運(yùn)行過(guò)程有一個(gè)清晰的認(rèn)識(shí)和把握。 1.什么是 MyBatis ? MyBatis 是一款優(yōu)秀的持久層框架,它支持定制化 SQL、存儲(chǔ)過(guò)程...
閱讀 3096·2023-04-25 20:43
閱讀 1729·2021-09-30 09:54
閱讀 1600·2021-09-24 09:47
閱讀 2890·2021-09-06 15:02
閱讀 3522·2021-02-22 17:09
閱讀 1245·2019-08-30 15:53
閱讀 1448·2019-08-29 17:04
閱讀 1970·2019-08-28 18:22