kotlin 写的一个简单 sql 查询解析器

  1 package com.dx.efuwu.core
  2
  3 import org.apache.commons.lang.StringUtils
  4 import java.sql.PreparedStatement
  5
  6 /**
  7  * sql 模板处理
  8  * @author sunzq
  9  * 2017/06/02
 10  */
 11
 12 /**
 13  * 查询的一个条件句
 14  */
 15 class QueryBranch(val content: String, val key: String, val type: String) {
 16
 17     override fun toString(): String {
 18         return "{content:$content, key:$key, type: $type}"
 19     }
 20
 21     fun build(input: String?): String {
 22         return if (StringUtils.isNotBlank(input)) content.replace("""(?:#|##|@|@@)\{.*}""".toRegex(), replacement = "?")
 23         else if (type.length > 1) " 1=0 "
 24         else " 1=1 "
 25     }
 26
 27     fun doSetParameter(input: String?, index: Int, pstmt: PreparedStatement): Boolean {
 28         input?.takeIf {
 29             StringUtils.isNotBlank(it)
 30         }?.run {
 31             when (type) {
 32                 "#", "##" -> pstmt.setString(index, input)
 33                 "@", "@@" -> pstmt.setLong(index, input.toLong())
 34             }
 35             return true
 36         }
 37         return false
 38     }
 39
 40 }
 41
 42
 43 /**
 44  * sql 查询模板处理器,并不提供 sql 是否正确的解析.
 45  * @ 原样填写,不自动填充单引号, 为空则 true @@ 为空则 false
 46  * # 自动包一下引号, 为空则 true  ## 为空则 false
 47  */
 48 class SQLTemplateExecutor(sql: String) {
 49
 50
 51     /**
 52      * 查询条件句
 53      */
 54     val queryBranches = ArrayList<QueryBranch>()
 55
 56     /**
 57      * 切割后的查询 sql
 58      */
 59     val splitQueryStrings = ArrayList<String>()
 60
 61     init {
 62         val _sql = sql.replace("""\n""".toRegex(), " ")
 63         val regex = """\b\S+(?:\s|=|>|<|in|not|like|IN|NOT|LIKE)+(#|##|@|@@)\{([^}]+)}""".toRegex()
 64         splitQueryStrings.addAll(_sql.split(regex))
 65         regex.findAll(_sql).iterator().forEach { matchResult ->
 66             matchResult.groupValues.apply {
 67                 queryBranches.add(QueryBranch(content = get(0), key = get(2).trim(), type = get(1)))
 68             }
 69         }
 70     }
 71
 72     fun doQuery(dict: Map<String, String?>): ArrayList<Map<String, Any>> {
 73         val sqlBuilder = StringBuilder()
 74         val queryBranchIterator = queryBranches.iterator()
 75         splitQueryStrings.forEach { queryString ->
 76             sqlBuilder.append(queryString)
 77             if (queryBranchIterator.hasNext()) {
 78                 queryBranchIterator.next().apply {
 79                     sqlBuilder.append(build(dict[key]))
 80                 }
 81             }
 82         }
 83
 84         val queryResults = ArrayList<Map<String, Any>>()
 85         SQL_SERVER_DATA_SOURCE.connection.apply {
 86             prepareStatement(sqlBuilder.toString()).apply {
 87                 // 设置查询参数
 88                 var paramIndex = 1
 89                 queryBranches.forEach { queryBranch ->
 90                     val param = dict[queryBranch.key]
 91                     if (queryBranch.doSetParameter(param, paramIndex, this)) {
 92                         paramIndex++
 93                     }
 94                 }
 95                 // 执行查询
 96                 executeQuery().apply {
 97                     while (next()) {
 98                         val result = HashMap<String, Any>(8)
 99                         metaData.apply {
100                             (1..columnCount).forEach { i ->
101                                 result[getColumnLabel(i)] =
102                                         when (getColumnTypeName(i)) {
103                                             "int" -> getInt(i)
104                                             else -> getString(i)
105                                         }
106                             }
107                         }
108                         queryResults.add(result)
109                     }
110                     close()
111                 }
112                 close()
113             }
114             close()
115         }
116         return queryResults
117     }
118 }
119
120 fun main(args: Array<String>) {
121     val sql = """select * from test"""
122     println(SQLTemplateExecutor(sql).doQuery(hashMapOf(
123             "userName1" to "大%",
124             "age" to "18",
125             "s2" to "hello,world",
126             "userId" to "10000"
127     )))
128 }
时间: 2024-10-17 14:10:21

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

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

