繁体   English   中英

如何访问OOP中的数据库class?

[英]How to access the database class in OOP?

所以我知道不应该问标题中带有“什么是最好的”的问题,但真的......你应该怎么做?

我们有一个数据库 class,例如,用户 class。 用户 class 将获得诸如 create() 和 update() 之类的方法,这将需要执行数据库操作。

据我所知,有两个主要选项,在每个 __construct() 中传递数据库 object 或创建数据库 class static。

(关于 OOP + 数据库驱动网站的任何其他提示也值得赞赏)

这里一个非常常见的模式是使数据库 class 成为 singleton 构造,然后将其传递给每个 object 构造函数(称为依赖注入)。

使数据库 object 成为 singleton 的目的是确保每次页面加载只建立一个连接。 如果您出于某种原因需要多个连接,则需要以不同的方式进行操作。 不过,通过构造函数传递它很重要,而不是在不相关的 class 中创建数据库 object ,这样您就可以更轻松地测试和调试代码。

// Basic singleton pattern for DB class
class DB
{

  // Connection is a static property
  private static $connection;

  // Constructor is a private method so the class can't be directly instantiated with `new`
  private function __construct() {}

  // A private connect() method connects to your database and returns the connection object/resource
  private static function connect() {
    // use PDO, or MySQLi
    $conn = new mysqli(...);
    // Error checking, etc
    return $conn;
  }

  // Static method retrieves existing connection or creates a new one if it doesn't exist
  // via the connect() method
  public static function get_connection() {
    if (!self::$connection) {
      self::$connection = self::connect();
      // This could even call new mysqli() or new PDO() directly and skip the connect() method
      // self::$connection = new mysqli(...);
    }
    return self::$connection;
  }
}

class Other_Class
{

  // accepts a DB in constructor
  public function __construct($database) {
    //stuff
  }
}

// Database is created by calling the static method get_connetion()
$db = DB::get_connection();

$otherclass = new Other_Class($db);

// Later, to retrieve the connection again, if you don't use the variable $db
// calling DB::get_connection() returns the same connection as before since it already exists
$otherclass2 = new Other_Class(DB::get_connection());

另一种方法是创建数据库 class直接扩展mysqliPDO 在这种情况下, __construct()方法将 object 提供给getConnect() ,如

public static function get_connection() {
  if (!self::$connection) {
    self::$connection = new self(/* params to constructor */);
  }
  return self::$connection;
}

好吧,您可以做的是在一个 object 中拥有数据库访问层,然后将其传递给您的对象,尊重控制模式的反转。

如果您想深入了解这个方向,请查看依赖注入 (DI): http://en.wikipedia.org/wiki/Dependency_injection

拥有 singleton 通常是个坏主意,因为在测试代码时最终会遇到问题。

在 model class 中包含数据库访问逻辑,例如 User 违反了关注点分离原则。 通常 DAO(数据访问对象)处理与数据库相关的问题。

有 ORM 框架,例如 Hibernate,可以很好地处理 OO 和关系模型之间的不匹配,可能会节省大量的手动工作。

我真的很惊讶没有人这么说,但这里是: ORM

如果您选择的武器是 PHP,那么主要选项是PropelDoctrine 他们都有很多优点和一些缺点,但毫无疑问,他们是强大的。 只是一个例子,来自 Propel(我个人最喜欢的)用户手册:

// retrieve a record from a database
$book = BookQuery::create()->findPK(123); 

// modify. Don't worry about escaping
$book->setName('Don\'t be Hax0red!'); 

// persist the modification to the database
$book->save();

$books = BookQuery::create()  // retrieve all books...
  ->filterByPublishYear(2009) // ... published in 2009
  ->orderByTitle()            // ... ordered by title
  ->joinWith('Book.Author')   // ... with their author
  ->find();
foreach($books as $book) {
  echo  $book->getAuthor()->getFullName();
}

你不会得到比这更多的OO!

他们会为你处理很多事情,从数据库供应商那里抽象出你的数据。 也就是说,您应该能够(相对轻松地)从 MySQL 移动到 SQL 服务器,如果您正在为 web 应用程序构建自己的工具,那么能够适应不同的环境非常重要。

希望我能帮上忙!

嘿,看看ORM的。 让他们为你做艰苦的工作? fluent nhibernate 或微软实体框架。

我可能误解了你的问题。 对不起,如果是这样

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM