手寫(xiě)一個(gè)Mybatis?
在文章內(nèi)容開(kāi)始之前,給大家送個(gè)福利,將自己整理了好多年的瀏覽器收藏夾送給大家,太多干貨了。將下載后的 html 直接導(dǎo)入到你們的瀏覽器書(shū)簽中,就成你們的啦?!疚哪┯蝎@取方式】
本篇文章,可樂(lè)將為大家介紹通過(guò)接口代理的方式去執(zhí)行SQL操作,了解了這種方式,手寫(xiě) Mybatis 框架不是夢(mèng)。話不多說(shuō),直接上圖:


其實(shí)無(wú)論哪種方式,我們最終是需要找到對(duì)應(yīng)的 SQL 語(yǔ)句,接口代理的方式就是通過(guò) 【包名.方法名】 的方式,去找到 xxxMapper.xml 文件中的 SQL 語(yǔ)句。
很明顯,通過(guò)動(dòng)態(tài)代理的方式,我們能夠?qū)崿F(xiàn)該功能。下面,可樂(lè)將為大家手?jǐn)]一個(gè) Mybatis 的接口代理。實(shí)例源碼地址:https://github.com/YSOcean/mybatisproject
1、創(chuàng)建接口
package com.itcoke.mapperproxy;
import com.itcoke.bean.Person;
public interface PersonMapper {
Person selectPersonById(Long pid);
}
2、創(chuàng)建代理類
package com.itcoke.mapperproxy;
import org.apache.ibatis.session.SqlSession;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MapperProxyHandler implements InvocationHandler {
private SqlSession sqlSession;
private Class<?> targetInterface;
public MapperProxyHandler(SqlSession sqlSession,Class<?> targetInterface){
this.sqlSession = sqlSession;
this.targetInterface = targetInterface;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String className = targetInterface.getName();
String methodName = method.getName();
String statement = className + "." + methodName;
return sqlSession.selectOne(statement,args[0]);
}
}
3、創(chuàng)建代理工廠類
package com.itcoke.mapperproxy;
import java.lang.reflect.Proxy;
public class MapperProxyFactory {
private Class<?> targetInterface;
public MapperProxyFactory(Class<?> targetInterface){
this.targetInterface = targetInterface;
}
public Object newInstance(MapperProxyHandler handler){
return Proxy.newProxyInstance(targetInterface.getClassLoader(),
new Class[]{targetInterface},
handler);
}
}
4、創(chuàng)建測(cè)試類
package com.itcoke.mapperproxy;
import com.itcoke.bean.Person;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MapperProxyTest {
public static void main(String[] args) {
// 1、獲取目標(biāo)接口對(duì)象
Class<?> targetInterface = PersonMapper.class;
// 2、獲取 SqlSession 對(duì)象
SqlSession sqlSession = getSqlSession();
MapperProxyHandler proxyHandler = new MapperProxyHandler(sqlSession,targetInterface);
MapperProxyFactory mapperProxyFactory = new MapperProxyFactory(PersonMapper.class);
PersonMapper personMapper = (PersonMapper)mapperProxyFactory.newInstance(proxyHandler);
Person person = personMapper.selectPersonById(1L);
System.out.println(person);
}
public static SqlSession getSqlSession() {
//定義mybatis全局配置文件
String resource = "mybatis-config.xml";
//加載 mybatis 全局配置文件
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
//構(gòu)建sqlSession的工廠
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sessionFactory.openSession();
}
}
5、總結(jié)
其實(shí) Mybatis 內(nèi)部實(shí)現(xiàn)方式大體上和上面差不多,在加入一些類型處理器,這就是一個(gè)簡(jiǎn)易版本的 Mybatis 了。
6、福利
前面說(shuō)的我整理的瀏覽器收藏夾,只需要在本公眾號(hào)回復(fù)【收藏夾】即可領(lǐng)取。
評(píng)論
圖片
表情
