Sql動態查詢拼接字符串的優化
最原始的 直接寫:string sql="select * from TestTables where 1=1";
... 這樣的代碼效率很低的,這樣影響了數據庫的索引引用
如下所示:
private void TestOneMethod()
{
string querySql = "select * from TestTables where 1=1";
if (hasOneCondition)
{
querySql += "oneCondition='oneCondition'";
}
if (hasTwoCondition)
{
querySql += "twoCondition='twoCondition'";
}
if (hasThreeCondition)
{
querySql += "threeCondition='threeCondition'";
}
// ....其他條件
// ExcSql(querySql)
}
優化方案A:
去掉 string sql="where 1=1"
那么,在用的時候定義一個變量,用來標志是否應存在了hasWhere=false ,如果已經存在了則 hasWhere=!hasWhere.這樣下一次在用的時候就
可以用下面的形式表示了:
private void TestOneMethod()
{
string querySql = "select * from TestTables";
bool _hasWhere = false;
if (hasOneCondition)
{
querySql += _hasWhere ? "where" : "and" + "oneCondition='oneCondition'";
_hasWhere = true;
}
if (hasTwoCondition)
{
querySql += _hasWhere ? "where" : "and" + "twoCondition='twoCondition'";
_hasWhere = true;
}
if (hasThreeCondition)
{
querySql += _hasWhere ? "where" : "and" + "threeCondition='threeCondition'";
_hasWhere = true;
}
// ....其他條件
// ExcSql(querySql)
}
....
經過優化后,sql的效率提高了,但是仍然存在問題,問題在哪里呢?如果我們每次都這樣寫的話是不是非常的費力,那么就提出一個通用的方
法,這個通用的方法首先得有一個bool類型的返回值,用來確認當前是否需要hasString。如下,在應用的時候:
private bool SeachHelper(string whereString, bool hasWhere)
{
if (!hasWhere)
whereString = "where" + whereString;
else
whereString = "and" + whereString;
return true;
}
private void TestTwoMethod()
{
string querySql = "select * from TestTables";
bool _hasWhere = false;
if (hasOneCondition)
{
_hasWhere = SeachHelper(querySql, _hasWhere);
querySql += "oneCondition='oneCondition'";
}
if (hasThreeCondition)
{
_hasWhere = SeachHelper(querySql, _hasWhere);
querySql += "twoCondition='twoCondition'";
}
if (hasThreeCondition)
{
_hasWhere = SeachHelper(querySql, _hasWhere);
querySql += "threeCondition='threeCondition'";
}
// ....其他條件
// ExcSql(querySql);
}
代碼簡潔了不少,但是仍然粗只能問題,那么問題又是什么呢?
額,字符串來回的拼接非常的浪費資源,那么 ,用StringBuilder啊,好接下來繼續。
private void TestThreeMethod()
{
StringBuilder querySql = new StringBuilder();
querySql.Append("select * from TestTables");
bool _hasWhere = false;
if (hasOneCondition)
{
_hasWhere = SeachHelper(querySql, _hasWhere);
querySql.Append("oneCondition='oneCondition'");
}
if (hasThreeCondition)
{
_hasWhere = SeachHelper(querySql, _hasWhere);
querySql.Append("twoCondition='twoCondition'");
}
if (hasThreeCondition)
{
_hasWhere = SeachHelper(querySql, _hasWhere);
querySql.Append("threeCondition='threeCondition'");
}
// ....其他條件
// ExcSql(querySql.ToString());
}
等一下,那個公用的方法也得改,當然要改!
private bool SeachHelper(StringBuilder whereString, bool hasWhere)
{
if (!hasWhere)
whereString.Append("where");
else
whereString.Append("and");
return true;
}
上面就是執行動態查詢時的逐步優化,說道優化,其實是有一定的前提的,除了第一種情況最低能,其余的要根據實際的情況來進行確定。
如果查詢條件非常少,甚至只有兩種的情況的時候,則無所謂了,但是如果查詢條件越多,那么后面的方法的效率越高。同時對於代碼的可讀
性越強,想一下,一個項目通常有多少人在寫sql查詢,如果沒給人的風格不同,那么以后的維護人員就要遭罪了,通過使用通用的方法,那么
以后給代碼的維護人員帶來方便,同時拼接字符串的帶來的額外開銷也是不容忽視的,好的代碼習慣很重要,一個系統從小的地方去注意,那
么最后一定是一個優秀的系統。
