日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Mybatis框架中是如何获取到SQL语句的,让我们一起来模拟一下吧

發布時間:2025/3/19 数据库 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mybatis框架中是如何获取到SQL语句的,让我们一起来模拟一下吧 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文主要是通過代理和反射來模擬Mybatis此ORM框架是如何獲得SQL語句及相關參數等。當我們拿到這些東西,那么一切就變得很簡單啦,想做啥就做啥啦。
與君共勉😁

一、基礎知識

我們都知道Mybatis框架主要就是靠代理和反射來進行操作,那么對于動態代理,怎么都需要了解一點點哈。

Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)

newProxyInstance,方法有三個參數:

  • loader: 用哪個類加載器去加載代理對象

  • interfaces:動態代理類需要實現的接口

  • h:動態代理方法在執行時,會調用h里面的invoke方法去執行

二、代碼

一個User類 為了測試加上的。

public class User {private Integer id;private String username;private String password; }

具體代碼哦:加一下 Mybatis 的依賴就 可以直接copy測試啦哦

import org.apache.ibatis.annotations.Select; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.lang.reflect.Proxy; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map;/*** @Author: crush* @Date: 2021-05-27 11:32* version 1.0*/ interface UserMapper {/*** @return*/@Select("select * from user where id=#{id} and name=#{name}")List<User> selectUser(Integer id,String name); }/*** @author crush*/ public class Application {public static void main(String[] args) {// newProxyInstance 這里用的是jdk的代理UserMapper userMapper = (UserMapper) Proxy.newProxyInstance(Application.class.getClassLoader(), new Class[]{UserMapper.class}, new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("參數==> " + Arrays.toString(args));System.out.println("UserMapper執行的方法名==> " + method.getName());Map<String, Object> nameArgMap = buildMethodArgNameMap(method, args);System.out.println("方法上的參數名==> "+nameArgMap.toString());// 這咯是通過反射獲取方法上的注解Select annotation = method.getAnnotation(Select.class);if (annotation != null) {// 這里是獲取 注解的值String[] value = annotation.value();String sql = value[0];//解析sql 語句sql = parseSQL(sql, nameArgMap );System.out.println(sql);System.out.println("返回的類型==>"+method.getReturnType());System.out.println("返回的泛型==>"+method.getGenericReturnType());}return null;}});userMapper.selectUser(1,"crush");}public static String parseSQL(String sql, Map<String, Object> nameArgMap ) {StringBuilder stringBuilder = new StringBuilder();int length = sql.length();for (int i = 0; i < length; i++) {char c = sql.charAt(i);// 此處是判斷'#{'if (c == '#') {int nextIndex = i + 1;char nextChar = sql.charAt(nextIndex);if (nextChar != '{') {throw new RuntimeException(String.format("這里應該為#{\nsql:%s\nindex:%d",stringBuilder.toString(), nextIndex));}StringBuilder argSB = new StringBuilder();//此處是 讓argSB 獲取到 #{} 中的值 手動打印一下查看i = parseSQLArg(argSB, sql, nextIndex);String argName = argSB.toString();Object argValue = nameArgMap.get(argName);stringBuilder.append(argValue.toString());continue;}stringBuilder.append(c);}return stringBuilder.toString();}private static int parseSQLArg(StringBuilder argSB, String sql, int nextIndex) {nextIndex++;for (; nextIndex < sql.length(); nextIndex++) {char c = sql.charAt(nextIndex);if (c != '}') {argSB.append(c);continue;}if (c == '}') {return nextIndex;}}throw new RuntimeException(String.format("缺少右括號\nindex:%d", nextIndex));}public static Map<String, Object> buildMethodArgNameMap(Method method, Object[] args) {Map<String, Object> nameArgMap = new HashMap<String, Object>();Parameter[] parameters = method.getParameters();int[] index = {0};Arrays.asList(parameters).forEach(parameter -> {String name = parameter.getName();System.out.println("接口方法上參數名字==》"+name);nameArgMap.put(name, args[index[0]]);index[0]++;});return nameArgMap;} }

自言自語

之前只是學習和使用mybatis,知道是代理和反射實現的框架原理,但是從來沒有真正去了解??催^之后發現,學習帶有好奇心,做什么都會有激情,事半功倍哦。
加油哦。

總結

以上是生活随笔為你收集整理的Mybatis框架中是如何获取到SQL语句的,让我们一起来模拟一下吧的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。