1:mybatis首先构建SqlSessionFactory,这个工厂主要就是初始化与数据库操作有关的上下文信息。会收集xml中的配置,如environment,datasource,transactionManager,setting配置等等,而默认构建出来的是DefaultSqlSessionFactory。
在mybatis最重要的配置节点就是和sql执行相关的mappers配置节点:
mybatis的mappers节点下可配置mapper和package:
(1)如果配置package首先会扫描接口,将接口中的每一个方法扫描到,并获取注解,“接口方法的全名称”和对应的“mappedStatement”对象(mappedStatement实际就是sql配置节点各个属性封装成的java对象)放入strictMap中。
(2)如果配置了mapper则,resources属性,url属性,class属性只能选择一个,因为源码只允许写一个,否则会抛出异常。
mybatis实际生产sql的时候是有两种方式,一个是动态sql一个是静态sql:
(1)动态sql中mybatis解析器会有一个标识,如果开头是“${”,结尾是“}”,则认为是动态sql。
(2)如果是静态sql那么加入,mappedStatement中的sqlResource就是将“#{}”替换成了“?”占位符的sql样子。
2:当SqlSessionFactory创建完成以后就会通过openSession方法获得一个session,默认情况下也是获取了一个DefaultSqlSession,er该sqlsession并没有数据库打开链接之类的行为,而是存储了一些信息,比如“sql执行器”,“配置信息configuration”,以及事务是否自动提交。
tx =transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); final Executor executor = configuration.newExecutor(tx, execType); return new DefaultSqlSession(configuration, executor, autoCommit);
3:核心方法通过getMapper获取实现了接口的代理对象,通过jdk动态代理方式。
public <T> T getMapper(Class<T> type, SqlSession sqlSession) { final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type); if (mapperProxyFactory == null) { throw new BindingException("Type " + type + " is not known to the MapperRegistry."); } try { return mapperProxyFactory.newInstance(sqlSession); } catch (Exception e) { throw new BindingException("Error getting mapper instance. Cause: " + e, e); } } protected T newInstance(MapperProxy<T> mapperProxy) { return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy); }
4:MapperProxy是动态代理的核心方法它继承自InvocationHandler,而获取对应的Mapper类以后实际执行的方法就是MapperProxy的invok方法
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { if (Object.class.equals(method.getDeclaringClass())) { return method.invoke(this, args); } else if (isDefaultMethod(method)) { return invokeDefaultMethod(proxy, method, args); } } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t); } final MapperMethod mapperMethod = cachedMapperMethod(method); return mapperMethod.execute(sqlSession, args); } @UsesJava7 private Object invokeDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable { final Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class .getDeclaredConstructor(Class.class, int.class); if (!constructor.isAccessible()) { constructor.setAccessible(true); } final Class<?> declaringClass = method.getDeclaringClass(); return constructor .newInstance(declaringClass, MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED | MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC) .unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args); }
原文:https://www.cnblogs.com/zzq-include/p/12013792.html