纯手写mybatis(注解版)

纯手写mybatis(注解版)
实现思路:
1.自定义注解
2.利用动态代理操作目标对象
3.利用反射绑定参数
4.执行SQL语句

项目结构图
在这里插入图片描述
定义查询和插入接口,这里采用注解方式。
在这里插入图片描述
定义一个SqlSession,采用动态代理来生成UserMapper接口的代理对象,待会要传入InvocationHandler的实现类。
在这里插入图片描述
定义UserMapperInvocationHandler实现InvocationHandler,mybatis的主要逻辑就是在这个类实现的。
在这里插入图片描述
这是获取结果集的方法,并将结果集映射为Java User对象
在这里插入图片描述
这个是获取方法参数的方法
在这里插入图片描述
这是将参数装入list集合以便后面可以取出这个参数
在这里插入图片描述

这个工具类是用来替换参数,拼接sql语句
在这里插入图片描述
最后调用jdbc底层代码来执行sql语句。
代码地址:https://github.com/dezhiguan/mybatis

Mybatis 是一款优秀的持久层框架,它可以对 JDBC 进行封装,使得开发者可以通过 XML 文件或注解来配置 SQL 语句,从而避免了手写 JDBC 代码的繁琐和重复。下面,我将简单介绍如何手写一个简单Mybatis。 1. 创建配置文件 在 resources 目录下创建一个 mybatis-config.xml 文件,用于配置 Mybatis 的各种参数。其中包括数据库连接信息、mapper 文件路径、缓存配置、插件等。以下是一个简单的配置文件示例: ``` <configuration> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> <mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers> </configuration> ``` 2. 创建数据库连接池 在 Mybatis 中,我们可以通过数据源来获取数据库连接。下面是一个简单的数据源示例: ``` public class PooledDataSource { private static final String driver = "com.mysql.jdbc.Driver"; private static final String url = "jdbc:mysql://localhost:3306/mybatis"; private static final String username = "root"; private static final String password = "root"; private static final int initialSize = 5; private static final int maxActive = 10; private static final int maxIdle = 8; private static final int minIdle = 5; private static final long maxWait = 60000; private static DataSource dataSource; static { try { GenericObjectPoolConfig<Connection> poolConfig = new GenericObjectPoolConfig<>(); poolConfig.setMinIdle(minIdle); poolConfig.setMaxIdle(maxIdle); poolConfig.setMaxTotal(maxActive); poolConfig.setMaxWaitMillis(maxWait); ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(url, username, password); PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, null); poolableConnectionFactory.setValidationQuery("SELECT 1"); dataSource = new PoolingDataSource(poolableConnectionFactory.getPool()); } catch (Exception e) { e.printStackTrace(); } } public static DataSource getDataSource() { return dataSource; } } ``` 3. 创建 SqlSession SqlSession 是 Mybatis 中用于执行 SQL 语句的核心接口,它提供了各种方法来执行 SQL 语句、获取 Mapper 等。下面是一个简单的 SqlSession 实现: ``` public class DefaultSqlSession implements SqlSession { private final Configuration configuration; private final Executor executor; public DefaultSqlSession(Configuration configuration, Executor executor) { this.configuration = configuration; this.executor = executor; } @Override public <T> T selectOne(String statement, Object parameter) { return executor.query(statement, parameter); } @Override public <T> T getMapper(Class<T> type) { return configuration.getMapper(type, this); } } ``` 4. 创建 Executor Executor 是 Mybatis 中用于执行 SQL 语句的实现类,它提供了各种方法来执行 SQL 语句、获取结果等。下面是一个简单的 Executor 实现: ``` public class SimpleExecutor implements Executor { private final DataSource dataSource; public SimpleExecutor(DataSource dataSource) { this.dataSource = dataSource; } @Override public <T> T query(String statement, Object parameter) { Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { connection = dataSource.getConnection(); preparedStatement = connection.prepareStatement(statement); preparedStatement.setString(1, parameter.toString()); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { return (T) resultSet.getString(1); } } catch (SQLException e) { e.printStackTrace(); } finally { try { resultSet.close(); preparedStatement.close(); connection.close(); } catch (SQLException e) { e.printStackTrace(); } } return null; } } ``` 5. 创建 Mapper Mapper 是 Mybatis 中用于定义 SQL 语句的接口,它包含了各种方法来执行 SQL 语句、获取结果等。下面是一个简单的 Mapper 接口示例: ``` public interface UserMapper { @Select("SELECT * FROM user WHERE id = #{id}") User selectById(Integer id); } ``` 6. 创建 Configuration Configuration 是 Mybatis 中用于配置各种参数的类,它负责解析配置文件、创建 SqlSession 和 Mapper 等。下面是一个简单的 Configuration 实现: ``` public class Configuration { private final Properties properties; private final Map<Class<?>, MapperProxyFactory<?>> mapperProxyFactoryMap = new HashMap<>(); public Configuration(Properties properties) { this.properties = properties; } public <T> T getMapper(Class<T> type, SqlSession sqlSession) { MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) mapperProxyFactoryMap.get(type); if (mapperProxyFactory == null) { mapperProxyFactory = new MapperProxyFactory<>(type); mapperProxyFactoryMap.put(type, mapperProxyFactory); } return mapperProxyFactory.newInstance(sqlSession); } } ``` 7. 创建 MapperProxyFactory 和 MapperProxy MapperProxyFactory 是 Mybatis 中用于创建 MapperProxy 的工厂类,它负责创建 MapperProxy 并维护 Mapper 接口和对应的 MapperProxy。MapperProxy 是 Mybatis 中用于动态代理 Mapper 接口的类,它负责解析 Mapper 接口中定义的 SQL 语句,并将其转化为对应的 SQL 语句执行器。下面是一个简单的 MapperProxyFactory 和 MapperProxy 实现: ``` public class MapperProxyFactory<T> { private final Class<T> mapperInterface; public MapperProxyFactory(Class<T> mapperInterface) { this.mapperInterface = mapperInterface; } public T newInstance(SqlSession sqlSession) { return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, new MapperProxy(sqlSession, mapperInterface)); } } public class MapperProxy<T> implements InvocationHandler { private final SqlSession sqlSession; private final 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 { Select select = method.getAnnotation(Select.class); if (select != null) { String sql = select.value()[0]; return sqlSession.selectOne(sql, args[0]); } throw new RuntimeException("No such method: " + method.getName()); } } ``` 至此,我们就手写了一个简单Mybatis,它包含了配置文件、数据库连接池、SqlSession、Executor、Mapper 等核心组件。虽然这个实现比较简单,但它足以帮助我们理解 Mybatis 的核心原理。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值