理想中的SQL語句條件拼接方式

背景

  Orm用過一些,但處理增刪改上面作的都不錯。可是查詢上跟我想要的效果老是差了一點。我想要的效果則是這樣,基於某種命名規則進行傳參,後臺解析器知道命名規則便可知道它要查詢什麼樣的數據。前端

  談談我以前的作法,好比說,頁面將查詢條件存入對象,序列化後後傳遞給控制器,此時控制器將其反序列化成Json,數據類型使用Dictionary<string,object>。裏面存儲的Key目前是這樣的格式: BeginTime, EndTime, Age, LikeAddress , NullTel , UnLikeMM , 其中 Begin End Like UnLike Null 等是自定義的命名規則,告訴後臺我須要查詢的數據類型,具體的含義看前綴大體便可知道。如傳入BeginTime=2013-10-31 21:55:47,但願獲得時間大於這個值的數。app

  當時後臺則是嘗試去判斷每個值,如使用 Dictionary.TryGetValue("BeginTime",out obj) , 來進行條件的傳值判斷。這個地方還存在一個類型問題,時間到了後臺變成了時間字符串,而不是DateTime類型。此處則須要強制轉換。也正式由於這些緣由,代碼寫的不大工整,儘管作了一些封裝,稍微簡潔點,但還不是我要的效果。框架

  以此爲主題,寫了一個初步的實現,但願各位朋友能給出部分建議,若是有相似的成熟的框架,能讓我在後臺定義個SQL以後,前端只要傳入規定的命名字段,便可完成查詢,這樣是再好不過了。測試

測試效果

            var strSql = "select * from Users where ";
            var dic = new Dictionary<string, object>();
            dic["BeginAge"] = "18";//Age>=18
            dic["EndAge"] = 80;//Age<=80
            dic["LikeName"] = "";//Name包含'玲'
            dic["IsGirl"] = "true";//IsGirl = true 
            dic["BeginLoginTime"] = DateTime.Now.AddDays(-7);//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語句,而且將數據類型轉換正確。ui

  咱們在看看複雜的查詢。spa

            strSql = "select * from Table1 t1 inner join Table2 t2 on t1.ID=t2.Table1ID where ";
            dic["t1.UserName"] = "admin";//UserName='admin'
            dic["t1.BeginAge"] = 18;//Age>=18
            dic["t1.EndAge"] = "80";//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,而且寫入了對應的數據(類型有正確有錯誤)。code

 

    實現方式很簡單,則是遍歷Dictionary,根據命名規則定義的前綴,來拼接SQL語句,而且檢測當前類型,若是是string類型,則須要和映射的類型匹配一下,不相同,則將string類型轉換成Mapper中映射的類型。orm

    最後在重申一下我想達到的目的,後臺定義SQL語句,如Select ....,方法接收Dictionary參數,解析後傳遞給ado或者orm去執行,如此一來,前端想查詢什麼樣的數據,只須要定義條件就行了。對象

 

  測試代碼下載blog

相關文章
相關標籤/搜索