package com.dx.efuwu.core

 import org.apache.commons.lang.StringUtils
import java.sql.PreparedStatement /**
* sql 模板处理
* @author sunzq
* 2017/06/02
*/ /**
* 查询的一个条件句
*/
class QueryBranch(val content: String, val key: String, val type: String) { override fun toString(): String {
return "{content:$content, key:$key, type: $type}"
} fun build(input: String?): String {
return if (StringUtils.isNotBlank(input)) content.replace("""(?:#|##|@|@@)\{.*}""".toRegex(), replacement = "?")
else if (type.length > ) " 1=0 "
else " 1=1 "
} fun doSetParameter(input: String?, index: Int, pstmt: PreparedStatement): Boolean {
input?.takeIf {
StringUtils.isNotBlank(it)
}?.run {
when (type) {
"#", "##" -> pstmt.setString(index, input)
"@", "@@" -> pstmt.setLong(index, input.toLong())
}
return true
}
return false
} } /**
* sql 查询模板处理器,并不提供 sql 是否正确的解析.
* @ 原样填写,不自动填充单引号, 为空则 true @@ 为空则 false
* # 自动包一下引号, 为空则 true ## 为空则 false
*/
class SQLTemplateExecutor(sql: String) { /**
* 查询条件句
*/
val queryBranches = ArrayList<QueryBranch>() /**
* 切割后的查询 sql
*/
val splitQueryStrings = ArrayList<String>() init {
val _sql = sql.replace("""\n""".toRegex(), " ")
val regex = """\b\S+(?:\s|=|>|<|in|not|like|IN|NOT|LIKE)+(#|##|@|@@)\{([^}]+)}""".toRegex()
splitQueryStrings.addAll(_sql.split(regex))
regex.findAll(_sql).iterator().forEach { matchResult ->
matchResult.groupValues.apply {
queryBranches.add(QueryBranch(content = get(), key = get().trim(), type = get()))
}
}
} fun doQuery(dict: Map<String, String?>): ArrayList<Map<String, Any>> {
val sqlBuilder = StringBuilder()
val queryBranchIterator = queryBranches.iterator()
splitQueryStrings.forEach { queryString ->
sqlBuilder.append(queryString)
if (queryBranchIterator.hasNext()) {
queryBranchIterator.next().apply {
sqlBuilder.append(build(dict[key]))
}
}
} val queryResults = ArrayList<Map<String, Any>>()
SQL_SERVER_DATA_SOURCE.connection.apply {
prepareStatement(sqlBuilder.toString()).apply {
// 设置查询参数
var paramIndex =
queryBranches.forEach { queryBranch ->
val param = dict[queryBranch.key]
if (queryBranch.doSetParameter(param, paramIndex, this)) {
paramIndex++
}
}
// 执行查询
executeQuery().apply {
while (next()) {
val result = HashMap<String, Any>()
metaData.apply {
(..columnCount).forEach { i ->
result[getColumnLabel(i)] =
when (getColumnTypeName(i)) {
"int" -> getInt(i)
else -> getString(i)
}
}
}
queryResults.add(result)
}
close()
}
close()
}
close()
}
return queryResults
}
} fun main(args: Array<String>) {
val sql = """select * from test"""
println(SQLTemplateExecutor(sql).doQuery(hashMapOf(
"userName1" to "大%",
"age" to "",
"s2" to "hello,world",
"userId" to ""
)))
}

