C#製作ORM對映學習筆記二 配置類及Sql語句生成類
阿新 • • 發佈:2019-01-04
在正式開始實現ORM之前還有一點準備工作需要完成,第一是實現一個配置類,這個很簡單的就是通過靜態變數來儲存資料庫的一些連線資訊,等同於.net專案中的web.config的功能;第二需要設計實現一個sql語句的生成類來幫助生成sql語句,當前如果不實現這個類也不會影響orm的製作,之所以要做這麼一個類主要有幾個目的,1.減少sql語句中拼寫錯誤的發生。2.統一解決防sql注入的問題。
下面分別說明一下這兩個類的實現方式:
1.配置類DbConfig
2.sql語句的生成類Sqlusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ORM { public class DbConfig { /// <summary> /// 資料庫連線資訊 /// </summary> public static string Host = "D:/C#/ORM/test.db"; /// <summary> /// 資料庫型別 /// </summary> public static DbType Type = DbType.Sqlite; } public enum DbType { Sqlite, Mysql, SqlServer, Oracle } }
到這裡ORM的前期準備工作就完成了,當然Sql實現的非常簡單,像inner join、left join等sql語句的幫助生成函式都沒有做,但是實現原理時相同的,如果需要可以自己仿照實現,當然也可以直接用Append函式新增sql語句,下篇開始正式介紹ORM的核心內容。using System; using System.Collections; using System.Text.RegularExpressions; namespace ORM { public class Sql { /// <summary> /// sql語句 /// </summary> private string sql; /// <summary> /// 是否有where關鍵字 /// </summary> private bool hasWhere; /// <summary> /// 是否有order關鍵字 /// </summary> private bool hasOrder; /// <summary> /// 防sql注入 /// </summary> /// <param name="value"></param> /// <returns></returns> public static bool InjectionDefend(string value) { //網上隨便找的,不確定是否有效 string SqlStr = @"and|or|exec|execute|insert|select|delete|update|alter|create|drop|count|\/\*|\*\/|chr|char|asc|mid|substring|master|truncate|declare|xp_cmdshell|restore|backup|net +user|net +localgroup +administrators"; try { if ((value != null) && (value != String.Empty)) { //string str_Regex = @"\b(" + SqlStr + @")\b"; Regex Regex = new Regex(SqlStr, RegexOptions.IgnoreCase); if (true == Regex.IsMatch(value)) { return false; } } } catch { return false; } return true; } /// <summary> /// 建構函式 /// </summary> public Sql() { sql = string.Empty; hasWhere = false; hasOrder = false; } /// <summary> /// 新增select /// </summary> /// <param name="column"></param> /// <returns></returns> public Sql Select(string column) { sql += ("SELECT " + column + " "); return this; } /// <summary> /// 新增from /// </summary> /// <param name="Table"></param> /// <returns></returns> public Sql From(string Table) { sql += ("FROM " + Table + " "); return this; } /// <summary> /// 新增where /// </summary> /// <param name="query"></param> /// <param name="values"></param> /// <returns></returns> public Sql Where(string query, params object[] values) { if (!hasWhere) { sql += "WHERE "; hasWhere = true; } else { sql += " AND "; } for (int i = 0; i < values.Length; i++) { Regex r = new Regex(@"@\d+"); //bool型別需要特殊處理,不能直接用tostring轉換,因為直接轉換的結果為"True"或"False",而不是1和0 if (values[i] is bool) { bool value = bool.Parse(values[i].ToString()); query = r.Replace(query, (value ? "1" : "0"), 1); continue; } else if (values[i].GetType().IsPrimitive) { query = r.Replace(query, values[i].ToString(), 1); continue; } else if (values[i].GetType().IsEnum) { int intValue = (int)values[i]; query = r.Replace(query, intValue.ToString(), 1); continue; } else { if (InjectionDefend(values[i].ToString())) { query = r.Replace(query, "\"" + values[i].ToString() + "\"", 1); } } } sql += query; return this; } /// <summary> /// 在sql尾部插入任意sql語句 /// </summary> /// <param name="sql"></param> /// <returns></returns> public Sql Append(string sql, params object[] values) { for (int i = 0; i < values.Length; i++) { Regex r = new Regex(@"@\d+"); if (values[i] is bool) { bool value = bool.Parse(values[i].ToString()); sql = r.Replace(sql, (value ? "1" : "0"), 1); continue; } else if (values[i].GetType().IsPrimitive) { sql = r.Replace(sql, values[i].ToString(), 1); continue; } else if (values[i].GetType().IsEnum) { int intValue = (int)values[i]; sql = r.Replace(sql, intValue.ToString(), 1); continue; } else { if (InjectionDefend(values[i].ToString())) { sql = r.Replace(sql, "\"" + values[i].ToString() + "\"", 1); } } } this.sql += (" " + sql + " "); return this; } /// <summary> /// 新增order /// </summary> /// <param name="column"></param> /// <returns></returns> public Sql OrderBy(string column) { if (!sql.EndsWith(" ")) { sql += " "; } if (hasOrder) { sql += (", " + column); } else { sql += ("ORDER BY " + column); } return this; } /// <summary> /// 獲取當前完整的sql語句 /// </summary> /// <returns></returns> public string GetSql() { return sql; } } }