接上篇
进入getConnection方法
发现是通过Transaction对象获取连接······
回顾之前的openSessionFromDataSource方法中
调用getTransactionFactoryFromEnvironment方法获取一个transactionFactory
根据配置文件中的
猜测返回的是
JdbcTransactionFactory
同时在Configuration的构造方法中可以验证这一点
JDBC对应的类型是JdbcTransactionFactory,
继续往下走。。
实例化一个JdbcTransaction对象
进入JdbcTransaction中的getConnection()方法
查看openConnection方法
看到这里总算有点熟悉了,通过dataSource获取一个jdbc connection,然后设置事务隔离级别,接着往下
这两步应该就是生成preparedStatement,并设置参数了
先看prepare方法,之前已经知道statementHandler的实例对象是RoutingStatementHandler,所以选择RountingStatementHandler的prepare方法。
唔。。。貌似使用了委托模式,看看这个delegate是个啥
也是个StatementHandler,注意到构造函数里
delegate是根据构造方法的传入的MappedStratement的statementType决定的,根据配置文件应该可以猜想到delegate是PreparedStatementHandler的实例,这里就体现了一种设计模式---委托模式,当需要处理多种statement时,这里有普通的Statement,preparedStatement,以及callable(存储过程),使用代理模式就可以只实例化一个RountingStatementHandler去处理,实际的处理由mappedStatement的类型决定实例化哪种代理statementHandler去实现,代理模式比简单的继承\接口实现有着更好的扩展性,比如在这里如果以后需要扩展出新的statementHandler,只需在RoutingStatementHandler中实例化新的代理即可
再看看prepare方法是怎么实现的(在BaseStatementHandler中)
先看看instantiateStatement(由子类实现,PreparedStatementHandler)
通过boundSql获取到真实的sql语句,然后就是jdbc传统的写法了,通过connection的preparedStatement方法获得一个statement,只不过会根据mappedStatement的一些信息做一些处理,比如根据主键的生成器,是否要返回生成的主键等,(这些都在mapper.xml中有着对应的体现)
接着看setStatementTimeout方法
没什么说的,设置超时时间
接下来的setFechSize也同理,都是基础的jdbc配置了。
现在又要往回跳了···跨度会有点大
回到SimpleExecutor的prepareStatement方法
接下来的parameterize方法,根据名字也能猜出是给preparedStatement设置参数
点进去看看(在preparedStatementHandler中)
继续跟进
看起来有点复杂,其实简单理解就是给statement设置参数(废话),注意到最后的typeHandler,mybatis会根据参数的类型来使用不同的typeHandler给statement赋值。
完成了参数的赋值后,使用statementHandler进行最后的查询了。。
进入PreparedStatmentHandler的query方法
很简单的三句代码,调用statement的execute方法执行查询。然后调用resultHandler的handleResultSet方法处理结果集
进入handleResultSets方法
这一部分代码比较复杂 关系到查询的结果集与在配置文件中设置的resultMap的映射转化。。暂时也看不大懂,不过mybatis的一个查询的流程也到此为止了,详细分析未完待续(其实是工作太忙了。。)