本篇文章,可樂將為大家介紹通過介面代理的方式去執行SQL操作。話不多說,直接上圖:

其實無論哪種方式,我們最終是需要找到對應的 SQL 語句,介面代理的方式就是通過 【包名.方法名】 的方式,去找到 xxxMapper.xml 檔案中的 SQL 語句。

很明顯,通過動態代理的方式,我們能夠實現該功能。下面,可樂將為大家手擼一個 Mybatis 的介面代理。

1、建立介面

package com.itcoke.mapperproxy;

import com.itcoke.bean.Person;

public interface PersonMapper {

    Person selectPersonById(Long pid);
}

2、建立代理類

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、建立代理工廠類

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、建立測試類

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、獲取目標介面物件
Class<?> targetInterface = PersonMapper.class;
// 2、獲取 SqlSession 物件
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();
}
//構建sqlSession的工廠
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sessionFactory.openSession();
}
}

5、總結

其實 Mybatis 內部實現方式大體上和上面差不多,在加入一些型別處理器,其實就是一個簡易版本的 Mybatis