詳解mybatis @SelectProvider 注解
01、前言
為什么會(huì)寫這篇文章, 因?yàn)樵诳吹?MapperAnnotationBuilder
構(gòu)造方法初始化時(shí), 發(fā)現(xiàn)了四個(gè)從未見過的注解
public MapperAnnotationBuilder(Configuration configuration, Class<?> type) { ... sqlAnnotationTypes.add(Select.class); sqlAnnotationTypes.add(Insert.class); sqlAnnotationTypes.add(Update.class); sqlAnnotationTypes.add(Delete.class); // 這四個(gè)注解眼生的很 sqlProviderAnnotationTypes.add(SelectProvider.class); sqlProviderAnnotationTypes.add(InsertProvider.class); sqlProviderAnnotationTypes.add(UpdateProvider.class); sqlProviderAnnotationTypes.add(DeleteProvider.class); }
@SelectProvider、@InsertProvider、@UpdateProvider、@DeleteProvider
分別是 mybatis 定義的 另類增刪改查注解
02、介紹篇
四個(gè)注解中分別都有兩個(gè)屬性, 這里以 @SelectProvider舉例
可以看到, 兩個(gè)屬性并沒有默認(rèn)值, 證明定義注解的話, 這兩個(gè)屬性必須組合使用
沒有看到這一塊的具體解析源碼, 不過也能猜出來, 根據(jù)反射調(diào)用方法獲取的返回值
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface InsertProvider { // 用于指定獲取 sql 語句的指定類 Class<?> type(); // 指定類中要執(zhí)行獲取 sql 語句的方法 String method(); }
03、實(shí)戰(zhàn)篇
如何根據(jù)注解定義 sql 語句呢, 首先定義 mapper 接口
public interface AutoConstructorMapper { @SelectProvider(type = SubjectSqlProvider.class, method = "getSubjectTestProvider") PrimitiveSubject getSubjectTestProvider(@Param("id") int id); }
@Param() 為必須, 在解析時(shí)會(huì)將參數(shù)定義為 map, 進(jìn)行調(diào)用指定 method
創(chuàng)建 type 對應(yīng)的存放 sql 語句的類, 以及定義返回 sql 語句的方法
有三點(diǎn)需要注意:
- 方法入?yún)⒈仨殲?Map
- 方法的權(quán)限修飾符 必須是 public
- 方法返回的必須是拼接好的 sql 字符串
public class SubjectSqlProvider { public String getSubjectTestProvider(Map<String, Object> params) { return new SQL() .SELECT("*") .FROM("subject") .WHERE("id = " + params.get("id")) .toString(); } }
SQL 類是 mybatis 提供開發(fā)者在代碼中靈活編寫 sql 語句的工具類
04、思考篇
思考一下, @SelectProvider
注解, 與 @Select
注解解析流程有什么不同?
@Select
與 @SelectProvider
只是在定義注解的方式上有所不同, 一個(gè)是直接定義 sql, 一個(gè)是在外部定義好 sql 直接引用, 沒有質(zhì)的區(qū)別
在 mybatis 初始化定義 MappedStatement
時(shí), 使用了兩種不同的邏輯進(jìn)行組裝 SqlSource
Class<? extends Annotation> sqlAnnotationType = getSqlAnnotationType(method); Class<? extends Annotation> sqlProviderAnnotationType = getSqlProviderAnnotationType(method); if (sqlAnnotationType != null) { if (sqlProviderAnnotationType != null) { throw new BindingException("You cannot supply both a static SQL and SqlProvider to method named " + method.getName()); } Annotation sqlAnnotation = method.getAnnotation(sqlAnnotationType); final String[] strings = (String[]) sqlAnnotation.getClass().getMethod("value").invoke(sqlAnnotation); return buildSqlSourceFromStrings(strings, parameterType, languageDriver); } else if (sqlProviderAnnotationType != null) { Annotation sqlProviderAnnotation = method.getAnnotation(sqlProviderAnnotationType); return new ProviderSqlSource(assistant.getConfiguration(), sqlProviderAnnotation, type, method); }
05、使用篇
這里介紹下 mybatis 具體編寫 SQL 的三種形式, 以及介紹不同的方式對應(yīng)的使用場景
5.1 @Select
這種方式能夠定義簡單的 sql, 不涉及復(fù)雜查詢和多參數(shù)的場景, 類似下述方式
@Select 定義 sql 的方式是最簡單的, 省去了定義 xml文件的繁瑣, 也少了定義編寫 @SelectProvider 對應(yīng)類和方法的步驟
SELECT * FROM subject WHERE id = #{id}
5.2 @SelectProvider
這種方式編寫sql適合編寫中等長度, 簡單的查詢搭配 join、group、order…
SQL 工具類提供了這種簡單的 API 語法, 還是比較方便的
如果不想使用 SQL 工具類, 自己編寫 sql 字符串也是可以的
5.3 .xml 文件
這種方式就不多說了, 功能全部具備, 比如計(jì)算函數(shù)、動(dòng)態(tài)SQL、各種關(guān)鍵字都支持
這幾種方式都能夠?qū)崿F(xiàn)我們的 sql 編寫需求, 只不過針對不同的場景, 合理的使用即可
06、總結(jié)篇
看 mybatis 源碼, 對變量、方法的命名加深了感觸, 一個(gè)好的變量或者方法命名在代碼中是多么有必要
getSqlSourceFromAnnotations
是不是要比 getSqlSource
要好理解很多, 看了之后就能讓閱讀者知道這個(gè)方法要做什么功能
到此這篇關(guān)于詳解mybatis @SelectProvider 注解的文章就介紹到這了,更多相關(guān)mybatis @SelectProvider 注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
探索Java中的equals()和hashCode()方法_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了探索Java中的equals()和hashCode()方法的相關(guān)資料,需要的朋友可以參考下2017-05-05SpringBoot3?Web編程開發(fā)的工程搭建攔截器及測試工具示例
這篇文章主要介紹了SpringBoot3?Web編程開發(fā)的工程搭建攔截器及測試工具示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08詳解SpringBoot上傳圖片到阿里云的OSS對象存儲(chǔ)中
這篇文章主要介紹了SpringBoot上傳圖片到阿里云的OSS對象存儲(chǔ)中,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10