本篇文章,可樂將為大家介紹通過介面代理的方式去執行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