- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在开发一个 PHP 网络应用程序,用户可以在其中创建前往目的地的旅行,并邀请其他用户参加这些旅行。
我有 Destinations
的 MySql 表, Trips
, 和 Users
和一个名为 Invites
的表解决Users
之间的多对多关系和 Trips
.
对于这些表中的每一个,我都在我的应用程序中创建了一个类(所以 Destinations
是一个类,Trips
是一个类,等等)。我为这些类中的每一个编写了一个静态函数,使对象能够被实例化并从 MySQL 查询中分配它们的属性(因此从 SELECT *
查询返回的每一行都会导致一个对象被实例化并分配属性)。
我正在尝试创建一个页面,我的用户可以在其中查看他们计划的所有旅行的详细信息。此页面将显示目的地(来自 Destinations
)、旅行详细信息(例如来自 Trips
的日期)和他们邀请的用户的详细信息(例如来自 Users
的用户名)并将所有这些数据放在 html 中每个行程都是一行的表格。
为了实现这一点,到目前为止我一直在实例化 Trips
与用户的 user_id
有关, Destinations
和 Invites
与那些有关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 映射到面向对象系统时很常见的问题。谷歌“延迟加载”进行大量讨论。问题归结为您一次加载多少“关系”的问题。在您的示例中,旅行链接到目的地和用户;加载“行程”时,是否还应加载目的地和用户?如果你这样做了,你是否还应该为用户加载其他信息(例如,他们正在进行的其他旅行?)。如果你这样做了,你会加载用户所有旅行的旅行数据吗?依此类推 - 如果您不小心,您最终会加载整个数据库。
不加载所有相关实体的缺点是,如果一次加载每个对象的数据,性能会变得非常差。
有关我认为最佳实践的详细说明,请购买并阅读 Evans 的“领域驱动设计”。
作为捷径,考虑创建一个“存储库”层,它知道如何将数据库记录映射到对象,并创建自定义方法来搜索您想要的内容。例如,您可以调用:
$repository::getTripsForUser($userID);
该方法将执行一个将 4 个表连接在一起的 SQL 查询,并将结果转换为对象树。
您可能想利用其他人在解决此问题时所做的工作;有许多“对象关系映射”框架可以解决这个问题。我认为对于 ORM 解决方案是否让生活更轻松尚无定论——但它值得研究。
关于php - 将 MySQL 连接查询与 OOP 和对象相关联的最佳实践方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13335253/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!