springboot整合mybatis的整体流程

1.查询前

也就是springboot启动时做的工作

  • 实例化SqlSessionFactory
    1.构建一个DefaultSqlSessionFactory,主要作用就是维护Configuration和查询时获取DefaultSqlSession,然后通过DefaultSqlSession执行查询操作。
    2.实例化的过程中会解析mapper.xml中的各种标签封装成xxxsqlSource,保存在Configuration的mappedstatelment的sqlSource属性中。
    3.解析mapper.xml中的各种标签的过程中会对已经解析过的xml对应的mapper进行保存,保存在Configuration的mapperRegistrykonwnMappers中,key是接口全限定名,value是接口对应的MapperProxyFactory类型,保存是为了实例化mapper接口时能获取到mapper及对应的MapperProxyFactory(作用是实例化时创建mapper接口的代理类MapperProxy)
    4.mybatis-plus这种,不写xml的,会解析baseMapper中的方法,根据实体类信息等,生成sql。
  • 实例化SqlSessionTemplate
    1.构建一个SqlSessionTemplate,用来在实例化mapper接口时获取mapper以及在执行查询时获取sqlsession。SqlSessionTemplate里维护DefaultSqlSessionFactory,比如获取Configuration就会通过SqlSessionTemplate获取DefaultSqlSessionFactory然后在获取Configuration,查询时获取和数据库关联的sqlsession,也是通过SqlSessionTemplate维护的DefaultSqlSessionFactory的opensession方法获取到的,类型是DefaultSqlSession
  • 实例化mapper
    扫描mapper文件变成BeanDefinition(@Mapper和@MapperScan),变成BeanDefinition后会把BeanDefinition中的BeanClass属性设置为MapperFactoryBean类型,以便在spring容器实例化对象时,对mapper接口也进行实例化,也就是生成对应的代理类MapperProxy,用以执行mapper的增删改查方法。
    实例化完这三个对象,springboot就可以等待前端调用接口然后执行mapper方法进行增删改查了。

2.查询时

也就是前端调接口,然后调service,然后调mapper的方法时做的工作

  • 解析传参
    当通过servcie调用mapper接口的方法时,会调用代理对象MapperProxy的invoke 方法。然后会调用MapperMethod的invoke 方法。在MapperMethod的invoke 方法会调用MapperMethod的execute方法。在这个方法中会调用SqlSessionTemplate的对应方法执行查询,在调用之前会进行方法参数解析,最终方法是ParamNameResolver类的getNamedParams,得到一个map,key是参数名,value是参数值。
  • 获取最终的sql
    mapper.xml中的sql会在MybatisAutoConfiguration中构建SqlSessionFactory时得到解析,如果有where if之类的标签会被解析成DynamicSqlSource,如果是普通的查询语句(select * from departments where department_id=#{depId})则会被解析成RawSqlSource,这个属性会被存在configuration的mappedstatements属性中,属性名称为sqlSource。然后执行查询时,会从sqlSource中拿到对应的原始sql,然后再进行解析,也就是把方法调用时的传参拼接到sql中以及拼接where if这种动态标签,最终得到完整的sql。方法就是对应的SqlSource类的getBoundsql方法。这里DynamicSqlSource类的getBoundsql方法也会调用RawSqlSource的getBoundSql方法。

3.查询后

也就是查询出结果后做的工作

  • 解析返回值
    关键类DefaultResultSetHandler,基本逻辑都是在这个类实现的。
    关键类ResultSetWrapper,保存要映射的字段集合和查询出的数值的字节数组
  • 1.DefaultResultSetHandler类的handleResultSets方法,先拿到需要映射的字段集合,封装在ResultSetWrapper中,然后再获取一个resultmap类型的集合,每个resultmap保存需要映射的类型,如果有resultmap标签则会封装到resultmappings属性中。
  • 2.DefaultResultSetHandler类的handleResultSet方法,调用handleRowValues方法处理结果集放到multipleResults中。
  • 3.DefaultResultSetHandler类的handleRowValues方法,分别处理嵌套映射和非嵌套映射。
  • 4.非嵌套映射,handleRowValuesForSimpleResultMap方法,遍历映射每行数据,调用getRowValue方法。没加resultmap或者resultmap中没做映射的字段调用applyAutomaticMappings方法,resultmap中映射的字段调用applyPropertyMappings方法。具体方法就是调用对应字段类型的typeHandler从字节数组中拿到数据进行转换。所有对应字段值的字节数组在ResultSetWrapperresultset属性中。
  • 5.嵌套映射,handleRowValuesForNestedResultMap方法,遍历映射每行数据,调用重载的getRowValue方法,没加resultmap或者resultmap中没做映射的字段调用applyAutomaticMappings方法,resultmap中映射的字段调用applyPropertyMappings方法,嵌套映射的字段调用applyNestedResultMappings方法。而applyNestedResultMappings会再次调用getRowValue方法解析每行数据,逻辑和非嵌套映射相同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值