码云代码:
MyBatis的简单实现
介绍
MyBatisTest里面有最基本的用法
- 导入配置类
- 创建SessionFactoryBuilder(会话建造)工厂
- 创建SessionFactory(会话)工厂
- 通过SessionFactory创建连接
- 获取Mapper对象
- 进行查询
整体思想
- 需要通过Connection来执行SQL语句
- 获取配置的SQL封装为PrepareStatement,等到解析的时候,填充?处的内容
- 需要解析XML,我没有解析,使用了官方的解析
- 需要解析所有的mapper映射
- 解析后的mapper内的内容肯定需要封装起来,暂且叫做sqlBean吧,里面包含SQL语句,以及返回值类型等等。
例如:public class SqlBean { String sql; Class<?> returnType; // 等等 }
- 那么这些mapper解析后的结果最好存起来,方便快速找到,那么此时比较适合的自然是 Map O(1)时间复杂度。
那么结构就是 Map<Class<?>, SqlBean>. - 假设有User和UserMapper,因为UserMapper是接口,自然而然可以想到是使用JDK的动态代理创建UserMapper的实现类
例如:public class DynamicInterfaceProxyTest { public static void main(String[] args) { // 动态代理创建对象 Object obj = Proxy.newProxyInstance(MyInvocationHandler.class.getClassLoader(), new Class[]{Say.class}, new MyInvocationHandler("select * from user")); Say say = (Say) obj; System.out.println("sepak = " + say.speak()); } static class MyInvocationHandler implements InvocationHandler { private String sql; public MyInvocationHandler(String sql) { this.sql = sql; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("动态代理打印sql = " + sql); return sql; } } static interface Say{ public String speak(); } }
- 那就很明了了,每次执行UserMapper的方法时候都会执行创建的代理类,那么代理类中需要写的就是
- 判断当前的方法
- 根据当前的方法,获取对应的sqlBean对象,那么此时很显然需要一个 Map<Method, sqlBean>map 了吧。
- 通过 connection 的 PrepareStatement 执行对应的 sqlBean。
- 把最终的结果封装好即可
码云代码:
MyBatis的简单实现