如果是ibatis的时代,直接通过sqlSession对象调用方法,然后执行器等后续执行;
SysRole sysRole = sqlSession.selectOne("com.honor.mybatis.mapper.SysRoleMapper.selectById", 1);mybatis的时候,我们可以不用操作sqlSession直接使用mapper接口。
SysRoleMapper sysRoleMapper = sqlSession.getMapper(SysRoleMapper.class); SysRole sysRole = sysRoleMapper.selectById(1)在MapperProxyFactory中发现这是通过jdk生成的代理对象
protected T newInstance(MapperProxy<T> mapperProxy) { return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy); } public T newInstance(SqlSession sqlSession) { final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache); return newInstance(mapperProxy); }根据对jdk动态代理的理解,这个mapper的逻辑会落在代理执行程序上(newProxyInstance的第三个参数,实现了InvocationHandler),可以看到这个类是MapperProxy,最重要就是他得invoke方法
execute方法中,下面两句就是本次执行的落点
Object param = method.convertArgsToSqlCommandParam(args); result = sqlSession.selectOne(command.getName(), param);其中第一句是将method的参数专称map对象,以便后续使用,具体规则如下
public ParamNameResolver(Configuration config, Method method) { final Class<?>[] paramTypes = method.getParameterTypes(); final Annotation[][] paramAnnotations = method.getParameterAnnotations(); final SortedMap<Integer, String> map = new TreeMap<Integer, String>(); int paramCount = paramAnnotations.length; // get names from @Param annotations for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) { if (isSpecialParameter(paramTypes[paramIndex])) { // skip special parameters continue; } String name = null; for (Annotation annotation : paramAnnotations[paramIndex]) { if (annotation instanceof Param) { hasParamAnnotation = true; name = ((Param) annotation).value(); break; } } if (name == null) { // @Param was not specified. if (config.isUseActualParamName()) { name = getActualParamName(method, paramIndex); } if (name == null) { // use the parameter index as the name ("0", "1", ...) // gcode issue #71 name = String.valueOf(map.size()); } } map.put(paramIndex, name); } names = Collections.unmodifiableSortedMap(map); }最终的结果,如果配置了@Param优先使用,否则使用参数名作为map的key(useActualParamName可以配置,默认为true),如果useActualParamName配置为false,则使用“0”,“1”作为key。 然后就是执行sqlSession的selectOne方法了 至此就从mybatis进入了itbatis,mapper接口的的作用就完了