Php/Mysql: 数据库 class 和依赖注入
Php/Mysql: Database class and dependency injection
我正在尝试将依赖注入模式应用于我一直从事的中型项目。我的大多数 classes 在某种程度上与数据库交互,而不是在每个 class 中实例化一个 pdo 对象,我在控制器级别实例化一个 pdo 对象并将该对象注入 classes需要数据库连接。这样,所有 classes 都使用相同的连接,整个过程使单元测试变得非常容易。
但是,当我尝试对这些 classes 使用事务时,事情变得有点复杂。我们的数据库是高度非规范化的,每个动作都需要来自不同 classes 的多个 inserts/updates。举一个基本的例子,假设我们有下面的 classes:
class student{
public function addCourse($pdo,$course){
//$pdo->execute();
}
}
class course{
public function incrementStudentCount($pdo){
//$pdo->execute();
}
}
如您所见,addCourse 和 incrementStudentCount 方法都必须在单个事务中工作 mode.However,学生和课程 classes 不知道事务是否在 $pdo 对象中启动。他们不知道如果出现问题是否需要回滚。
我想创建一个 PDO 包装器 class 并使用这个 class 进行数据库交互。这样,我可以将事务状态保留在 class 中。基本上,它看起来像这样:
class PDOWrapper {
private $transactionStarted=false;
private $pdo;
public function __construct($pdo){
$this->pdo=$pdo;
}
public function startTransaction(){
$this->transactionStarted=true;
$this->pdo->beginTransaction()
}
public function query($query){
try{
//$this->db->execute($query);
}
catch(PDOException e){
if($this->transactionStarted){
$this->db->rollBack();
}
}
}
}
好吧,我不确定这种方法是否可行。那么,您有什么建议?
你是对的,你的 classes 不应该知道另一个 class / DB 中发生了什么。 None 重要的是,所有 student
和 user
class 所关心的都是插入到数据库中。
是否有交易无关紧要:他们仍然应该做他们无论如何都会做的完全相同的事情,即插入行。我建议您有一个控制器来处理这两项任务,如下所示:
$pdo->startTransaction();
//However you instantiate the course object, do it here
$course = new Course;
//Same with student
$student = new Student;
$student->addCourse($pdo, $course);
$course->incrementStudentCount($pdo);
$pdo->commit();
当您提交给数据库时,您的所有查询都将通过。如果出现这样的错误,您可以回滚:
try
{
$pdo->startTransaction();
//Code
}
catch(PDOException $e)
{
$pdo->rollback();
}
我正在尝试将依赖注入模式应用于我一直从事的中型项目。我的大多数 classes 在某种程度上与数据库交互,而不是在每个 class 中实例化一个 pdo 对象,我在控制器级别实例化一个 pdo 对象并将该对象注入 classes需要数据库连接。这样,所有 classes 都使用相同的连接,整个过程使单元测试变得非常容易。
但是,当我尝试对这些 classes 使用事务时,事情变得有点复杂。我们的数据库是高度非规范化的,每个动作都需要来自不同 classes 的多个 inserts/updates。举一个基本的例子,假设我们有下面的 classes:
class student{
public function addCourse($pdo,$course){
//$pdo->execute();
}
}
class course{
public function incrementStudentCount($pdo){
//$pdo->execute();
}
}
如您所见,addCourse 和 incrementStudentCount 方法都必须在单个事务中工作 mode.However,学生和课程 classes 不知道事务是否在 $pdo 对象中启动。他们不知道如果出现问题是否需要回滚。
我想创建一个 PDO 包装器 class 并使用这个 class 进行数据库交互。这样,我可以将事务状态保留在 class 中。基本上,它看起来像这样:
class PDOWrapper {
private $transactionStarted=false;
private $pdo;
public function __construct($pdo){
$this->pdo=$pdo;
}
public function startTransaction(){
$this->transactionStarted=true;
$this->pdo->beginTransaction()
}
public function query($query){
try{
//$this->db->execute($query);
}
catch(PDOException e){
if($this->transactionStarted){
$this->db->rollBack();
}
}
}
}
好吧,我不确定这种方法是否可行。那么,您有什么建议?
你是对的,你的 classes 不应该知道另一个 class / DB 中发生了什么。 None 重要的是,所有 student
和 user
class 所关心的都是插入到数据库中。
是否有交易无关紧要:他们仍然应该做他们无论如何都会做的完全相同的事情,即插入行。我建议您有一个控制器来处理这两项任务,如下所示:
$pdo->startTransaction();
//However you instantiate the course object, do it here
$course = new Course;
//Same with student
$student = new Student;
$student->addCourse($pdo, $course);
$course->incrementStudentCount($pdo);
$pdo->commit();
当您提交给数据库时,您的所有查询都将通过。如果出现这样的错误,您可以回滚:
try
{
$pdo->startTransaction();
//Code
}
catch(PDOException $e)
{
$pdo->rollback();
}