背景:最近在做一个类似于低代码平台的开发,碰到一个需求,基于数据库对外提供restful接口,其实这个需求的难点在于解析写好的sql,那么解析sql有什么好办法呢。下面分享一下我的做法。 做法:比如现在用户输入 select * from t where id = #{ID} AND name = #{NAME}.针对这个sql,我们需要解析出对应的条件ID和NAME.这样基于这个语句生成对外提供的restful接口,就需要用户传递两个参数分别为ID和NAME就可以了。我这边借助了mybatis能力解析对应的sql.
import lombok.Data;
import org.apache.ibatis.parsing.GenericTokenParser;
import org.apache.ibatis.parsing.TokenHandler;
import java.util.ArrayList;
import java.util.List;
@Data
public class BoundSql implements TokenHandler {
private String sql;
private List<String> parameterMappingList=new ArrayList<>();
public BoundSql() {
}
public BoundSql(String sql, List<String> parameterMappingList) {
this.sql = sql;
this.parameterMappingList = parameterMappingList;
}
@Override
public String handleToken(String content) {
parameterMappingList.add(content);
return "?";
}
/**
* 解析自定义占位符
* @param sql
* @return
*/
public static BoundSql getBoundSql(String sql){
BoundSql boundSql = new BoundSql();
GenericTokenParser genericTokenParser = new GenericTokenParser("#{","}",boundSql);
String parse = genericTokenParser.parse(sql);
return new BoundSql(parse,boundSql.getParameterMappingList());
}
public static void main(String[] args) {
// String sql = "select * from qq where id = #{appid} and qq = #{appName}";
String sql = "insert into qq (appod,disfs) values( #{appid},#{appName})";
BoundSql boundSql = getBoundSql(sql);
System.out.println(boundSql.sql);
}
}