通过 String 内容获取 SqlPara 对象

<pre>
例子：
String content = "select * from user where id = #para(0)";
SqlPara sqlPara = getSqlParaByString(content, 123);

特别注意：content 参数中不能包含 #sql 指令
</pre>
422045
public SqlPara getSqlParaByString(String content, Object... paras) {
		Template template = engine.getTemplateByString(content);
		
		SqlPara sqlPara = new SqlPara();
		Map data = new HashMap();
		data.put(SQL_PARA_KEY, sqlPara);
		data.put(PARA_ARRAY_KEY, paras);
		sqlPara.setSql(template.renderToString(data));
		// data 为本方法中创建，不会污染用户数据，无需移除 SQL_PARA_KEY、PARA_ARRAY_KEY
		return sqlPara;
	}
923871
public static ParsedSql parseSqlStatement(final String sql) {
        Assert.notNull(sql, "SQL must not be null");

        Set<String> namedParameters = new HashSet<>();
        String sqlToUse = sql;
        List<ParameterHolder> parameterList = new ArrayList<>();

        char[] statement = sql.toCharArray();
        int namedParameterCount = 0;
        int unnamedParameterCount = 0;
        int totalParameterCount = 0;

        int escapes = 0;
        int i = 0;
        while (i < statement.length) {
            int skipToPosition;
            while (i < statement.length) {
                skipToPosition = skipCommentsAndQuotes(statement, i);
                if (i == skipToPosition) {
                    break;
                } else {
                    i = skipToPosition;
                }
            }
            if (i >= statement.length) {
                break;
            }
            char c = statement[i];
            if (c == ':' || c == '&') {
                int j = i + 1;
                if (j < statement.length && statement[j] == ':' && c == ':') {
                    // Postgres-style "::" casting operator should be skipped
                    i = i + 2;
                    continue;
                }
                String parameter;
                if (j < statement.length && c == ':' && statement[j] == '{') {
                    // :{x} style parameter
                    while (j < statement.length && !('}' == statement[j])) {
                        j++;
                        if (':' == statement[j] || '{' == statement[j]) {
                            throw new CommonRuntimeException("Parameter name contains invalid character '" +
                                    statement[j] + "' at position " + i + " in statement: " + sql);
                        }
                    }
                    if (j >= statement.length) {
                        throw new CommonRuntimeException(
                                "Non-terminated named parameter declaration at position " + i + " in statement: " + sql);
                    }
                    if (j - i > 3) {
                        parameter = sql.substring(i + 2, j);
                        namedParameterCount = addNewNamedParameter(namedParameters, namedParameterCount, parameter);
                        totalParameterCount = addNamedParameter(parameterList, totalParameterCount, escapes, i, j + 1, parameter);
                    }
                    j++;
                } else {
                    while (j < statement.length && !isParameterSeparator(statement[j])) {
                        j++;
                    }
                    if (j - i > 1) {
                        parameter = sql.substring(i + 1, j);
                        namedParameterCount = addNewNamedParameter(namedParameters, namedParameterCount, parameter);
                        totalParameterCount = addNamedParameter(parameterList, totalParameterCount, escapes, i, j, parameter);
                    }
                }
                i = j - 1;
            } else {
                if (c == '\\') {
                    int j = i + 1;
                    if (j < statement.length && statement[j] == ':') {
                        // escaped ":" should be skipped
                        sqlToUse = sqlToUse.substring(0, i - escapes) + sqlToUse.substring(i - escapes + 1);
                        escapes++;
                        i = i + 2;
                        continue;
                    }
                }
                if (c == '?') {
                    int j = i + 1;
                    if (j < statement.length && (statement[j] == '?' || statement[j] == '|' || statement[j] == '&')) {
                        // Postgres-style "??", "?|", "?&" operator should be skipped
                        i = i + 2;
                        continue;
                    }
                    unnamedParameterCount++;
                    totalParameterCount++;
                }
            }
            i++;
        }

        ParsedSql parsedSql = new ParsedSql(sqlToUse);
        parsedSql.setParameterList(parameterList);
        parsedSql.setNamedParameterCount(namedParameterCount);
        parsedSql.setUnnamedParameterCount(unnamedParameterCount);
        parsedSql.setTotalParameterCount(totalParameterCount);
        return parsedSql;
    }
