定制化开发【原创】MybatisPlus调用原生SQL的三种方法

前言

定制化开发在有些情况下需要用到MybatisPlus查询原生SQL,MybatisPlus定制化开发其实带有运行原生SQL的方法,定制化开发我这里列举三种

方法一

定制化开发这也是网上流传最广的方法,但是我个人认为这个方法并不优雅,且采用${}的方式代码审计可能会无法通过,会被作为代码漏洞

  1. public interface BaseMapper<T> extends com.baomidou.mybatisplus.core.mapper.BaseMapper<T> {
  2. @Select("${nativeSql}")
  3. Object nativeSql(@Param("nativeSql") String nativeSql);
  4. }

使用一个自己的BaseMapper去继承MybatisPlus自己的BaseMapper,然后所有的Mapper去继承自己写的BaseMapper即可。那么所有的Mapper都能查询原生SQL了。

问题在于${nativeSql}可能会被作为代码漏洞,我并不提倡这种写法。

方法二

使用SqlRunner的方式执行原生SQL。这个方法我较为提倡,也是MybatisPlus源码的测试类中用的最多的方法。

下图为MybatisPlus源码的测试类:

 要使用SqlRunner的前提是打开SqlRunner,编辑application.yaml增加配置如下:

  1. mybatis-plus:
  2. global-config:
  3. enable-sql-runner: true

application.properties写法:

-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最底层的方式执行原生SQL

  1. String sql = "select * from test_example limit 1,10";
  2. Class<ExampleEntity> entityClass = ExampleEntity.class;
  3. // INFO: DCTANT: 2022/9/29 使用MybatisPlus自己的SqlHelper获取SqlSessionFactory
  4. SqlSessionFactory sqlSessionFactory = SqlHelper.sqlSessionFactory(ExampleEntity.class);
  5. // INFO: DCTANT: 2022/9/29 通过SqlSessionFactory创建一个新的SqlSession,并获取全局配置
  6. SqlSession sqlSession = sqlSessionFactory.openSession();
  7. Configuration configuration = sqlSessionFactory.getConfiguration();
  8. // INFO: DCTANT: 2022/9/29 生成一个uuid,用于将这个SQL创建的MappedStatement注册到MybatisPlus中
  9. String sqlUuid = UUID.fastUUID().toString(true);
  10. RawSqlSource rawSqlSource = new RawSqlSource(configuration, sql, Object.class);
  11. MappedStatement.Builder builder = new MappedStatement.Builder(configuration, sqlUuid, rawSqlSource, SqlCommandType.SELECT);
  12. ArrayList<ResultMap> resultMaps = new ArrayList<>();
  13. // INFO: DCTANT: 2022/9/29 创建返回映射
  14. ResultMap.Builder resultMapBuilder = new ResultMap.Builder(configuration, UUID.fastUUID().toString(true), entityClass, new ArrayList<>());
  15. ResultMap resultMap = resultMapBuilder.build();
  16. resultMaps.add(resultMap);
  17. builder.resultMaps(resultMaps);
  18. MappedStatement mappedStatement = builder.build();
  19. // INFO: DCTANT: 2022/9/29 将创建的MappedStatement注册到配置中
  20. configuration.addMappedStatement(mappedStatement);
  21. // INFO: DCTANT: 2022/9/29 使用SqlSession查询原生SQL
  22. List<ExampleEntity> list = sqlSession.selectList(sqlUuid);
  23. // INFO: DCTANT: 2022/9/29 关闭session
  24. sqlSession.close();

其中的UUID是Hutool中的方法,用于生成随机字符串。

这个方法就不需要打开SqlRunner了,就是代码量感人,我不是很推荐,但是能够窥探一下MybatisPlus的底层逻辑。

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发