使用mybatis动态执行SQL
Posted 艾斯利文
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用mybatis动态执行SQL相关的知识,希望对你有一定的参考价值。
抽取mybatis,根据xml方式sql,拼接参数
package com.jdcloud.zs.api.db; import com.baomidou.mybatisplus.core.MybatisConfiguration; import org.apache.ibatis.mapping.*; import org.apache.ibatis.scripting.LanguageDriver; import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.defaults.DefaultSqlSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Component public class SqlSourceUtil { @Autowired private SqlSessionFactory sqlSessionFactory; /** * sql拼接 * @param sqlString * @param parameters * @return */ public String sqlSource(String sqlString, Map<String,Object> parameters){ MybatisConfiguration configuration=(MybatisConfiguration)sqlSessionFactory.getConfiguration(); LanguageDriver xmlLanguageDriver=new XMLLanguageDriver(); final StringBuilder sqlXml = new StringBuilder(); String[]strings=new String[]{sqlString}; for (String fragment : strings) { sqlXml.append(fragment); sqlXml.append(" "); } SqlSource sqlSource=xmlLanguageDriver.createSqlSource(configuration, sqlXml.toString().trim(), Map.class); BoundSql boundSql=sqlSource.getBoundSql(parameters); final StringBuilder sql=new StringBuilder(boundSql.getSql()); if(parameters!=null&&!parameters.isEmpty()){ for (Object parameter:parameters.values()) { int start=sql.indexOf("?"); sql.replace(start,start+1,parameter.toString()); } } return sql.toString(); } /** * 带缓存sql,直接返回sql执行结果 * @param sqlString * @param apiId * @param param * @return */ public List<Map<String, Object>> query(String sqlString,Long apiId, Map<String,Object> param){ String mastpId="sql."+apiId; MybatisConfiguration configuration=(MybatisConfiguration)sqlSessionFactory.getConfiguration(); if(!configuration.hasStatement(mastpId)){ // String[] strings=new String[]{"<script>select " + // " role_id as id, " + // " name, " + // " description " + // " from sys_role " + // " where 1=1 " + // " <if test="name != null and name != ‘‘"> " + // " and name LIKE CONCAT(‘%‘, #{name},‘%‘) " + // " " + // " </if></script>"}; LanguageDriver xmlLanguageDriver=new XMLLanguageDriver(); final StringBuilder sql = new StringBuilder(); String[]strings=new String[]{sqlString}; for (String fragment : strings) { sql.append(fragment); sql.append(" "); } SqlSource sqlSource=xmlLanguageDriver.createSqlSource(configuration, sql.toString().trim(), Map.class); BoundSql boundSql=sqlSource.getBoundSql(param); MappedStatement ms = new MappedStatement.Builder(configuration, mastpId, sqlSource, SqlCommandType.SELECT) .resultMaps(new ArrayList<ResultMap>() { { add(new ResultMap.Builder(configuration, "defaultResultMap", Map.class, new ArrayList<>(0)) .build()); } }).build(); // 缓存 configuration.addMappedStatement(ms); } DefaultSqlSession defaultSqlSession=(DefaultSqlSession)sqlSessionFactory.openSession(); List<Map<String, Object>> resutls=defaultSqlSession.selectList(mastpId,param); return resutls; } }
执行:
注入SqlSourceUtil
@Autowired private SqlSourceUtil sqlSourceUtil;
调用:
public static void sqlTest() { //按照Mybatis xml的方式写sql StringBuffer sb=new StringBuffer(); sb.append("<script>select "); sb.append(" role_id as id, "); sb.append("name, "); sb.append("description "); sb.append("from sys_role "); sb.append("where 1=1 "); sb.append("<if test="name != null and name != ‘‘"> "); sb.append("and name LIKE CONCAT(‘%‘, #{name},‘%‘) "); sb.append("</if></script>"); Map<String,Object> parameters=new HashMap<>(); parameters.put("name","test"); //拼接sql String s = sqlSourceUtil.sqlSource(sb.toString(), parameters); System.out.println(s); //执行sql,并缓存sql,直接返回执行结果 Long cacheId=1L;//缓存id,唯一 List<Map<String, Object>> query = sqlSourceUtil.query(sb.toString(), cacheId, parameters); System.out.println(query.toArray().toString()); }
以上是关于使用mybatis动态执行SQL的主要内容,如果未能解决你的问题,请参考以下文章
Mybatis -- 动态Sql概述动态Sql之<if>(包含<where>)动态Sql之<foreach>sql片段抽取
[mybatis]动态sql_sql_抽取可重用的sql片段