例:
package com.example.demo.service;
import com.example.demo.dao.UserDao;
import com.example.demo.domain.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@Slf4j
public class UserService {
@Autowired
private UserDao userDao;
public List getUser(){
List userList = userDao.getUser();
log.info("查询出来的用户信息,{}",userList.toString());
return userList;
}
}
当userService中的getUser方法执行的时候,userDao.getUser()是怎么走的?
1、在springboot项目启动时,加载mybatis相关配置,同事会在MapperRegister中保存mapper的代理类,在创建UserService bean的时候,需要注入userDao类,但userDao类是一个Interface类型,所以在注入的时候其实是注入的一个mapper代理类,也就是MapperProxy类
2、当执行userDao.getUser()时,会走MapperProxy中的invoke方法,最终是通过mapperMethod.execute(sqlSession. args)
3、进入MapperMethod的execute方法,会根据select、insert、update 来走不同的方法
4、本次测试时走的是SELECT 的case,在该case中会判断是否有返回值(返回值得处理器),因本次查询返回值是一个list,所以会走executeForMany()
5、进入到executeForMany中,参数是SQLSessionTemplate和null,进行处理后,进入到sqlsession.
6、该selectList方法调用的是SQLSessionTemplate类的selectList
7、进入到sqlSessionProxy(该代理类其实就是DefaultSqlSession)的selectList方法中,参数statement就是mapper方法,paramter为null,
在selectList方法中,会从Configuration对象中获取statement对应的对象,然后通过执行器executor的query来执行
8、进入到executor的query方法中,当前的executor默认是CachingExecutor
9、进入到CachingExecutor的query方法中,在当前方法中会先获取相应的BindSql,然后会创建cache
10、进入到createCacheKey方法中,该方法其实是BaseExecutor中的方法
11、创建完成之后,会调用query方法,在方法中,会先查询cache,没有再调用delegate的query方法
12、delegate是BaseExecutor(执行器),在当前方法中也会先从缓存中查询,查询不到在从库中查询
13、进入queryFormDatabase方法中,在方法中会将之前创建的cacheKey保存到localCache中,然后在执行doQuery方法
14、进入到doQuery方法中,也就是默认的simpleExecutor中
15、进入到configuration.newStatementHandler中(默认statement为preparedStatement)
16、返回preparestatementHandler处理器,然后调用prepareStatement方法
18、在方法中会通过prepareStatement的execute来查询数据库,完毕后,会在handeler中处理返回数据
19、处理返回数据是在DefaultResultSetHandler类中
20、处理完成后悔返回一个list
posted @ 2019-03-06 18:24 犇犇丶 阅读(...) 评论(...) 编辑 收藏