背景

  Orm用过一些,但处理增删改上面做的都不错。但是查询上跟我想要的效果总是差了一点。我想要的效果则是这样,基于某种命名规则进行传参,后台解析器知道命名规则即可知道它要查询什么样的数据。

  谈谈我之前的做法,比如说,页面将查询条件存入对象,序列化后后传递给控制器,此时控制器将其反序列化成Json,数据类型使用Dictionary<string,object>。里面存储的Key目前是这样的格式: BeginTime, EndTime, Age, LikeAddress , NullTel , UnLikeMM , 其中 Begin End Like UnLike Null 等是自定义的命名规则,告诉后台我需要查询的数据类型,具体的含义看前缀大致即可知道。如传入BeginTime=2013-10-31 21:55:47,希望得到时间大于这个值的数。

  当时后台则是尝试去判断每一个值,如使用 Dictionary.TryGetValue("BeginTime",out obj) , 来进行条件的传值判断。这个地方还存在一个类型问题,时间到了后台变成了时间字符串,而不是DateTime类型。此处则需要强制转换。也正式因为这些原因,代码写的不大工整,尽管做了一些封装,稍微简洁点,但还不是我要的效果。

  以此为主题,写了一个初步的实现,希望各位朋友能给出部分建议,如果有类似的成熟的框架,能让我在后台定义个SQL之后,前端只要传入规定的命名字段,即可完成查询,这样是再好不过了。

测试效果

            var strSql = "select * from Users where ";
var dic = new Dictionary<string, object>();
dic["BeginAge"] = "";//Age>=18
dic["EndAge"] = ;//Age<=80
dic["LikeName"] = "玲";//Name包含'玲'
dic["IsGirl"] = "true";//IsGirl = true
dic["BeginLoginTime"] = DateTime.Now.AddDays(-);//LoginTime >= 七天前
dic["EndLoginTime"] = DateTime.Now.ToString();//LoginTime <= 今天
//部分类型若不正确,则需要手动映射
SqlMapper mapper = new SqlMapper(dic);
mapper.LoadTypeMapper<DateTime>("LoginTime");
mapper.LoadTypeMapper<int>("Age");
mapper.LoadTypeMapper<bool>("IsGirl");
//看看生成的条件语句
var where = mapper.Where();
Console.WriteLine("{0} {1}", strSql, where);
Console.WriteLine();

  

  目前的效果则如图,得到对应的SQL语句,并且将数据类型转换正确。

  我们在看看复杂的查询。

            strSql = "select * from Table1 t1 inner join Table2 t2 on t1.ID=t2.Table1ID where ";
dic["t1.UserName"] = "admin";//UserName='admin'
dic["t1.BeginAge"] = ;//Age>=18
dic["t1.EndAge"] = "";//Age<=80
dic["t1.NullSex"] = "false";//Sex is not null
dic["t1.NullNice"] = "true";//Nice is true
dic["t2.LikeHomeName"] = "中国";//HomeName like '%中国%'
dic["t2.UnLikeAddress"] = "郊区";//Address not like '%郊区%'
dic["t2.BeginCreateTime"] = DateTime.Now.ToString();//CreateTime >= DateTime.Now
mapper = new SqlMapper(dic);
mapper.LoadTypeMapper<DateTime>("CreateTime");
mapper.LoadTypeMapper<int>("Age");
mapper.LoadTypeMapper<bool>("Sex");
where = mapper.Where();
Console.WriteLine("{0} {1}", strSql, where);
Console.WriteLine();
//看看格式化后的Dictionary
foreach (var e in dic)
{
Console.WriteLine("{0}:{1} {2}", e.Key, e.Value, e.Value.GetType());
}

    

    我想要的效果,大致就是这样,由于是测试代码,所以直接构造了Dictionary,并且写入了对应的数据(类型有正确有错误)。

    实现方式很简单,则是遍历Dictionary,根据命名规则定义的前缀,来拼接SQL语句,并且检测当前类型,如果是string类型,则需要和映射的类型匹配一下,不相同,则将string类型转换成Mapper中映射的类型。

    最后在重申一下我想达到的目的,后台定义SQL语句,如Select ....,方法接收Dictionary参数,解析后传递给ado或者orm去执行,如此一来,前端想查询什么样的数据,只需要定义条件就好了。

  测试代码下载

    