135972
protected String getQueryString() {
        if (bindings.size() == 0)
            return queryString;
        String qry = queryString;
        int b = qry.indexOf('{');
        String select = qry.substring(0, b);
        String where = qry.substring(b);
        for (String name : bindings.getBindingNames()) {
            String replacement = getReplacement(bindings.getValue(name));
            if (replacement != null) {
                String pattern = "[\\?\\$]" + name + "(?=\\W)";
                select = select.replaceAll(pattern, "");
                where = where.replaceAll(pattern, replacement);
            }
        }
        return select + where;
    }
481855
public static String adHocSQLStringFromPlannedStatement(AdHocPlannedStatement statement, Object[] userparams) {
        final int MAX_PARAM_LINE_CHARS = 120;

        StringBuilder sb = new StringBuilder();
        String sql = new String(statement.sql, Charsets.UTF_8);
        sb.append(sql);

        Object[] params = paramsForStatement(statement, userparams);
        // convert params to strings of a certain max length
        for (int i = 0; i < params.length; i++) {
            Object param = params[i];

            String paramLineStr = String.format("    Param %d: %s", i, param.toString());
            // trim param line if it's silly long
            if (paramLineStr.length() > MAX_PARAM_LINE_CHARS) {
                paramLineStr = paramLineStr.substring(0, MAX_PARAM_LINE_CHARS - 3);
                paramLineStr += "...";
            }

            sb.append('\n').append(paramLineStr);
        }

        return sb.toString();
    }
61820
protected static String generateQueryString(Map<String, Object> parameters) {
        if (parameters == null || parameters.size() == 0) {
            return "";
        }
        StringBuilder result = new StringBuilder();
        try {
            for(Map.Entry<String, Object> entry : parameters.entrySet()) {
                // Check to see if the key/value isn't null or empty string
                if (entry.getKey() != null && (entry.getValue() != null && !entry.getValue().toString().equals(""))) {
                    result.append('&').append(URLEncoder.encode(entry.getKey(), "utf-8")).append("=")
                            .append(URLEncoder.encode(entry.getValue().toString(), "utf-8"));
                }
            }
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }

        return result.length() == 0 ? "" : "?" + result.substring(1);
    }
