2011-08-13 3 views
2

제목에서 '무엇이 최고'라는 질문에 질문하지 않아도되지만 실제로 어떻게해야합니까?OOP에서 데이터베이스 클래스에 액세스하는 방법?

우리는 데이터베이스 클래스와 예를 들어 사용자 클래스를 가지고 있습니다. 사용자 클래스는 데이터베이스 항목을 수행해야하는 create() 및 update()와 같은 메소드를 가져옵니다.

필자가 아는 한 모든 기본 __construct()에 데이터베이스 객체를 전달하거나 데이터베이스 클래스를 정적으로 만드는 두 가지 주요 옵션이 있습니다.

다음 (즉 Dependency Injection라고 모든 개체의 생성자에 전달되는 데이터베이스 클래스 싱글 구조를 만들기 위해 여기

답변

2

에게 매우 일반적인 패턴이다 (OOP + 데이터베이스 기반 웹 사이트에 대한 다른 팁도 감사합니다)).

데이터베이스 개체를 단일 개체로 만드는 목적은 페이지로드 당 하나의 연결 만 수행되도록하는 것입니다. 어떤 이유로 여러 연결이 필요한 경우 다른 방법으로 연결하는 것이 좋습니다. 관련없는 클래스 내에 데이터베이스 객체를 생성하는 대신 생성자를 통해 전달하는 것이 중요하므로 코드를보다 쉽게 ​​테스트하고 디버깅 할 수 있습니다.

// 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()); 

또 다른 방법은 직접 중 하나 mysqli 또는 PDO 확장 데이터베이스 클래스 를 만드는 것입니다. 이 경우, __construct() 방법은

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

음과 같이 getConnect()에 개체를 제공합니다, 당신이 할 수있는 것은 반전을 존중, 다음 객체에 전달되는 하나의 객체에 데이터베이스 액세스 레이어를하는 것입니다 제어 패턴의 http://en.wikipedia.org/wiki/Dependency_injection

싱글을 갖는 것은 당신이 당신의 코드를 테스트 할 때 문제가 끝날 것 같은 나쁜 생각이 일반적이다 :

이 방향으로 조금 파고하려면

은 의존성 주입 (DI)로보고있다.

1

사용자와 같은 모델 클래스 내에서 데이터베이스 액세스 논리를 갖는 것은 관심사 분리 원칙을 위반합니다. 대개 DAO (Data Access Object)는 db 관련 문제를 처리합니다.

OO와 관계형 모델 간의 불일치를 다루는 Hibernate와 같은 ORM 프레임 워크가 있으며 많은 수작업을 절약 할 수 있습니다.

1

나는 아무도 이것을 말하지 않았지만 실제로는 여기에있다 : 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 Server로 (상대적으로 고통없이) 이동할 수 있어야하고 웹 응용 프로그램 용 도구를 직접 만드는 경우 다른 환경에 적응할 수있는 능력이 매우 중요합니다.

희망을 도울 수 있습니다.

+0

CakePHP의 ORM 기능을 사용하면 명백한 이유가 없으므로 여분의 오버 헤드가 발생하지 않으므로 추가 기능이 정말 마음에 들지 않았습니다. 독립 실행 형 ORM이이를 어떻게 처리합니까? –

+0

그들은 어떻게 처리합니까? 죄송 합니다만 질문이 없습니다. –

0

안녕하세요, ORM을 살펴보세요. 그들이 당신을 위해 열심히 일하게하십시오? 유창한 nhibernate 또는 microsofts 실재물기구.

귀하의 질문에 대한 오해가있을 수 있습니다. 죄송합니다.

+0

Fluent NHibernate는 awsome이지만 그는 PHP에 대해 말하고 있습니다. (적어도 질문은 PHP로 태그되어 있습니다) FluentNH가 .NET이기 때문에 적용되지 않습니다. 어쨌든 좋은 제안. –

관련 문제