kotlin 写的一个简单 sql 查询解析器的更多相关文章

  1. 简单sql字段解析器实现参考

    用例:有一段sql语句,我们需要从中截取出所有字段部分,以便进行后续的类型推断,请给出此解析方法. 想来很简单吧,因为 sql 中的字段列表,使用方式有限,比如 a as b, a, a b... 1 ...

  2. 自己动手实现一个简单的JSON解析器

    1. 背景 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着诸多优点.比如易读性更好,占用空间更少等.在 ...

  3. 一个简单的json解析器

    实现一个简单地json解析器. 两部分组成,词法分析.语法分析 词法分析 package com.mahuan.json; import java.util.LinkedList; import ja ...

  4. 用c#自己实现一个简单的JSON解析器

    一.JSON格式介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着很多优点.例如易读性更好,占用空间更 ...

  5. 使用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(一)

    梳理下使用spring+springMVC+mybatis 整合后的一个简单实例:输入用户的 ID,之后显示用户的信息(此次由于篇幅问题,会分几次进行说明,此次是工程的创建,逆向生成文件以及这个简单查 ...

  6. 使用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(三)(错误整理篇)

    使用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(一) 使用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(二) 以上两篇已经把流 ...

  7. 使用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(二)(代码篇)

    这篇是上一篇的延续: 用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(一) 源代码在github上可以下载,地址:https://github.com/guoxia ...

  8. c# 怎样能写个sql的解析器

    c# 怎样能写个sql的解析器 本示例主要是讲明sql解析的原理,真实的源代码下查看 sql解析器源代码 详细示例DEMO 请查看demo代码 前言 阅读本文需要有一定正则表达式基础 正则表达式基础教 ...

  9. 只是一个用EF写的一个简单的分页方法而已

    只是一个用EF写的一个简单的分页方法而已 慢慢的写吧.比如,第一步,先把所有数据查询出来吧. //第一步. public IQueryable<UserInfo> LoadPagesFor ...

随机推荐

  1. 【bzoj3997】[TJOI2015]组合数学 Dilworth定理结论题+dp

    题目描述 给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右走.问至少走多少次才能将财宝捡完.此对此问题变形,假设每个格子中有好多财宝,而每一次经过一个格子至多只能捡走一块财宝,至少走 ...

  2. [bzoj4860] [BeiJing2017]树的难题

    Description 给你一棵 n 个点的无根树.树上的每条边具有颜色. 一共有 m 种颜色,编号为 1 到 m.第 i 种颜色的权值为 ci.对于一条树上的简单路径,路径上经过的所有边按顺序组成一 ...

  3. [洛谷P1951]收费站_NOI导刊2009提高(2)

    题目大意:有一张$n$个点$m$条边的图,每个点有一个权值$w_i$,有边权,询问从$S$到$T$的路径中,边权和小于$s$,且$\max\limits_{路径经过k}\{w_i\}$最小,输出这个最 ...

  4. 周记【距gdoi:105天】

    月考果然很可怕,跪得要死. 然后这周搞(被老师坑)去搞某个程序,我和蔡大神和kpm分工搞(结果最后我也只是变成全程嘴炮). 这周有点闷,明明想快乐点但还是…… 进度慢得要死,后缀数组略神的东西.模仿了 ...

  5. 【BZOJ 4565】 [Haoi2016]字符合并 区间dp+状压

    考试的时候由于总是搞这道题导致爆零~~~~~(神™倒序难度.....) 考试的时候想着想着想用状压,但是觉得不行又想用区间dp,然而正解是状压着搞区间,这充分说明了一件事,状压不是只是一种dp而是一种 ...

  6. [NOIP2016]换教室 期望dp

    先弗洛伊德,然后把状态拆分遗传 #include<iostream> #include<cstdio> #include<cstring> #include< ...

  7. HTML5 Canvas圣诞树

    又逢圣诞了,为了让小站NowaMagic有点节日气氛,这里也弄一棵圣诞树放放-大家可以先看下效果. 效果演示 <canvas id="c"></canvas> ...

  8. Substrings Sort string 基本操作

    You are given nn strings. Each string consists of lowercase English letters. Rearrange (reorder) the ...

  9. 固定width但是有间隔

    <!DOCTYPE > <html> <head> <title></title> <meta name="name&quo ...

  10. css sprite应用

    (一)实现简单的淘宝带图标侧边栏效果 <!DOCTYPE html> <html lang="en"> <head> <meta char ...