475976
public static Map<String, byte[]> getBigData(String sql, Object... arg) {
        Map<String, byte[]> bigDataMap = new HashMap<String, byte[]>();
        Connection connection = JDBCUtils.getConnection();
        PreparedStatement ps = null;
        ResultSet result = null;

        // 填充占位符
        try {
            ps = connection.prepareStatement(sql);
            for (int i = 0; i < arg.length; i++) {
                ps.setObject(i + 1, arg[i]);
            }

            // 执行SQL语句
            result = ps.executeQuery();
            // 获取字段名
            List<String> columnList = DBUtils.getColumnLabels(result);
            // 遍历结果集
            while (result.next()) {
                // 遍历字段名获取相应大数据值
                for (String column : columnList) {
                    Blob data = result.getBlob(column);
                    byte[] datas = data.getBytes(1, (int) data.length());
                    bigDataMap.put(column, datas);
                }
                break;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.release(result, ps, connection);
        }

        return bigDataMap;
    }
8340
function CheckParams(data, query)
{
    for (let key in data) {
        let par = data[key];
        if(par.constructor!=Object)continue;//非
        let errkey = par.lbl?par.lbl:(par.rem?par.rem:key);//发生错误时的key的称呼方式
        if(par.constructor != Object){return `${errkey}接口文档定义错误。`}
        if (null==par.rem && null==par.lbl) {//这里则认为是两层及以上对象嵌套,递归
            if(par.need && null==query[key]){query[key]={};delete par.need;delete par.rem;delete par.lbl;}//如果需要的传外层的话,且为空时,默认给空对象
            let msg =CheckParams(data[key],query[key]);
            if(msg){return msg;}
        }else {
            //参数是否缺少
            if(!query){return 0;}
            let val = query[key];
            //检验必要的请求参数,非必要参数则不验证
            if (par.need&&null==val) {return`缺少${par.lbl?par.lbl:(par.rem?par.rem:key)}参数。`;}
            //若未传,且有默认值,则设置默认值,然后继续向下检验默认值
            if(null!=par.default&&null==val){query[key]=par.default;val = par.default;CTX.usedefault = true;}
            if(null!=par.def&&null==val){query[key]=par.def;val = par.def;CTX.usedefault = true;}
            if(null==val){continue;}//未传的非必须参数不需要校验
            //参数类型
            if(par.type) {
                let isObj=true;
                try{
                    switch(par.type.toLowerCase()){
                        case 'number':
                        case 'int':
                            if((par.type == 'number'||par.type =='int')&& parseInt(val)!=val)throw Error('类型错误');
                            query[key] = parseInt(val);
                            val = query[key];
                            break;
                        case 'float':
                            if(par.type == 'float' && parseFloat(val)!=val)throw Error('类型错误');
                            query[key] = parseFloat(val);
                            val = query[key];
                            break;
                        case 'string':if(val.constructor.name != 'String')throw Error('类型错误');break;
                        case 'boolean':
                            if(par.type == 'boolean'&&val.constructor!=Boolean&&(val.trim()!="false"&&val.trim()!="true"))throw Error('类型错误');
                            if(val.constructor!=Boolean)query[key]=(val.trim()==="false"?false:true);
                            val = query[key];
                            break;
                        case 'object':
                            if(val.constructor != Object){
                                try{
                                    val=JSON.parse(val);
                                }catch(err){isObj=false;}
                            }
                            if(!isObj)throw Error('类型错误');break;
                        case 'array':
                            if(val.constructor != Array){
                                try{
                                    val=JSON.parse(val);
                                }catch(err){isObj=false}
                            }
                            if(!isObj)throw Error('类型错误');break;
                        case 'array':if(val.constructor.name != 'Array')throw Error('类型错误');break;
                        case 'file':if(val.path && !isExist(val.path)) throw Error('类型错误');break;
                        case 'json':
                            try{
                                let t=JSON.parse(val);
                                query[key]=t;
                                val=t;
                            }catch(err){
                                throw Error('json格式错误');
                            }
                            break;
                        default :
                            if(val.constructor.name != 'String')throw Error('类型错误');
                    }
                }catch(err){return `${errkey}参数类型错误。`;}
            }
            let msg;
            //参数长度控制
            if(par.len){
                //接口文档在定义的时候定义为一个对象
                var ol = 0;
                let name = "长度";
                switch (par.type.toLowerCase()){
                    case 'array':
                        ol =  val.length;
                        name = "数组长度";
                        break;
                    case 'object'://数组或者对象
                        ol =  Object.keys(val).length;
                        name = "对象长度";
                        break;
                    case 'string':
                        ol = val.length;
                        name = "字符串长度";
                        break;
                    case 'file':
                        ol = val.size;//文件大小
                        name = "文件大小";
                        break;
                    default:
                        ol = val.length;
                        name = "字符串长度";
                        break;
                }
                if((msg=getRange(ol,par.len))){
                    return `${errkey}${name}${msg}${'file'==par.type?'字节':''}`;
                }
            }
            //范围控制
            if(par.range && (msg=getRange(val,par.range))){return `${errkey}${'string'==par.type?"字符内容":""}${msg}`;}
            //枚举型判断参数是否在设置范围内
            if (par.enum && par.enum.indexOf(val)<0) {return `${errkey}参数只能是${par.enum}。`;}
            //正则验证参数是否合法
            if(par.reg && !eval(par.reg).test((par.type == 'file' ? val.name:par.type=='json'?JSON.stringify(val):val))){return `${errkey}格式错误`;}
            // RES.usedefault = null;
        }
    }
    return 0;
}
407272
public static Object[] getSqlParams(String sqlPattern, Map map) {
        Object[] sqlParams = JdbcPatternUtil.getValues(JdbcPatternUtil.getCamelKeys(sqlPattern), map).toArray();
        for (int i = 0; i < sqlParams.length; i++) {
            if (sqlParams[i] instanceof Calendar) {//因为prepared statement不支持calendar类型,所以需要将其其中的calendar转为date
                sqlParams[i] = ((Calendar) sqlParams[i]).getTime();
            }
        }
        return sqlParams;
    }
1286643
private int getTotalCount(String sql, Connection conn, MappedStatement ms, BoundSql boundSql) throws SQLException {
    int start = sql.indexOf("from");
    if (start == -1) {
      throw new RuntimeException("statement has no 'from' keyword");
    }
    int stop = sql.indexOf("order by");
    if (stop == -1) {
      stop = sql.length();
    }

    String countSql = "select count(0) " + sql.substring(start, stop);
    BoundSql countBoundSql = new BoundSql(ms.getConfiguration(), countSql, boundSql.getParameterMappings(), boundSql.getParameterObject());
    ParameterHandler parameterHandler = new DefaultParameterHandler(ms, boundSql.getParameterObject(), countBoundSql);
    PreparedStatement stmt = null;
    ResultSet rs = null;
    int count = 0;
    try {
      stmt = conn.prepareStatement(countSql);
      // 通过parameterHandler给PreparedStatement对象设置参数
      parameterHandler.setParameters(stmt);
      rs = stmt.executeQuery();
      if (rs.next()) {
        count = rs.getInt(1);
      }
    } finally {
      CloseableUtil.closeQuietly(rs);
      CloseableUtil.closeQuietly(stmt);
    }
    return count;
  }
886618
public void createPreparedStatement(String query, List<Object> params) throws SQLException {

        m_preparedStatement = m_connection.prepareStatement(query);

        // Check the params
        if (params != null) {
            for (int i = 0; i < params.size(); i++) {
                Object item = params.get(i);

                // Check if the parameter is a string
                if (item instanceof String) {
                    m_preparedStatement.setString(i + 1, (String)item);
                }
                if (item instanceof Integer) {
                    Integer number = (Integer)item;
                    m_preparedStatement.setInt(i + 1, number.intValue());
                }
                if (item instanceof Long) {
                    Long longNumber = (Long)item;
                    m_preparedStatement.setLong(i + 1, longNumber.longValue());
                }

                // If item is none of types above set the statement to use the bytes
                if (!(item instanceof Integer) && !(item instanceof String) && !(item instanceof Long)) {
                    try {
                        m_preparedStatement.setBytes(i + 1, CmsDataTypeUtil.dataSerialize(item));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

    }
265313
public SqlPara getSqlPara(String key, Object... paras) {
		Template template = getSqlTemplate(key);
		if (template == null) {
			return null;
		}
		
		SqlPara sqlPara = new SqlPara();
		Map data = new HashMap();
		data.put(SQL_PARA_KEY, sqlPara);
		data.put(PARA_ARRAY_KEY, paras);
		sqlPara.setSql(template.renderToString(data));
		// data 为本方法中创建，不会污染用户数据，无需移除 SQL_PARA_KEY、PARA_ARRAY_KEY
		return sqlPara;
	}
871753
public function buildRequestParaToString($para_temp) {
        //待请求参数数组
        $para = $this->buildRequestPara($para_temp);

        //把参数组中所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串，并对字符串做urlencode编码
        $request_data = HelperFunction::createLinkstringUrlencode($para);

        return $request_data;
    }
1343346
private String replaceChoose(SqlObject sqlObj, Map<String, Object> parameters) {
		String query = null;
		if (sqlObj != null) {
			query = sqlObj.getValue();
			if (StringUtils.isNotEmpty(query)) {

				try {
					// 执行子句构建 子句格式为{statement}
					List<Choose> chooseList = sqlObj.getChoose();

					if (chooseList != null && parameters != null) {
						for (Choose choose : chooseList) {
							String condition = choose.getWhen();
							if (parameters.containsKey(condition)) {
								String statement = choose.getBlock();

								// 如果不存在statement参数，则使用when参数代替
								if (StringUtils.isEmpty(statement)) {
									statement = condition;
								}
								statement = "{" + statement + "}";

								if (StringUtils.contains(query, statement)) {
									query = query.replace(statement, choose.getValue());
								} else {
									query = query + " " + choose.getValue();
								}
							}
						}
					}

					// 清理没有被替换的子句
					String regexs = "[{](\\w*)[}]"; // 子句替换模式
					Pattern regex = Pattern.compile(regexs);
					Matcher regexMatcher = regex.matcher(query);
					while (regexMatcher.find()) {
						query = query.replace(regexMatcher.group(0), "");
					}

				} catch (Exception e) {

				}
			}
		}

		return query;
	}
576130
static String getSQL(Token[] statement) {

        boolean      wasDelimiter = true;
        StringBuffer sb           = new StringBuffer();

        for (int i = 0; i < statement.length; i++) {
            // when the previous statement is ')', there should be a blank before the non-delimiter statement.
            if (!statement[i].isDelimiter &&
                    (!wasDelimiter
                            || (i > 0 && ")".equals(statement[i - 1].getSQL()))))
            {
                sb.append(' ');
            }

            sb.append(statement[i].getSQL());

            wasDelimiter = statement[i].isDelimiter;
        }

        return sb.toString();
    }
1298334
public function toQueryString()
    {
        $queryString = '';
        $inString = false;
        $parameterIndex = 0;
        $length = strlen($this->statement);

        for ($i=0; $i < $length; $i++) {
            $char = $this->statement{$i};
            if ($char === '\'') {
                if ($inString && $this->statement{max(0, $i-1)} === '\\') {
                    $inString = true;
                } else {
                    $inString = !$inString;
                }
                $queryString .= $char;
            } elseif ($char === '?' && !$inString) {
                $parameterIndex ++;
                $queryString .= $this->parametersMap[$parameterIndex];
            } else {
                $queryString .= $char;
            }
        }

        return $queryString;
    }
408590
public function sql(string $fields = null, string $where = null, string $orderBy = null, string $limit = null): string
    {
        $this->statement->select($fields, $where, $orderBy, $limit);

        // 语句真正被创建
        $this->statement->create();

        // 返回相应的SQL语句
        return $this->statement->getSql();
    }
402007
public static <T> SqlParamsPairs getGetFromObject(Class<T> clazz,Object id) throws NoIdAnnotationFoundException, NoColumnAnnotationFoundException{
		
		//用来存放get语句
		StringBuffer getSql = new StringBuffer();
		
		//分析表名
		String tableName = getTableName(clazz);
		
		getSql.append("select * from " + tableName + " where ");
		
		//分析列
		Field[] fields = clazz.getDeclaredFields();
		Id idAnno = null;
		for (int i = 0; i < fields.length; i++) {
			Field f = fields[i];
			
			//找id字段
			Method getter = getGetter(clazz,f);
			
			if(getter == null){
				//没有get方法直接跳过
				continue;
			}
			
			//看是不是主键
			idAnno = getter.getAnnotation(Id.class);
			if(idAnno == null){
				continue;
			}
			
			//get column name
			String columnName = getColumnNameFromGetter(getter,f);

			getSql.append(columnName + " = ?");
			
			break;
		}
		
		//全部遍历完如果找不到主键就抛异常
		if(idAnno == null){
			throw new NoIdAnnotationFoundException(clazz);
		}
		
		SqlParamsPairs sqlAndParams = new SqlParamsPairs(getSql.toString(),new Object[]{id});
		logger.debug(sqlAndParams.toString());
		
		return sqlAndParams;
	}