Spring mybatis交互时序图
ContextLoadListener启动
MapperScannerConfigure实现了* ,其postProcessBeanDefinitionRegistry方法被调用,这个方法里有扫描包含mapper接口的动作,并动态创建bean,这个bean的名称是mapper接口的名称,class属性是org.mybatis.spring.mapper.MapperFactoryBean,同时它是Autowired
Spring对有Autowired注释的bean进行自动注入,这个过程中,需要对bean进行实例化
看看MapperFactoryBean中是怎样实例化bean的。
可见MapperFactoryBean是返回一个MapperProxy的代理对象,这是一个mapper接口的变量就是引用了一个MapperProxy的对象
Spring启动后,mybatis框架是怎样将mapper接口的方法绑定到具体的配置文件中的sql语句呢?一个请求过来,改请求涉及到数据查询,过程如下:
UserMapper的userMapper变量引用MapperProxy对象
执行queryAll方法后,由于是动态代理,会执行MapperProxy类的invoke方法,这个方法里就可以执行方法,并返回结果。
详细的看mapperMethod和mapperMethod.execute()
com.dao.UserMapper.queryAll
JDBC连接和执行过程
1.加载驱动
2.通过驱动建立连接
3.通过连接创建stateMent
4.执行stateMent
5.解析result
Mybatis
DataSourceUtil中通过dataSource.getConnetion()获取连接
从dbcp数据源的数据库连接池中获取连接
需要注意的是,第一次sql语句执行时连接数据库需要初始化,并建立数据库连接池,以后sql语句执行时,从数据库连接池中获取连接。
关于DataSource,目前常用的有三种
1.使用org.springframework.jdbc.datasource.DriverManagerDataSource
2.使用org.apache.commons.dbcp.BasicDataSource
3.使用com.mchange.v2.c3p0.ComboPooledDataSource
第一中没有数据库连接池的功能,不推荐;第二种和第三中都有数据库连接池的功能,Spring推荐使用第二种;据说dbcp比c3p0性能稍好,但是稳定性不如后者,后者在数据库重启和网络故障的情况下可以自动重连。
dbcp:
c3p0:
(1800s=30m)
spring使用哪种dataSource通过applicationContext.xml进行简单的配置即可,这些数据源都是实现了javax.sql.DataSource接口的类,DateSource接口主要提供getConnection()方法。
mybatis动态代理
看看MapperProxy类中的invoke方法是怎么执行sql语句的:
userMapper=new Proxy(),当执行userMapper.queryAll()时,会执行 Proxy类的query方法,这个方法会执行MapperProxy类的invoke函数,proxy参数是生成的 Proxy类的对象,是通过字节码操作技术在运行时生成的,可以通过反射获取proxy实现的接口,method参数是 Proxy中的m1,MapperMethod里有一个org.apache.ibatis.session.Configuration类型config对象,这个对象里有一个map类型的mappedStatements变量,存储key,value为< MappedStatement obj.id, MappedStatement obj> ,obj.id为namespace的值拼接上sql的id值,这个id对应的value对象为MappedStatement,MappedStatement里面包含了sql语句。
Proxy中生成动态代理类的方法如下: