wordpress网站域名解析,wordpress搭建教育平台,排名网站却搜不到,贴心的合肥网站建设转载自 mybatis源码阅读(四)#xff1a;mapper(dao)实例化
在开始分析之前#xff0c;先来了解一下这个模块中的核心组件之间的关系#xff0c;如图#xff1a; 1.MapperRegistryMapperProxyFactory
MapperRegistry是Mapper接口及其对应的代理对象工程的注册中心mapper(dao)实例化
在开始分析之前先来了解一下这个模块中的核心组件之间的关系如图 1.MapperRegistryMapperProxyFactory
MapperRegistry是Mapper接口及其对应的代理对象工程的注册中心Configuration是Mybatis全局性的配置对象在初始化的过程中所有配置信息会被解析成相应的对象并记录到Configuration对象中这在之前也详细介绍了。Configuration.mapperRegistry字段记录当前使用的MapperRegistry对象
public class MapperRegistry {// 全局唯一的配置对象其中包含了所有的配置信息private final Configuration config;// 记录Mapper接口与对应MapperProxyFactory之间的关系private final MapClass?, MapperProxyFactory? knownMappers new HashMapClass?, MapperProxyFactory?();
}private void bindMapperForNamespace() {String namespace builderAssistant.getCurrentNamespace();if (namespace ! null) {Class? boundType null;try {boundType Resources.classForName(namespace);} catch (ClassNotFoundException e) {//ignore, bound type is not required}if (boundType ! null) {if (!configuration.hasMapper(boundType)) {// Spring may not know the real resource name so we set a flag// to prevent loading again this resource from the mapper interface// look at MapperAnnotationBuilder#loadXmlResourceconfiguration.addLoadedResource(namespace: namespace);configuration.addMapper(boundType);}}}
}
public T void addMapper(ClassT type) {mapperRegistry.addMapper(type);
}
public T void addMapper(ClassT type) {if (type.isInterface()) {//是否为接口if (hasMapper(type)) {//是否已经加载过throw new BindingException(Type type is already known to the MapperRegistry.);}boolean loadCompleted false;try {knownMappers.put(type, new MapperProxyFactoryT(type));// 注解处理MapperAnnotationBuilder parser new MapperAnnotationBuilder(config, type);parser.parse();loadCompleted true;} finally {if (!loadCompleted) {knownMappers.remove(type);}}}
}
在需要执行SQL语句时会先获取mapper借口的代理对象例如
Test
public void findUserById() {SqlSession sqlSession getSessionFactory().openSession();UserDao userMapper sqlSession.getMapper(UserDao.class);User user userMapper.findUserById(1);Assert.assertNotNull(没找到数据, user);
}
DefaultSqlSession类中方法如下实际上是通过JDK动态代理生成的代理对象
public T T getMapper(ClassT type) {return this.configuration.getMapper(type, this);
}
Configuration类方法如下
public T T getMapper(ClassT type, SqlSession sqlSession) {return mapperRegistry.getMapper(type, sqlSession);
}
MapperRegistry类中方法如下
SuppressWarnings(unchecked)
public T T getMapper(ClassT type, SqlSession sqlSession) {//查找指定type对象的MapperProxyFactory对象final MapperProxyFactoryT mapperProxyFactory (MapperProxyFactoryT) knownMappers.get(type);if (mapperProxyFactory null) {//如果为空抛出异常throw new BindingException(Type type is not known to the MapperRegistry.);}try {// 创建实现了type接口的代理对象return mapperProxyFactory.newInstance(sqlSession);} catch (Exception e) {throw new BindingException(Error getting mapper instance. Cause: e, e);}
}
MapperProxyFactory主要负责创建代理对象
SuppressWarnings(unchecked)
protected T newInstance(MapperProxyT mapperProxy) {return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}public T newInstance(SqlSession sqlSession) {final MapperProxyT mapperProxy new MapperProxyT(sqlSession, mapperInterface, methodCache);return newInstance(mapperProxy);
}
2.MapperProxy
MapperProxy实现了InvocationHandler接口对动态代理的可以先去了解这篇文章https://my.oschina.net/u/3737136/blog/1786175
public class MapperProxyT implements InvocationHandler, Serializable {private static final long serialVersionUID -6424540398559729838L;// 记录关联的SQLSession对象private final SqlSession sqlSession;// mapper接口对应的class对象private final ClassT mapperInterface;private final MapMethod, MapperMethod methodCache;public MapperProxy(SqlSession sqlSession, ClassT mapperInterface, MapMethod, MapperMethod methodCache) {this.sqlSession sqlSession;this.mapperInterface mapperInterface;this.methodCache methodCache;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {try {// 如果目标方法是Object类继承来的直接调用目标方法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);}// 从缓存中获取MapperMethod 对象,如果没有就创建新的并添加final MapperMethod mapperMethod cachedMapperMethod(method);// 执行sql 语句return mapperMethod.execute(sqlSession, args);}}
3.MapperMethod
MapperMethod中封装了Mapper接口中对应方法的信息以及对应SQL语句的信息
public class MapperMethod {// 记录SQL语句的名称和类型private final SqlCommand command;// mapper接口中对应方法的相关信息private final MethodSignature method;public MapperMethod(Class? mapperInterface, Method method, Configuration config) {this.command new SqlCommand(config, mapperInterface, method);this.method new MethodSignature(config, mapperInterface, method);}public Object execute(SqlSession sqlSession, Object[] args) {Object result;switch (command.getType()) {case INSERT: {Object param method.convertArgsToSqlCommandParam(args);result rowCountResult(sqlSession.insert(command.getName(), param));break;}case UPDATE: {Object param method.convertArgsToSqlCommandParam(args);result rowCountResult(sqlSession.update(command.getName(), param));break;}case DELETE: {Object param method.convertArgsToSqlCommandParam(args);result rowCountResult(sqlSession.delete(command.getName(), param));break;}case SELECT:if (method.returnsVoid() method.hasResultHandler()) {// 处理返回值为void ,ResultSet 通过ResultHand处理的方法executeWithResultHandler(sqlSession, args);result null;} else if (method.returnsMany()) {// 处理返回值为集合或者数组的方法result executeForMany(sqlSession, args);} else if (method.returnsMap()) {// 处理返回值为map的方法result executeForMap(sqlSession, args);} else if (method.returnsCursor()) {// 处理返回值为cursor的方法result executeForCursor(sqlSession, args);} else {// 处理返回值为单一对象的方法Object param method.convertArgsToSqlCommandParam(args);result sqlSession.selectOne(command.getName(), param);}break;case FLUSH:result sqlSession.flushStatements();break;default:throw new BindingException(Unknown execution method for: command.getName());}if (result null method.getReturnType().isPrimitive() !method.returnsVoid()) {throw new BindingException(Mapper method command.getName() attempted to return null from a method with a primitive return type ( method.getReturnType() ).);}return result;}
}