上一篇章我们主要分析了mybatis的初始化工作,包括解析mapper.xml,扫描mapper接口,为每个mapper接口动态创建实现类,并且创建出对象,本篇主要分析一个mapper的方法具体执行过程。
我们知道为每个mapper动态创建实现类是使用了jdk的动态代理,以下面这个mapper为例,
public interface ActivityMapper { int insert(Activity record); Activity selectByPrimaryKey(String id); int updateByPrimaryKeySelective(Activity record); }我们将动态代理类输出出来
public final class $Proxy26 extends Proxy implements ActivityMapper { private static Method m5; private static Method m3; private static Method m1; private static Method m0; private static Method m4; private static Method m2; public $Proxy26(InvocationHandler paramInvocationHandler) { super(paramInvocationHandler); } public final Activity selectByPrimaryKey(String paramString) { try { return (Activity) this.h.invoke(this, m5, new Object[]{paramString}); } catch (Error | RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int insert(Activity paramActivity) { try { return ((Integer) this.h.invoke(this, m3, new Object[]{paramActivity})).intValue(); } catch (Error | RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int updateByPrimaryKeySelective(Activity paramActivity) { try { return ((Integer) this.h.invoke(this, m4, new Object[]{paramActivity})).intValue(); } catch (Error | RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String toString() { try { return (String) this.h.invoke(this, m2, null); } catch (Error | RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final boolean equals(Object paramObject) { try { return ((Boolean) this.h.invoke(this, m1, new Object[]{paramObject})).booleanValue(); } catch (Error | RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int hashCode() { try { return ((Integer) this.h.invoke(this, m0, null)).intValue(); } catch (Error | RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } static { try { m5 = Class.forName("com.fengjr.prizecenter.dao.ActivityMapper").getMethod("selectByPrimaryKey", new Class[]{Class.forName("java.lang.String")}); m3 = Class.forName("com.fengjr.prizecenter.dao.ActivityMapper").getMethod("insert", new Class[]{Class.forName("com.fengjr.prizecenter.model.Activity")}); m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")}); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m4 = Class.forName("com.fengjr.prizecenter.dao.ActivityMapper").getMethod("updateByPrimaryKeySelective", new Class[]{Class.forName("com.fengjr.prizecenter.model.Activity")}); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); } catch (NoSuchMethodException localNoSuchMethodException) { throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); } catch (ClassNotFoundException localClassNotFoundException) { throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); } } }
执行selectByPrimaryKey的时候,执行了下面这个方法
this.h.invoke(this, m3, new Object[]{paramActivity}));
这个h是什么?根据上一篇文章,h是MapperProxy
我们看下这个invoke方法
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 ExceptionUtil.unwrapThrowable(t); } } final MapperMethod mapperMethod = cachedMapperMethod(method); return mapperMethod.execute(sqlSession, args);
这个execute会执行到SqlSessionTemplate的下面这个方法
public <T> T selectOne(String statement, Object parameter) { return this.sqlSessionProxy.selectOne(statement, parameter); }又一个动态代理,我靠!!!mybatis的作者是有多喜欢动态代理。。。。。无语啊
我们来看下这个动态代理对象的结构
按照我们对动态代理对了解,执行代理对象对方法,会执行到h.invoke
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
SqlSession sqlSession = SqlSessionUtils.getSqlSession(SqlSessionTemplate.this.sqlSessionFactory, SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator); Object unwrapped; try { Object t = method.invoke(sqlSession, args);
if(!SqlSessionUtils.isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) { sqlSession.commit(true); } unwrapped = t; } catch (Throwable var11) { unwrapped = ExceptionUtil.unwrapThrowable(var11); if(SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) { SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory); sqlSession = null; DataAccessException translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException)unwrapped); if(translated != null) { unwrapped = translated; } } throw (Throwable)unwrapped; } finally { if(sqlSession != null) { SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory); } } return unwrapped; }
method.invoke 执行到DefaultSqlSession的下面这个方法
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) { try { MappedStatement ms = configuration.getMappedStatement(statement); List<E> result = executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER); return result; } catch (Exception e) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } }