IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 如何在代码里优雅的拼接SQL -> 正文阅读

[大数据]如何在代码里优雅的拼接SQL

刚进入这行业的时候,最早的时候用ADO,后来又出了各种ORM,在用了很多年后,还是觉得手写SQL最舒服,也最灵活。在各种对比后本人选择了Dapper,选择的理由是够轻量,性能好。

不管你用什么数据库框架,都会涉及到拼接SQL,可能你会说EF里不用拼接SQL,那你也得组装Expression对吧

不管你用什么工具,肯定避不开的一个就是拼接SQL,如果遇到稍复杂的逻辑,拼接SQL就很乱,可读性非常的差,如下:

//比较常见的拼接方式
var name = "jason";
var gender = 1;
var age = 18;
var sql = new StringBuilder("select * from tb where 0 = 0");
if (!string.IsNullOrWhiteSpace(name))
    sql.Append(" and name=@name");
if (gender > 0)
    sql.Append(" and gender=@gender");
if (age > 0)
    sql.Append(" and age=@age");

或者

 var name = "jason";
 var gender = 1;
 var age = 18;
 var sql = $"select * from tb where 0=0 {(!string.IsNullOrWhiteSpace(name) ? " and name=@name" : "")} {(age > 0 ? " and age=@age" : "")} {(gender > 0 ? " and gender=@gender" : "")}";

我相信上面的写法很多人都写过,我也这么写了很多年,当你遇到比较复杂的逻辑时,这种写法可读性非常的差,别特是条件非常多的时候。后来我就想有没有什么方式,既能灵活的拼接,又有很好的可读性呢?如果要有很好的可读性,那么SQL的拼接不能放在多个条件里拼接,看到的就是一条完整的SQL语句。思考后,我写一个扩展方法,先看如何使用

var sql="select * from tb where 0=0 {and name=@name} {and gender=@gender} {and age=@age}".Splice(!string.IsNullOrWhiteSpace(name),gender>0,age>0);

用法其实有点像string.Format,每一对大括号里的字符串,是否需要,根据Splice里的对应的第几个参数是一一对应的,你看见的SQL是一个完整的SQL语句,并且支持if…else:

var status=false;
var sql="select * from tb where status={1:0}".Splice(status);
//拼出的sql为:select * from tb where status=0

大括号内,用冒号分开,当对应参数为True时,将使用冒号前面部分,否则使用冒号的后面部分

您已经看到这里了,您觉得这样拼接是否是比上面的方式更具有可读性呢?

下面直接上实现代码,非常简单

public static string Splice(this string sql, params bool[] conditions)
{
     var startIndex = 0;
     foreach (var condition in conditions)
     {
         var start = sql.IndexOf('{', startIndex);
         if (start < 0)
             return sql;
         var end = sql.IndexOf('}', start);
         if (end < 0)
             return sql;
         startIndex = end;

         var elseIndex = sql.IndexOf(':', start, end - start);
         if (elseIndex < 0)
         {
             if (condition)
             {
                 sql = sql.Remove(start, 1).Remove(end - 1, 1);
                 startIndex -= 2;
             }
             else
             {
                 var count = end - start + 1;
                 sql = sql.Remove(start, count);
                 startIndex -= count;
             }
         }
         else
         {
             if (condition)
             {
                 var count = end - elseIndex + 1;
                 sql = sql.Remove(start, 1).Remove(elseIndex - 1, count);
                 startIndex -= count;
             }
             else
             {
                 var count = elseIndex - start + 1;
                 sql = sql.Remove(start, count).Remove(end - count, 1);
                 startIndex -= count;
             }
         }
     }
     return sql;
 }

也许您觉得条件多了,可读性也不好,第几个参数对应到的第几个{}呢?是的,确实有这个问题存在,但至少比前面的拼接方式的可读性好很多,我也打算自己写一个VS的VSIX扩展插件,当光标移动到Splice里的第几个参数上,前面对应的{}部分就高亮,但是不太熟悉VSIX的开发,所以迟迟没有进行。

本人对Dapper进行了封装,支持不同数据库,集成了缓存支持,性能监控,也集成了上面的拼接方法,GitHub库:
https://github.com/1100100/Dapper.Extensions
如果您有更好的拼接方式,欢迎分享出来,如果您会开发VSIX扩展,可以提一个PR,感谢您的阅读。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-11-30 15:41:10  更:2021-11-30 15:43:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:50:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码