返回

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

后端

来到《手写Mybatis》的第二章,我们将深入了解 MyBatis 的运行原理。掌握了原理之后,我们就能够自己动手创建简单的映射器代理工厂。

在开始之前,我们先来回顾一下 MyBatis 的工作原理。

1. MyBatis 是一个基于 ORM(对象关系映射)的数据库操作框架。

ORM 是一种编程技巧,它允许我们使用面向对象的方式来操作数据库。在 MyBatis 中,我们使用 Java Bean 对象来表示数据库中的表和行。

2. MyBatis 使用 XML 文件来配置映射器。

映射器文件定义了 Java Bean 对象和数据库表之间的映射关系。它告诉 MyBatis 如何将 Java Bean 对象中的属性映射到数据库表中的列。

3. MyBatis 使用反射机制来创建 Java Bean 对象的实例。

当 MyBatis 执行 SQL 查询时,它会使用反射机制来创建 Java Bean 对象的实例。它会将查询结果中的每一行数据都映射到一个 Java Bean 对象的属性上。

4. MyBatis 使用动态代理来生成映射器接口的代理对象。

动态代理是一种编程技巧,它允许我们创建一个对象的代理对象。代理对象的行为和原对象完全相同,但是代理对象可以在原对象的方法执行前后做一些额外的事情。

在 MyBatis 中,动态代理用于生成映射器接口的代理对象。映射器接口的代理对象可以自动执行一些数据库操作,例如查询、插入、更新和删除。

现在,我们已经对 MyBatis 的工作原理有了一个基本的了解。接下来,我们就开始创建简单的映射器代理工厂。

1. 创建一个 Java 接口,定义映射器接口的签名。

public interface UserMapper {

    List<User> findAll();

    User findById(int id);

    void insert(User user);

    void update(User user);

    void delete(int id);

}

2. 创建一个 Java 类,实现映射器接口。

public class UserMapperImpl implements UserMapper {

    private SqlSession sqlSession;

    public UserMapperImpl(SqlSession sqlSession) {
        this.sqlSession = sqlSession;
    }

    @Override
    public List<User> findAll() {
        return sqlSession.selectList("UserMapper.findAll");
    }

    @Override
    public User findById(int id) {
        return sqlSession.selectOne("UserMapper.findById", id);
    }

    @Override
    public void insert(User user) {
        sqlSession.insert("UserMapper.insert", user);
    }

    @Override
    public void update(User user) {
        sqlSession.update("UserMapper.update", user);
    }

    @Override
    public void delete(int id) {
        sqlSession.delete("UserMapper.delete", id);
    }

}

3. 创建一个 Java 类,实现代理工厂接口。

public class MapperProxyFactory {

    private static final Map<Class<?>, Object> MAPPER_CACHE = new HashMap<>();

    public static <T> T getMapper(Class<T> mapperInterface) {
        Object mapper = MAPPER_CACHE.get(mapperInterface);
        if (mapper == null) {
            mapper = createMapper(mapperInterface);
            MAPPER_CACHE.put(mapperInterface, mapper);
        }
        return (T) mapper;
    }

    private static <T> T createMapper(Class<T> mapperInterface) {
        try {
            InvocationHandler invocationHandler = new MapperInvocationHandler(mapperInterface);
            return Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class<?>[]{mapperInterface}, invocationHandler);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException("Could not create mapper for interface " + mapperInterface, e);
        }
    }

}

4. 使用代理工厂创建映射器接口的代理对象。

UserMapper userMapper = MapperProxyFactory.getMapper(UserMapper.class);
List<User> users = userMapper.findAll();

现在,我们已经创建了简单的映射器代理工厂。我们可以使用这个代理工厂来创建任何映射器接口的代理对象。代理对象可以自动执行一些数据库操作,例如查询、插入、更新和删除。

至此,我们就完成了《手写Mybatis》的第二章内容。在下一章中,我们将学习如何使用代理对象来执行数据库操作。