[英]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.