[英]Database queries in OOP… design pattern?
這是基本問題。 假設我有一個基類Foo。 此類調用數據庫,以獲取一些要緩存在該類中的數據。
public class Foo
{
// Properties/fields go here.
public virtual void ReadData()
{
// Queries the database for information and stores it in Foo.
}
}
現在,假設我有一個名為Bar的派生類。 此類想要緩存一些其他數據。
public class Bar : Foo
{
// Additional properties/fields go here.
public override void ReadData()
{
base.ReadData();
// Queries the database for additional information and stores it in Bar.
}
}
現在,看一下這一點,如果您要進行常規的OOP,這似乎是一件常事。 但是,在這種情況下,您要訪問數據庫兩次,效率低下。 我正在使用一個遺留代碼庫,該代碼庫到處都在進行這種操作。 在下一發行版中,他們希望優化數據庫訪問(意味着減少對數據庫的調用)。
最簡單的技巧是不調用基類方法。 取而代之的是,讓繼承的類使用專門的查詢來一次獲取數據。
如果您的要求是減少查詢數量,則oop對此無可厚非。
然后,另一個選擇是擁有緩存代理 ,這是處理緩存的常規設計模式。
解決此問題的一般方法是使用組合,而不是繼承 。
使這項工作最有效地進行還可能意味着更改Foo
類型的設計,因此,與其直接緩存數據,它僅提供有關要緩存的內容的信息。 然后,另一種類型將查看Foo
和Bar
實例,將它們要緩存的內容組合在一起,並在一次調用中獲得所有內容。
另一個問題是類對象直接與數據庫對話通常是個壞主意。 通常,您希望將一個對象或幾個對象組合在一起以創建數據訪問層。 所有數據庫訪問都將通過這些對象。 緩存將在更高級別進行。
如何構建一個表達式樹來定義要提取的數據以及如何映射數據?
父類的ReadData()將要求獲取數據以獲取表達式,並通過單個SQL命令進行獲取。 通過覆蓋,子類可以根據需要添加,操縱或替換父類的表達式。 子類將不再需要直接查詢數據庫。
編寫將表達式樹轉換為SQL的引擎可能需要一些工作。
用偽代碼:基類
public void ReadData() {
var expression = DataExpression();
var connection = // new db connection
// translates the expression into SQL, executes the query, retrieves results, maps those results
DataExpressionHelper::Process(expression, connection);
}
protected virtual SqlExpression DataExpression() {
// Return an expression tree like:
// From("BaseDataTable").Map("Name" => this.Name).Map("Age" => this.Age);
}
兒童班
protected override SqlExpression DataExpression() {
var expression = base.DataExpression();
// Then, something to the effect of:
// expression += Join("ChildClassTable).On("parent.Id = child.ParentId).Map("Gender" => this.Gender);
}
如果您的問題是(而且是) “是否存在一種可用於OOP的數據庫訪問設計模式,以便可以最大程度地減少數據庫上的查詢量?”
答案是否定的 -沒有設計模式可以最大程度地減少查詢量。 應用程序的一般設計可能導致更多或更少的查詢。
查看這三件事:
延遲加載
快取
為了提高執行查詢的性能:如果使用動態Sql-Sql查詢的參數化將最大限度地減少DB Server用於執行查詢的資源
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.