使用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片段

mybatis学习(39):动态sql片段

MYBATIS05_ifwherechoosewhentrimsetforEach标签sql片段

Mybatis动态sql

MyBatis框架—动态 SQL配置文件事务