1. 背景 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着诸多优点.比如易读性更好,占用空间更少等.在 web 应用开发领域内,得益于 JavaScript 对 JSON 提供的良好支持,JSON 要比 XML 更受开发人员青睐.所以作为开发人员,如果有兴趣的话,还是应该深入了解一下 JSON 相关的知识.本着探究 JSON 原理的目的,我将会在这篇文章中详细向大家介绍一个简单的JSON解析器的解析流

用qt写的一个简单到不能在简单的上位机

学QT时,写的一个简单得不能再简单的串口上位机,用来控制单片机上的2个LED.假设一个是只有开和关的状态.一个可以调节亮度.上位机的界面如下图: 其中,波特率,数据位,停止位下拉值在设计师里面添加.剩下的功能,基本由代码实现.通信使用的协议也是随便写的.很简单和随意.图片是老弟手绘的. 下面贴代码 (*^__^*) #include "mainwindow.h" #include "ui_mainwindow.h" #include <QtSerialPort

虚幻4,BP写了一个简单的三线跑酷工程

BP写了一个简单的三线跑酷 链接: http://pan.baidu.com/s/1jILE4V8 密码: 96ua

java写的一个简单学生管理系统[改进]

用Java写的一个简单学生管理系统 import java.util.*; public class student_cj {  public static void main(String[] args){      Scanner in=new Scanner(System.in);   System.out.print("请输入学生人数:");   int num=in.nextInt();//学生人数   String[] str=new String[num];//结合一行数

写了一个简单的CGI Server

之前看过一些开源程序的源码,也略微知道些Apache的CGI处理程序架构,于是用了一周时间,用C写了一个简单的CGI Server,代码算上头文件,一共1200行左右,难度中等偏上,小伙伴可以仔细看看,对于学生来说,拿来当简历,含金量还是足够的.如果把程序里所涉及的HTTP协议,Linux下POSIX编程等等搞清楚,我想找工作中肯定是有足够的竞争力的,当然我也只是皮毛而已,不再班门弄斧了,下面简单的说下程序流程吧,方便小伙伴们阅读. 程序源代码:戳我 在说程序流程之前,我先简单说下CGI吧,CG

写的一个简单定时器(非独立线程)

//Callback.h #ifndef __CALLBACK_H__ #define __CALLBACK_H__ typedef void (*T_CallBack)(void *); typedef struct { T_CallBack cb; void *obj; }ST_CallBack; int __NewTimer(void* obj, int interval, bool isloop, T_CallBack cb); void __DeleteTimer(int handle

写了一个简单可用的IOC

根据<架构探险从零开始写javaweb框架>内容写的一个简单的 IOC 学习记录    只说明了主要的类,从上到下执行的流程,需要分清主次,无法每个类都说明,只是把整个主线流程说清楚,避免陷入细节中.学习过程最大的收获,框架也是人写的,没学过感觉很神秘高端.现在看来大概率是,未知往往觉得是高不可攀.http://naotu.baidu.com/file/6c3da879a4495b6bd369f71dcb726f05?token=ed8c0d49d4ee7bbd 原文地址:https://ww

MySQL技术探索01实现SQL语法解析器

本文将介绍如何使用开源的语法和词法分析框架bison和flex来实现SQL解析器.出于技术学习的目的,本文做描述的微型SQL解析器仅能实现对微型SQL的语法解析. 1.MySQL中的SQL解析器 包括JDBC.ODBC.ADO等等关系数据库客户端应用开发框架在内的各种SDK,核心功能是帮助程序员简化各种客户端的数据库操作,同时将SQL语句通过网络形式发送给MySQL等关系数据库的服务器进程.MySQL服务器进行负责解析并执行这些SQL语句.SQL语句中的语法规则多种多样,MySQL服务器是如何实

Arachnid包含一个简单的HTML剖析器能够分析包含HTML内容的输入流

Arachnid是一个基于Java的web spider框架.它包含一个简单的HTML剖析器能够分析包含HTML内容的输入流.通过实现Arachnid的子类就能够开发一个简单的Web spiders并能够在Web站上的每个页面被解析之后增加几行代码调用. Arachnid的下载包中包含两个spider应用程序例子用于演示如何使用该框架. http://sourceforge.net/projects/arachnid/