Mybatis开发 – SqlSession创建Mapper

1.Mybatis中Mapper的使用 Mybatis除了使用SqlSession直接执行Mapper配置文件中的方法外,还可以生成Mapper

1.Mybatis中Mapper的使用

Mybatis除了使用SqlSession直接执行Mapper配置文件中的方法外,还可以生成Mapper接口的对象,通过Mapper对象调用接口方法也可以执行数据库操作。

在获得SqlSession之后,通过getMapper方法可以获得Mapper接口的实例,传入的参数是对应Mapper的class对象

public static void main(String[] args) {
	...
	session = factory.openSession();
	MybatisUserMapper mybatisUserMapper = session.getMapper(MybatisUserMapper.class);
	user = mybatisUserMapper.select(3);
	...
}

2.SqlSession获取Mapper

从SqlSession的创建过程中了解到SqlSession的实例是DefaultSqlSession

查看DefaultSqlSession的getMapper方法,方法中实际是通过Configuration的getMapper方法获得Mapper对象,传入的参数是Mapper的class类型和SqlSession的引用

Configuration是XMLConfigBuilder解析Mybatis配置文件得到的

    public <T> T getMapper(Class<T> type) {
        return this.configuration.getMapper(type, this);
    }

3.Configuration中获取Mapper

查看Configuration的getMapper方法,方法中通过mapperRegistry对象的getMapper方法获取Mapper对象

    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        return this.mapperRegistry.getMapper(type, sqlSession);
    }

mapperRegistry是MapperRegistry的对象,它在Configuration的构造方法中进行初始化

protected final MapperRegistry mapperRegistry;

public Configuration() {
        ...
        this.mapperRegistry = new MapperRegistry(this);
        ...
}

4.MapperRegistry中获取Mapper

MapperRegistry构造方法中给Configuration对象进行赋值,它还有另一个Map对象的属性knownMappers

public class MapperRegistry {
    private final Configuration config;
    private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap();

    public MapperRegistry(Configuration config) {
        this.config = config;
    }
}

在MapperRegistry的getMapper方法中,通过传入的Mapper接口的class对象到knownMappers中获取对应的MapperProxyFactory对象

然后通过MapperProxyFactory的newInstance方法创建对应的接口的实例

	public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
        if (mapperProxyFactory == null) {
            throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
        } else {
            try {
                return mapperProxyFactory.newInstance(sqlSession);
            } catch (Exception var5) {
                throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
            }
        }
    }

5.MapperProxyFactory中生成Mapper对象

MapperProxyFactory的newInstance方法中,首先创建一个MapperProxy对象,然后调用newInstance(MapperProxy)方法创建Mapper对象

public class MapperProxyFactory<T> {
	...
    public T newInstance(SqlSession sqlSession) {
        MapperProxy<T> mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);
        return this.newInstance(mapperProxy);
    }
	...
}

MapperProxy实现InvocationHandler接口,是Java动态代理中的代理类,在调用对象的方法的时候会回调invoke方法

public class MapperProxy<T> implements InvocationHandler, Serializable {
	...
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            return Object.class.equals(method.getDeclaringClass()) ? method.invoke(this, args) : this.cachedInvoker(method).invoke(proxy, method, args, this.sqlSession);
        } catch (Throwable var5) {
            throw ExceptionUtil.unwrapThrowable(var5);
        }
    }
	...
}

newInstance(MapperProxy)方法中使用动态代理模式创建Mapper实例

public class MapperProxyFactory<T> {
	...
    protected T newInstance(MapperProxy<T> mapperProxy) {
        return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
    }
	...
}

6.总结

SqlSession中获取Mapper实际上是通过SqlSession的configuration对象来获取,在Configuration类中有一个MapperRegistry对象,MapperRegistry中有一个knownMappers集合对象,里面存储了Mapper的class对象和MapperProxyFactory的对应关系,通过Mapper的class对象可以从集合中获取对应的MapperProxyFactory对象,在MapperProxyFactory中通过动态代理的模式来创建Mapper的实例

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/8236.html

(0)
上一篇 2023年 4月 21日 下午8:51
下一篇 2023年 4月 21日 下午8:51

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信