手写mybatis之创建简单的映射器代理工厂

前言


我们使用 JDBC 的时候,需要手动建立数据库链接、编码 SQL 语句、执行数据库操作、自己封装返回结果等。但在使用 ORM 框架后,只需要通过简单配置即可对定义的 DAO 接口进行数据库的操作了。
我们就来解决 ORM 框架第一个关联对象接口和映射类的问题,把 DAO 接口使用代理类,包装映射操作。
设计一个 ORM 框架的过程中,首先要考虑怎么把用户定义的数据库操作接口、xml配置的SQL语句、数据库三者联系起来。其实最适合的操作就是使用代理的方式进行处理,因为代理可以封装一个复杂的流程为接口对象的实现类
在这里插入图片描述
以下是实战部分

public class MapperProxy<T> implements InvocationHandler, Serializable {
    private Map<String, String> sqlSession;
    private final Class<T> mapperInterface;

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

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (Object.class.equals(method.getDeclaringClass())) {
            return method.invoke(this, args);
        } else {
            return "你的被代理了!" + sqlSession.get(mapperInterface.getName() + "." + method.getName());
        }
    }
}

注意上述
要注意如果是 Object 提供的 toString、hashCode 等方法是不需要代理执行的,所以添加 Object.class.equals(method.getDeclaringClass()) 判断。
代理类工厂


public class MapperProxyFactory<T> {
    private final Class<T> mapperInterface;

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

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

工厂操作相当于把代理的创建给封装起来了,如果不做这层封装,那么每一个创建代理类的操作,都需要自己使用 Proxy.newProxyInstance 进行处理,那么这样的操作方式就显得比较麻烦了。
测试

public interface IUserDao {

    String queryUserName(String uId);

    Integer queryUserAge(String uId);

}

首先提供一个 DAO 接口,并定义2个接口方法。
编写测试类

public class TestApi {
    private Logger logger = LoggerFactory.getLogger(TestApi.class);

    @Test
    public void test01() {
        MapperProxyFactory<IUserDao> factory = new MapperProxyFactory<>(IUserDao.class);
        Map<String, String> sqlSession = new HashMap<String, String>();
        sqlSession.put("com.lm.test.dao.IUserDao.queryUserName", "模拟执行 Mapper.xml 中 SQL 语句的操作:查询用户姓名");
        sqlSession.put("com.lm.test.dao.IUserDao.queryUserAge", "模拟执行 Mapper.xml 中 SQL 语句的操作:查询用户年龄");
        IUserDao iUserDao = factory.newInstance(sqlSession);
        String res = iUserDao.queryUserName("10001");
        logger.info("测试结果:{}", res);
    }
}

在这里插入图片描述

好了到这里就结束了手写mybatis之创建简单的映射器代理工厂的学习,大家一定要跟着动手操作起来。需要的源码的 可si我获取;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值