MybatisPlus調(diào)用原生SQL的三種方法實例詳解
前言
在有些情況下需要用到MybatisPlus查詢原生SQL,MybatisPlus其實帶有運行原生SQL的方法,我這里列舉三種
方法一
這也是網(wǎng)上流傳最廣的方法,但是我個人認為這個方法并不優(yōu)雅,且采用${}的方式代碼審計可能會無法通過,會被作為代碼漏洞
public interface BaseMapper<T> extends com.baomidou.mybatisplus.core.mapper.BaseMapper<T> { @Select("${nativeSql}") Object nativeSql(@Param("nativeSql") String nativeSql); }
使用一個自己的BaseMapper去繼承MybatisPlus自己的BaseMapper,然后所有的Mapper去繼承自己寫的BaseMapper即可。那么所有的Mapper都能查詢原生SQL了。
問題在于${nativeSql}可能會被作為代碼漏洞,我并不提倡這種寫法。
方法二
使用SqlRunner的方式執(zhí)行原生SQL。這個方法我較為提倡,也是MybatisPlus源碼的測試類中用的最多的方法。
下圖為MybatisPlus源碼的測試類:
要使用SqlRunner的前提是打開SqlRunner,編輯application.yaml增加配置如下:
mybatis-plus: global-config: enable-sql-runner: true
application.properties寫法:
mybatis-plus.global-config.enable-sql-runner=true
如果不打開會報
Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for xxxxxxx
使用方法:
List<Map<String, Object>> mapList = SqlRunner.db().selectList("select * from test_example limit 1,10");
我個人比較推薦使用這種方式來查詢原生SQL,既不會污染Mapper,也不會被報出代碼漏洞。
方法三
采用原始的洪荒之力,用Mybatis最底層的方式執(zhí)行原生SQL
String sql = "select * from test_example limit 1,10"; Class<ExampleEntity> entityClass = ExampleEntity.class; // INFO: DCTANT: 2022/9/29 使用MybatisPlus自己的SqlHelper獲取SqlSessionFactory SqlSessionFactory sqlSessionFactory = SqlHelper.sqlSessionFactory(ExampleEntity.class); // INFO: DCTANT: 2022/9/29 通過SqlSessionFactory創(chuàng)建一個新的SqlSession,并獲取全局配置 SqlSession sqlSession = sqlSessionFactory.openSession(); Configuration configuration = sqlSessionFactory.getConfiguration(); // INFO: DCTANT: 2022/9/29 生成一個uuid,用于將這個SQL創(chuàng)建的MappedStatement注冊到MybatisPlus中 String sqlUuid = UUID.fastUUID().toString(true); RawSqlSource rawSqlSource = new RawSqlSource(configuration, sql, Object.class); MappedStatement.Builder builder = new MappedStatement.Builder(configuration, sqlUuid, rawSqlSource, SqlCommandType.SELECT); ArrayList<ResultMap> resultMaps = new ArrayList<>(); // INFO: DCTANT: 2022/9/29 創(chuàng)建返回映射 ResultMap.Builder resultMapBuilder = new ResultMap.Builder(configuration, UUID.fastUUID().toString(true), entityClass, new ArrayList<>()); ResultMap resultMap = resultMapBuilder.build(); resultMaps.add(resultMap); builder.resultMaps(resultMaps); MappedStatement mappedStatement = builder.build(); // INFO: DCTANT: 2022/9/29 將創(chuàng)建的MappedStatement注冊到配置中 configuration.addMappedStatement(mappedStatement); // INFO: DCTANT: 2022/9/29 使用SqlSession查詢原生SQL List<ExampleEntity> list = sqlSession.selectList(sqlUuid); // INFO: DCTANT: 2022/9/29 關(guān)閉session sqlSession.close();
其中的UUID是Hutool中的方法,用于生成隨機字符串。
這個方法就不需要打開SqlRunner了,就是代碼量感人,我不是很推薦,但是能夠窺探一下MybatisPlus的底層邏輯。
MyBatis-Plus執(zhí)行原生SQL
在mapper文件中定義要執(zhí)行的方法
@Repository public interface ZbArticleCEIResultPerformanceMapper extends BaseMapper<ZbArticleCEIResultPerformance> { ? ? @Select({"${sql}"}) ? ? @ResultType(ArrayList.class) ? ? List<ZbArticleCEIResultPerformance> executeQuery(@Param("sql") String sql); }
到此這篇關(guān)于MybatisPlus調(diào)用原生SQL的三種方法的文章就介紹到這了,更多相關(guān)MybatisPlus原生SQL內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Security 在 Spring Boot 中的使用詳解【集中式】
這篇文章主要介紹了Spring Security 在 Spring Boot 中的使用【集中式】,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10Spring?Security實現(xiàn)接口放通的方法詳解
在用Spring?Security項目開發(fā)中,有時候需要放通某一個接口時,我們需要在配置中把接口地址配置上,這樣做有時候顯得麻煩。本文將通過一個注解的方式快速實現(xiàn)接口放通,感興趣的可以了解一下2022-05-05