理想中的SQL语句条件拼接方式的更多相关文章

  1. 理想中的SQL语句条件拼接方式 (二)

    问题以及想要的效果,不重复叙述,如果需要的请先看 理想中的SQL语句条件拼接方式 . 效果 现在有2个类映射数据库的2张表,结构如下: public class User { public int U ...

  2. MyBatis中动态SQL语句完成多条件查询

    一看这标题,我都感觉到是mybatis在动态SQL语句中的多条件查询是多么的强大,不仅让我们用SQL语句完成了对数据库的操作:还通过一些条件选择语句让我们SQL的多条件.动态查询更加容易.简洁.直观. ...

  3. [转帖]关于Java中SQL语句的拼接规则

    关于Java中SQL语句的拼接规则 自学demo 的时候遇到的问题 结果应该是 '"+e.getName()+"' 注意 一共有三组标点符号 (除去 方法函数后面的括号) 实现目标 ...

  4. 在Excel中使用SQL语句查询和筛选

    本文转自:http://blog.sina.com.cn/s/blog_5fc375650102e1g5.html 今天在微博上看到@数据分析精选 分享的一篇文章,是关于<在Excel中使用SQ ...

  5. [转]在EntityFramework6中执行SQL语句

    本文转自:http://www.cnblogs.com/wujingtao/p/5412329.html 在上一节中我介绍了如何使用EF6对数据库实现CRDU以及事务,我们没有写一句SQL就完成了所有 ...

  6. sql语句分页多种方式ROW_NUMBER()OVER

    sql语句分页多种方式ROW_NUMBER()OVER 摘自: http://www.cnblogs.com/CodingArt/articles/1692468.html 方式一 select to ...

  7. 在EntityFramework6中执行SQL语句

    在EntityFramework6中执行SQL语句 在上一节中我介绍了如何使用EF6对数据库实现CRDU以及事务,我们没有写一句SQL就完成了所有操作.这一节我来介绍一下如何使用在EF6中执行SQL语 ...

  8. 在EF中执行SQL语句(转载)

    在EF中执行SQL语句   你可能要问,我用EF不就为了避免写SQL吗?如果要写SQL我不如直接用ADO.NET得了.话虽然这么说没错,可有些时候使用EF操作数据还是有一些不方便,例如让你根据条件删除 ...

  9. 在EntityFramework6中执行SQL语句【转】

    在上一节中我介绍了如何使用EF6对数据库实现CRDU以及事务,我们没有写一句SQL就完成了所有操作.这一节我来介绍一下如何使用在EF6中执行SQL语句. 你可能要问,我用EF不就为了避免写SQL吗?如 ...

随机推荐

  1. C++基础 inline 默认参数 函数占位参数 函数重载

    1. inline内联函数 内联函数用于替换宏, 实例: 其中宏和 ++ 连用有副作用. #include "iostream" using namespace std; #def ...

  2. Python os.walk() 简介

    Table of Contents 1. os.walk目录遍历 1.1. os.walk 1.2. 例子 1.2.1. 测试topdown 1.2.2. 运行时修改遍历目录 2. 参考资料 os.w ...

  3. 7 Vue.js实现loading1

    1 2 3 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter ...

  4. android gradle 给所有的buildFlavor 的versionName 增加一个后缀

    build里面有很多的productFlavors,我想要给所有的productFlavors 的versionName增加一个后缀比如:_20180323 怎么做?注意是所有的productFlav ...

  5. Robolectric

    今天学习了单元测试框架,Robolectric.初步感觉,可能我测试的少,没有感觉Robolectric能有多大的帮助.虽然可以帮助创建activity.可以模拟点击事件.可是有什么呢. 好吧,讲下使 ...

  6. Java中数据类型转换&基本类型变量和对象型变量

    1.Java的数据类型分为三大类 布尔型,字符型和数值型 其中数值型又分为整型和浮点型 2.Java的变量类型 布尔型 boolean 字符型 char 整型    byte,short,int,lo ...

  7. TCP close seq问题

    测试mt_hls一条流时,发现会话的时长总是对应不上. 仔细观察发现: 注意 1.包1735 (客户端) 发送FIN 请求,seq = 2435582428 2.包1736,1737,1738 (服务 ...

  8. 让菜鸡讲一讲费用流(EK)

    让我再讲一个故事吧. 又有一些小精灵要准备从银月城(S)迁徙到Nibel山(T). 这两个地方之间的道路构成了一个网络. 每个道路都有它自己的容量,这决定了每天有多少小精灵可以同时从这儿通过. 和上一 ...

  9. iOS笔记060 - 自定义控件

    自定义tabBar 系统自带的tabBar不能满足需求 自己定义UITabBar 自定义一个类继承自UITabBar 实现initWithFrame和layoutSubviews方法即可. //#im ...

  10. 用Chrome浏览器,学会这27个超好用功能

    一些非常有用的隐藏捷径 1. 想要在后台打开一个新的标签页而不离开现有的页面,这样就不会打断目前的工作了?按住 Ctrl 键或 Cmd 并点击它.如果你要在一个全新的窗口中打开一个链接,那就按 Shi ...