繁体   English   中英

将MySQL连接查询与OOP和对象相关联的最佳实践方法

[英]Best Practice approach to relating MySQL join queries to OOP and Objects

我正在开发一个PHP Web应用程序,用户可以在其中创建到目的地的旅行,并邀请其他用户参与这些旅行。

我有用于DestinationsTripsUsers MySql表,还有一个名为Invites的表,用于解决UsersTrips之间的多对多关系。

对于这些表中的每一个,我都在应用程序中创建了一个类(因此Destinations是一个类, Trips是一个类,等等)。 我为这些类的每一个编写了一个静态函数,该函数允许实例​​化对象并从MySQL查询分配属性(因此,从SELECT *查询返回的每一行都会实例化对象并分配属性)。

我正在尝试创建一个页面,我的用户可以在该页面上查看他们计划的所有行程的详细信息。 此页面将显示目的地(来自Destinations ),旅程详细信息(例如Trips日期)和他们邀请的用户的详细信息(例如Users名),并将所有这些数据放在html表中,其中每个旅程都是行。

要做到这一点,到目前为止,我一直在实例Trips这涉及到用户的user_idDestinationsInvites其涉及到的Trips ,和Users这涉及到这些Invites 然后,我使用了嵌套的foreach循环来根据需要显示这些循环,如下所示:

foreach($trips as $trip) {
 foreach($invites as $invite) {
   foreach($invited_users as $invited_user) {
      if($invite->trip_id == $trip->id && $invite->guest_id == $invited_user->id) {
        echo $invited_user->name;
                  } } } }

我看到的是可怕的,没有办法做到这一点。

通过阅读,我认为我想使用MySQL来联接这4个表,然后仅选择与我的相关行程有关的数据。 我不确定的是:

a)如何从该MySQL结果实例化对象并正确分配其属性?

b)即使这样做,如何避免昂贵的foreach循环在正确的行程旁边显示正确的数据?

是否存在“最佳实践”方式以面向对象的方式显示来自多个相关数据库表的数据?

首先,“良好实践”是人们用来给偏见以可敬的色彩的短语之一。 最好问一下如何通过设计实现特定的目标。

话虽如此:您偶然发现了将RDBMS映射到面向对象系统时常见的问题。 Google的“延迟加载”进行了大量讨论。 问题归结为您一次加载多少个“关系”的问题。 在您的示例中,旅行与目的地和用户相关联; 加载“行程”时,是否还应该加载目的地和用户? 如果这样做,那么是否还应该为用户加载其他信息(例如,他们正在进行的其他旅行?)。 如果这样做,是否为用户进行的所有行程加载行程数据? 依此类推-如果不小心,最终将加载整个数据库。

不加载所有相关实体的缺点是,如果一次加载每个对象的数据,性能可能会变得很差。

有关我认为最佳实践的详细说明,请购买并阅读Evans的“域驱动设计”。

作为一种捷径,请考虑创建一个“存储库”层,该层知道如何将数据库记录映射到对象,并创建用于搜索所需内容的自定义方法。 例如,您可以调用:

$repository::getTripsForUser($userID);

该方法将执行将4个表连接在一起的SQL查询,并将结果转换为对象树。

您可能想利用他人在解决此问题上所做的工作; 有许多解决此问题的“对象关系映射”框架。 我认为对于ORM解决方案是否可以使生活更轻松尚无定论-但这值得一看。

我认为您正在使事情变得复杂,您不需要一次加载所有数据。

为什么需要遍历所有行程,而又需要显示一位用户的行程?

OOP的一种天真但简单的方法: User类,具有检索用户相关旅程的方法。

它可以返回Trip数组,其自身具有受邀用户的引用:

class User {
    private $id;
    public function __construct($id) {
        $this->id = $id;
    }
    public function getTrips() {
        $trips = array();
        // Run your query using $this->id to build the WHERE clause
        return $trips;
    }
}

class Trip {

    // Array of User objects invited to the trip        
    private $invited = array();

    // Other methods here to add/retrieve invited users

}

$user = new User(1);
foreach ($user->getTrips() as $trip) {
    // Do something with $trip
}

理想情况下, User实例将存储在会话中

暂无
暂无

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

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