第一步 创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
inputStream来源:从xml配置文件读取
InputStream inputStream = Resources.getResourceAsStream(“configuration.xml”);
怎么解析配置文件,获取内容呢?
//创建解析器解析
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
//parse 解析 parser.parse()返回全局配置信息类configuration
build(parser.parse());
configuration也可以手动添加mapper
sqlSession.getConfiguration().addMapper(cls);
第二步 获取SqlSession对象
SqlSession = sqlSessionFactory.openSession(true);
第三步 获取Mapper对象
T mapper = sqlSession.getMapper(type);
此处获取的mapper对象是代理对象
//(实际configuration保存或新增mapper信息时)
//在MapperRegistry中添加mapper的時候会存MapperProxyFactory代理工厂类
knownMappers.put(type, new MapperProxyFactory<>(type));
//当getMapper执行的时候 实际执行代码如下
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
//从map中获取MapperProxyFactory代理工厂类
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
try {
//通过动态代理获取代理mapper类
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
.........
.........
//MapperProxyFactory 类如下
public class MapperProxyFactory<T> {
private final Class<T> mapperInterface;
private final Map<Method, org.source.ibatis.binding.MapperMethod> methodCache = new ConcurrentHashMap<>();
public MapperProxyFactory(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
public Class<T> getMapperInterface() {
return mapperInterface;
}
public Map<Method, MapperMethod> getMethodCache() {
return methodCache;
}
@SuppressWarnings("unchecked")
protected T newInstance(MapperProxy<T> mapperProxy) {
//通过JDK动态代理生成一个Mapper的代理
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
}
.
第四步 执行mapper增删改查方法
如果mapper中有一方法叫selectUserById
mapper.selectuserById(1);
那具体是如何执行的呢?
1、首先我们看下MapperProxy代理类
//代理类的参数
private final SqlSession sqlSession;
private final Class<T> mapperInterface;
private final Map<Method, MapperMethod> methodCache;
2、再看下invoke方法
@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);
}
//把当前请求放入一个HashMap中,下次如果同样的方法进来直接返回
final MapperMethod mapperMethod = cachedMapperMethod(method);
//具体执行并返回结果
return mapperMethod.execute(sqlSession, args);
}
总结
1、创建SqlSessionFactory对象
2、获取SqlSession对象
3、获取代理对象
4、执行增删改查方法