mybatis中session.getMapper方法源码分析

 

0开始代码AuthorMapper mapper = session.getMapper(AuthorMapper.class);

1 DefaultSqlSession类

 

@Override

public <T> T getMapper(Class<T> type) {

//最后会去调用MapperRegistry.getMapper

return configuration.<T>getMapper(type, this);

}

 

2 Configuration类

 

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {

return mapperRegistry.getMapper(type, sqlSession);

}

3 MapperRegistry类

 

//返回代理类

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);

}

}

MapperProxyFactory<T> 类

public T newInstance(SqlSession sqlSession) {

final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);

return newInstance(mapperProxy);

}

 

protected T newInstance(MapperProxy<T> mapperProxy) {

//用JDK自带的动态代理生成映射器

return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);

}

 

MapperProxy类

public class MapperProxy<T> implements InvocationHandler, Serializable{

 

public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) {

this.sqlSession = sqlSession;

this.mapperInterface = mapperInterface;

this.methodCache = methodCache;

}

}

 

 

 

//去缓存中找MapperMethod

private MapperMethod cachedMapperMethod(Method method) {

MapperMethod mapperMethod = methodCache.get(method);

if (mapperMethod == null) {

//找不到才去new

mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration());

methodCache.put(method, mapperMethod);

}

return mapperMethod;

}

 

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

//代理以后,所有Mapper的方法调用时,都会调用这个invoke方法

//并不是任何一个方法都需要执行调用代理对象进行执行,如果这个方法是Object中通用的方法(toString、hashCode等)无需执行

if (Object.class.equals(method.getDeclaringClass())) {

try {

return method.invoke(this, args);

} catch (Throwable t) {

throw ExceptionUtil.unwrapThrowable(t);

}

}

//这里优化了,去缓存中找MapperMethod

final MapperMethod mapperMethod = cachedMapperMethod(method);

//执行

return mapperMethod.execute(sqlSession, args);

}

MapperMethod类

 

 

//执行

public Object execute(SqlSession sqlSession, Object[] args) {

Object result;

//可以看到执行时就是4种情况,insert|update|delete|select,分别调用SqlSession的4大类方法

if (SqlCommandType.INSERT == command.getType()) {

Object param = method.convertArgsToSqlCommandParam(args);

result = rowCountResult(sqlSession.insert(command.getName(), param));

} else if (SqlCommandType.UPDATE == command.getType()) {

Object param = method.convertArgsToSqlCommandParam(args);

result = rowCountResult(sqlSession.update(command.getName(), param));

} else if (SqlCommandType.DELETE == command.getType()) {

Object param = method.convertArgsToSqlCommandParam(args);

result = rowCountResult(sqlSession.delete(command.getName(), param));

} else if (SqlCommandType.SELECT == command.getType()) {

if (method.returnsVoid() && method.hasResultHandler()) {

//如果有结果处理器

executeWithResultHandler(sqlSession, args);

result = null;

} else if (method.returnsMany()) {

//如果结果有多条记录

result = executeForMany(sqlSession, args);

} else if (method.returnsMap()) {

//如果结果是map

result = executeForMap(sqlSession, args);

} else {

//否则就是一条记录

Object param = method.convertArgsToSqlCommandParam(args);

result = sqlSession.selectOne(command.getName(), param);

}

} else {

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;

}

 

 

 

 

 

转载于:https://my.oschina.net/iioschina/blog/1860215

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值