Mybatisplus-动态获取sql字符串

记录贴

借助mybatisplus构建动态 SQL 查询语句的功能,来动态构建sql来做presto查询,这样就不用在代码里写sql了

getBoundSql 是 MyBatis 中 org.apache.ibatis.mapping.BoundSql 接口的方法,用于获取一个表示 SQL 语句和相关参数映射的对象。BoundSql 实例包含了预编译的 SQL 语句以及参数映射信息,可以用于执行数据库操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class DynamicSqlUtils {

@Autowired
private SqlSession sqlSession;

public String getSql(Class clz,String method, Object obj) {
Configuration configuration = sqlSession.getConfiguration();
MappedStatement ms = configuration.getMappedStatement(clz.getName() + "." + method);
BoundSql boundSql = ms.getBoundSql(obj);
String parsedSql = boundSql.getSql();
// #{}会被替换成? ,${}才会被替换成对应的值
// 获取参数映射
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
// 获取参数对象
Object parameterObject = boundSql.getParameterObject();
// 打印参数占位符和对应的参数值
for (ParameterMapping parameterMapping : parameterMappings) {
String property = parameterMapping.getProperty();
// 获取参数值
Object value = null;
if (boundSql.hasAdditionalParameter(property)) {
// 对于额外的参数,直接获取
value = boundSql.getAdditionalParameter(property);
} else if (parameterObject != null) {
// 对于参数对象,通过反射获取属性值
MetaObject metaObject = configuration.newMetaObject(parameterObject);
value = metaObject.getValue(property);
}
// 替换 SQL 语句中的占位符
parsedSql = parsedSql.replaceFirst("\\?", "'"+value.toString()+"'");
}
return parsedSql;
}
}
  • xml

    1
    2
    3
    4
    5
    6
    <select id="demoList" resultType="com.*.dto.DemoDTO">
    select * from t demo where 1=1
    <if test="form.status != null">
    and t.status = #{form.status}
    </if>
    </select>
  • mapper

    1
    2
    3
    4
    @Repository
    public interface DemoMapper extends BaseMapper<DemoEntity> {
    List<DemoDTO> demoList(@Param("form") DemoForm form);
    }
  • 调用

    值得注意的是,如果使用了@Param(“form”)给方法参数起别名,那么就要使用Map来包装一下map.put(“form”,原来的form对象),否则获取不到form

    1
    2
    3
    4
    5
    Map<String, Object> map = new HashMap<>();
    Map<String, Object> map2 = JSON.parseObject(JSON.toJSONString(demoForm), new TypeReference<Map<String, Object>>() {});
    map.put("form", map2);
    String sql=dynamicSqlUtils.getSql(DemoMapper.class, "demoList", map);
    //presto.query(sql) 或者 hive.query(sql)

Mybatisplus-动态获取sql字符串
https://cason.work/2023/12/11/Mybatisplus-动态获取sql字符串/
作者
Cason Mo
发布于
2023年12月11日
许可协议