简体   繁体   English

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

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

So I know that questions with 'what is the best' in their title aren't supposed to be asked, but really.. how should you do this?所以我知道不应该问标题中带有“什么是最好的”的问题,但真的......你应该怎么做?

We have a database class and, for example, a user class.我们有一个数据库 class,例如,用户 class。 A user class will get methods such as create() and update(), which will need to do database stuff.用户 class 将获得诸如 create() 和 update() 之类的方法,这将需要执行数据库操作。

As far as I know there are 2 main options, passing on the database object in every __construct() or make the database class static.据我所知,有两个主要选项,在每个 __construct() 中传递数据库 object 或创建数据库 class static。

(Any other tips about OOP + database driven websites are also appreciated) (关于 OOP + 数据库驱动网站的任何其他提示也值得赞赏)

A very common pattern here is to make the database class a singleton construct, which is then passed to every object constructor (that is called Dependency Injection ).这里一个非常常见的模式是使数据库 class 成为 singleton 构造,然后将其传递给每个 object 构造函数(称为依赖注入)。

The purpose of making the database object a singleton is to ensure that only one connection is made per page load.使数据库 object 成为 singleton 的目的是确保每次页面加载只建立一个连接。 If you need multiple connections for some reason, you would want to do it a different way.如果您出于某种原因需要多个连接,则需要以不同的方式进行操作。 It's important to pass it via the constructors though, rather than creating the database object inside an unrelated class so that you can more easily test and debug your code.不过,通过构造函数传递它很重要,而不是在不相关的 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());

Another method is to create your database class directly extending either mysqli or PDO .另一种方法是创建数据库 class直接扩展mysqliPDO In that case, the __construct() method supplies the object to getConnect() , as in在这种情况下, __construct()方法将 object 提供给getConnect() ,如

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

Well, what you can do is to have the database access layer in one object, which is then passed to your objects, respecting the inversion of control pattern.好吧,您可以做的是在一个 object 中拥有数据库访问层,然后将其传递给您的对象,尊重控制模式的反转。

If you want to dig a bit into this direction, have a look into dependency injection (DI): http://en.wikipedia.org/wiki/Dependency_injection如果您想深入了解这个方向,请查看依赖注入 (DI): http://en.wikipedia.org/wiki/Dependency_injection

Having a singleton is usually a bad idea as you will end up having problems when testing your code.拥有 singleton 通常是个坏主意,因为在测试代码时最终会遇到问题。

Having the database access logic within a model class such as User violates the separation of concerns principle.在 model class 中包含数据库访问逻辑,例如 User 违反了关注点分离原则。 Usually DAO (Data Access Object) handles db related concerns.通常 DAO(数据访问对象)处理与数据库相关的问题。

There are ORM frameworks such as Hibernate, which handle mismatch between OO and relational models quite well, potentially saving a lot of manual work.有 ORM 框架,例如 Hibernate,可以很好地处理 OO 和关系模型之间的不匹配,可能会节省大量的手动工作。

I'm really surprised that no one said this, but here it goes: ORM .我真的很惊讶没有人这么说,但这里是: ORM

If your weapon of choice is PHP, then the major options are Propel and Doctrine .如果您选择的武器是 PHP,那么主要选项是PropelDoctrine They both have many strengths and some weaknesses, but there's no doubt that they're powerfull.他们都有很多优点和一些缺点,但毫无疑问,他们是强大的。 Just an example, from Propel's (my personal favourite) user manual:只是一个例子,来自 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();
}

You won't get more OO than that!你不会得到比这更多的OO!

They will handle a lot of things for you like for one, abstracting your data from the database vendor.他们会为你处理很多事情,从数据库供应商那里抽象出你的数据。 That said, you should be able to move (relatively painlessly) from MySQL to SQL Server and if you're building your own tools for web applications, then beign able to adapt to different environments is a very important thing.也就是说,您应该能够(相对轻松地)从 MySQL 移动到 SQL 服务器,如果您正在为 web 应用程序构建自己的工具,那么能够适应不同的环境非常重要。

Hope I can help!希望我能帮上忙!

Hey have a look at ORM's.嘿,看看ORM的。 Let them do the hard work for you?让他们为你做艰苦的工作? fluent nhibernate or microsofts entity framework. fluent nhibernate 或微软实体框架。

I could be misunderstanding your question.我可能误解了你的问题。 Sorry if so对不起,如果是这样

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

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