手写MyBatis,纯手工打造开源框架(第四篇:决胜千里)- 第272篇


说明

MyBatis版本:3.5.1

相关历史文章(阅读本文之前,您可能需要先看下之前的系列?)br/>

 

相关历史文章(阅读本文之前,您可能需要先看下之前的系列)

Spring Boot MyBatis最全教程:你值得拥有
MyBatis能脱离Spring吗一图纵览MyBatis的工作原理从源码看MyBatis,竟如此简单MyBatis的Mapper是什么`垃圾`

手写MyBatis,纯手工打造开源框架(第一篇:风云再起)

手写MyBatis,纯手工打造开源框架(第二篇:君临天下)

手写MyBatis,纯手工打造开源框架(第三篇:运筹帷幄)

 

前言

运筹帷幄之中,决胜千里之外,是该做个了结了,把你的家伙掏出来,上刺刀。
上一篇已经能够使用SqlSession进行查询返回结果了。这一篇我们就是加入瑞士军刀Mapper。

一、分析

在SqlSession会提供getMapper的方法,在DefaultSqlSession会使用Proxy实例化一个MapperProxy代理,而MapperProxy代理会获取SqlSession,在这里进行Sql的操作,然后结果。

 

二、编码

2.1 MapperProxy

MapperProxy是mapper最终执行的核心:

package com.kfit.mybatis.session.impl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Collection;

import com.kfit.mybatis.session.SqlSession;

public class MapperProxy implements InvocationHandler{
	private SqlSession sqlSession;
	public MapperProxy(SqlSession sqlSession) {
		this.sqlSession = sqlSession;
	}
	
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		String statement = method.getDeclaringClass().getName()+"."+method.getName();
		//isAssignableFrom方法是判断是否为某个类的父类
		if(Collection.class.isAssignableFrom(method.getReturnType())) {
			//返回值是集合的话,那么是调用selectList
			return sqlSession.selectList(statement,null==args?null:args[0]);
		}else {
			return sqlSession.selectOne(statement,null==args?null:args[0]);
		}
	}
	
}

 

说明:

(1)由于MapperProxy是一个代理类,所以需要实现接口InvocationHandler的Invoke方法。

(2)在Invoke方法中直接使用SqlSession进行执行,那么主要的核心就是要判断具体执行什么方法,这里现在通过返回值是否是集合来判断是否是执行selectOne还是SelectList。

2.2 SqlSession

在SqlSession中添加getMapper方法:

public interface SqlSession {
	 <T> T selectOne(String statement, Object parameter);
	 <E> List<E> selectList(String statement);
	 <E> List<E> selectList(String statement, Object parameter);
	 <T> T getMapper(Class<T> type);
}

 

在DefaultSqlSession中进行实现getMapper方法:

	@SuppressWarnings("unchecked")
	public <T> T getMapper(Class<T> type) {
		T newProxyInstance = (T) Proxy.newProxyInstance(type.getClassLoader(),new Class[]{type},new MapperProxy(this));
		return newProxyInstance;
	}

2.3 测试下

好了写段代码测试下吧:

public static void main(String[] args) {
		String resource = "mybatis-config.xml";
		InputStream inputStream = App.class.getClassLoader().getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		System.out.println(sqlSessionFactory);
		System.out.println(sqlSessionFactory.getConfiguration().getJdbcProperties().getUrl());
		
		SqlSession sqlSession = sqlSessionFactory.openSession();
		
		
		Demo demo = null;
		List<Demo> demos = null;
		
		
		//使用Mapper
		DemoMapper demoMapper = sqlSession.getMapper(DemoMapper.class);
		demo = demoMapper.getById(1);
		System.out.println(demo);
		demos = demoMapper.getAll();
		System.out.println(demos);
	}

运行看下结果:

Demo [id=1, name=张三1]
[Demo [id=1, name=张三1], Demo [id=9, name=张三], Demo [id=10, name=张三], Demo [id=11, name=张三], Demo [id=12, name=张三], Demo [id=13, name=张三]]

很明显执行的结果和直接使用SqlSession调用的结果是一样的。

好了有关手写MyBatis的文章就先到此告一段落了,通过手写mybatis,想必大家对于MyBatis的认知又高了一个等级了。

 

我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。

 


à悟空学院:http://t.cn/Rg3fKJD 

学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!

SpringBoot视频: http://t.cn/R3QepWG 
Spring Cloud视频: http://t.cn/R3QeRZc 
SpringBoot Shiro视频: http://t.cn/R3QDMbh 
SpringBoot交流平台: http://t.cn/R3QDhU0 
SpringData和JPA视频: http://t.cn/R1pSojf 
SpringSecurity5.0视频: http://t.cn/EwlLjHh 
Sharding-JDBC分库分表实战: http://t.cn/E4lpD6e
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值