初看Mybatis 源码 (三) SQL是怎么执行的

前面说到Java动态代理,Mybatis通过这种方式实现了我们通过getMapper方式得到的Dao接口,可以直接通过接口的没有实现的方法来执行sql。

AuthUserDao mapper = session.getMapper(AuthUserDao.class);

getMapper方法到底做了什么。跟踪getMapper方法,进入到 MapperProxyFactory 类的 newInstance(SqlSession sqlSession) 方法。

@SuppressWarnings(“unchecked”) 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); }

看过上一篇的例子,我们知道。最后是通过Proxy.newProxyInstance 来实现切入sql的。他的实现在MapperProxy的 invoke 方法里面。看下invoke方法:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (Object.class.equals(method.getDeclaringClass())) {return method.invoke(this, args);}final MapperMethod mapperMethod = cachedMapperMethod(method);return mapperMethod.execute(sqlSession, args); }

简单来说,在invoke里面做了如下事情:

1. 通过我们调用的方法,如本例中的 selectAuthUserByName ,,接口名来组合成语句。本例中是 com.mybatis.dao.AuthUserDao.selectAuthUserByName 。其实使用过sqlSession的selectOne(String statmet)之类的语句都知道。这个可以唯一定位到我们在sql映射文件中配置的sql语句

2. 通过返回值类型,定位到的语句的类型。确定最后应该执行的方法。是执行查询、删除、添加、修改等等。

看下mybatis的是如何做的:

public Object execute(SqlSession sqlSession, Object[] args) { Object result; 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()) {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; }耿耿于怀着过去和忐忑不安着未来的人,也常常挥霍无度着现在。

初看Mybatis 源码 (三) SQL是怎么执行的

相关文章:

你感兴趣的文章:

标签云: