Mybatis(二)

在上篇中,是接口类生成对应的映射器代理,再在代理中完成对应的接口调用。本篇中,提供包路径的扫描和注册,将注册生成的类与代理器对象插入进Map中,进行调用,并对session进行规范化处理。

注册器机制以及实现

注册器机制有两个方法,一个是获取对应的MapperProxyFactory对象,另一个是扫描对应的接口类,注册成MapperProxyFactory进行调用,这个注册器机制在以后的工程中可以去进行借鉴。

public class MapperRegistry {

    /*
    将映射代理添加到HashMap中
     */
    private final Map<Class<?>, MapperProxyFactory<?>> mapperMap = new HashMap<>();

    //相当于去进行重新获取
    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) mapperMap.get(type);
        if (mapperProxyFactory == null) {
            throw new RuntimeException("原有的Mapper未包含对应资源,确认清楚");
        }
        try {
            return mapperProxyFactory.newInstance(sqlSession);
        } catch (Exception e) {
            throw new RuntimeException("重新获取mapper时失败");
        }
    }
    
    public void addMappers(String packageName) {
        //从包中读出类
        Set<Class<?>> classes = ClassScanner.scanPackage(packageName);
        classes.stream().forEach(a ->
                addMapper(a)
        );
    }

    private void addMapper(Class<?> a) {
        //只对接口生效
        if (a.isInterface()) {
            if (mapperMap.containsKey(a)) {
                throw new RuntimeException("该接口已经扫描加载,再确定下机制是否存在问题");
            }
            mapperMap.put(a, new MapperProxyFactory<>(a));
        }
    }
}

addMappers是生成Map,getMapper是获取对应的接口代理器。

代理器工厂的实现

工厂实现还是按照一的实现去进行处理

public class MapperProxyFactory<T> {

    private final Class<T> mapperInterface;

    public MapperProxyFactory(Class<T> mapperInterface){
        this.mapperInterface = mapperInterface;
    }

    public T newInstance(SqlSession sqlSession){
        final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface);
        return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, mapperProxy);
    }
}

代理Mapper的实现

先上代码

public class MapperProxy<T> implements InvocationHandler, Serializable {

    private static final long serialVersionUID = -6424540398559729838L;

    private SqlSession sqlSession;

    private Class<T> mapperInterface;

    public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface){
        this.sqlSession = sqlSession;
        this.mapperInterface = mapperInterface;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (Object.class.equals(method.getDeclaringClass())){
            return method.invoke(method, this);
        }
        return sqlSession.selectOne(method.getName(), args);
    }
}

与一相比,对sqlSession进行对应的封装

sqlSession的封装与使用

接口封装——sqlSession与sqlSessionFactory的接口封装

public interface SqlSessionFactory {

    /**
     * 打开一个session
     * @return
     */
    SqlSession openSession();

}
/**
 * 表示当前对象可以被关闭
 */
public interface SqlSession extends Closeable {
    
    /**
     * 根据指定的SqlId获取对应的封装对象
     * @param statement
     * @param <T>
     * @return
     */
    <T> T selectOne(String statement);
    
    /**
     * 根据指定的sqlId获取对应的封装对象,但允许向封装对象中塞入对应的参数
     * @param statement
     * @param parameter
     * @param <T>
     * @return
     */
    <T> T selectOne(String statement, Object parameter);
    
    /**
     * 从session中获取对应的映射器
     * @param type
     * @param <T>
     * @return
     */
    <T> T getMapper(Class<T> type);
}

对sqlSession和sqlSeesionFactory进行实现

public class DefaultSqlSession implements SqlSession {

    private MapperRegistry mapperRegistry;

    public DefaultSqlSession(MapperRegistry mapperRegistry){ this.mapperRegistry = mapperRegistry;}

    @Override
    public <T> T selectOne(String statement) {
        return (T) ("你被代理了" + statement);
    }

    @Override
    public <T> T selectOne(String statement, Object parameter) {
        return (T) ("你被代理了" + statement + "且输入的入参是" + parameter.toString());
    }

    /*
    通过getMapper的映射,获取对应的映射mapper
     */
    @Override
    public <T> T getMapper(Class<T> type) {
        return mapperRegistry.getMapper(type, this);
    }

    /*
    close方法先作保留,看后期能否使用
     */
    @Override
    public void close() throws IOException {
    }
}
public class DefaultSqlSessionFactory implements SqlSessionFactory {
    
    private MapperRegistry mapperRegistry;

    public DefaultSqlSessionFactory(MapperRegistry mapperRegistry){
        this.mapperRegistry = mapperRegistry;
    }

    @Override
    public SqlSession openSession() {
        return new DefaultSqlSession(mapperRegistry);
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值