Mybatis實現Mapper介面的簡單案例
阿新 • • 發佈:2018-12-21
用了很久mybatis,一直猜想mybatis是使用動態代理的方式實現mapper介面的,通過實踐探索之後,果然如此,但是還是遇到了不少問題,在此粘出來供初學者參考。
首先我將案例程式碼粘出來,這段程式碼簡單實現了從service層開始呼叫mapper介面的過程。
package com.star.ott.common.office; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class TestClass { public static void main(String[] args) { new UserService().updateUserByUserName(); new UserService().findUser(""); } } /** * 我們需要操作的user實體 */ class User { private String userName; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } } /** * 這裡是我們的mapper介面 */ interface UserMapper { User findUserByUserName(String userName); void updateUserByUserName(User user); } /** * 此處是service層的業務類 */ class UserService { //在實際開發中,此處的UserMapper是通過註解載入進來的,而其真正的 //實現就類似於下面的實現方式,通過動態帶來的方式建立例項 UserMapper userMapper = (UserMapper) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{UserMapper.class}, new MybatisProxy()); public User findUser(String userName) { return userMapper.findUserByUserName(userName); } public void updateUserByUserName() { userMapper.updateUserByUserName(new User()); } } /** * 這裡就是具體的代理類,在代理類中,通過資料庫驅動與資料庫獲取 * 連線,然後讀取相關mapper.xml執行sql,最後獲得操作結果,具體 * 連線資料庫,讀取mapper.xml檔案的方式就不再累贅 */ class MybatisProxy implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("遍歷引數" + method.getParameters()[0]); System.out.println("通過method的名字去mapper.xml檔案中找到sql: " + method.getName()); System.out.println("執行資料庫操作,若果有異常等,直接在此處丟擲,沒有則拿到返回值"); if(method.getReturnType().toString().equals("void")){ System.out.println("無返回值的情況"); return method.getGenericReturnType(); }else { Object result = method.getReturnType().getDeclaredConstructor().newInstance(); System.out.println("將得到的返回值賦值給result,然後返回" + method.getReturnType()); return result; } } }
需要注意的是,通過Proxy.newProxyInstance方式生成代理物件時,一般除了需要介面類的類型別之外,還需要實現類的例項作為代理類的引數,這樣,我們就可以在代理物件中,也就是MybatisProxy中直接執行實現類例項的方法,然後返回。但是我們此處代理物件的特殊之處,就是代理了介面,實現邏輯完全寫在代理類中,所以遇到沒有返回值的方法時,需要做邏輯判斷,返回一個method.getGenericReturnType(),否則這裡會報錯。
好了,這就是mybatis通過動態代理的方式實現mapper介面的大致方式,可以參考一下。