保存在数据库中的不同用户类型的工厂模式
我有一个必须多次回答的问题,但我找不到任何好的搜索词来找出解决该问题的最佳方法。
在我的应用程序中,我将有不同类型的用户,它们将具有不同的属性和不同的方法,但其中大部分也将是相同的。因此,我创建了一个基类“User”和其他类“Player”、“trainer”等...继承自“User”类。
我应该如何将其保存在数据库中,在一个名为“用户”的巨大表中,该表具有所有类的所有不同属性,或者我的数据库应该看起来像我的类吗?我认为解决方案2更好。
我只有一种登录方法,因此它将始终返回基类,但是当应该使用不同的特定类型(“玩家”、“训练者”)时,将会对该类进行强制转换。但是我如何进行数据库调用来填充我的不同类。
我能做的是在用户表中也保存类型。当我将该信息返回到我的代码时,我检查类型是什么,然后调用数据库获取该类型的特定信息,创建正确的类型并将其作为代码中的“用户”返回。但我不喜欢这样的想法:我需要调用数据库两次才能用数据填充我的对象,我可以用 SP 解决它,但我尽量不使用 SP。
当我不知道调用数据库时会返回什么类型时,有没有一种好方法可以通过一次调用数据库来解决这个问题。
感谢您的任何帮助。
I have a question that must be answer several times before, but I can't find any good search words to find out what's the best approach to solve it.
In my application I will have different types of Users, that will have different properties and different methods, but much of it will also be the same. So I create a baseclass 'User' and the other classes 'Player', 'trainer' and so on... that inherits from the 'User' class.
How should I save this in the database, in one huge table called 'User' that has all different properties from all classes, or should my database look like my classes? I think solution 2 is better.
I will only have one login method, so it will always return the baseclass, but then when the different specific types ('player','trainer') should be use there will be a cast to that class. But how I do the database call to populate my different classes.
What I could do is that in the user-table the type is also saved. When I get that information back to my code, I check what the type is and then call to the database getting the specific information for that type, create the correct type and return it as a 'user' in the code. But I don't like the idea that I need to call twice to the database to fill my objects with data, I could solve it with a SP, but I try not to use SP's.
Is there a good way to solve this with one call to the database, when I don't know what type that will be returned when I call to database.
Thanks for any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,在我看来,我建议您不要考虑基于面向对象软件解决方案的关系设计。
如果最后一句话是正确的,我的提示是每种与业务有关的实体类型,您都将为它设计一个数据表。
不管怎样,我发现你可以有另一种关系设计。为什么不创建这样的“用户”表,其中包含唯一标识符、凭据等基本信息以及用户识别、身份验证和授权所需的任何其他基本信息?
有了这个,您就可以设计一个名为“TrainerUsersProfiles”、“PlayerUsersProfiles”等的关系表。
事实上,“TrainerUsersProfiles”、“PlayerUsersProfiles”类似于个人资料数据,因为您必须成为用户才能进行身份验证并获得应用程序资源的授权。但用户可以拥有更多相关信息,例如“个人资料”。作为教练或球员的任何信息都是用户个人资料的一部分。
现在是时候找出教练和球员(以及任何其他人)共享哪些属性了。此类共享属性应位于用户的配置文件表“UsersProfiles”中,该表与特定用户具有一对一的关系。
例如,我将任何扩展的配置文件数据放入“TrainerUsersProfiles”和“PlayerUsersProfiles”中,并且两者(或多个)将与某些用户配置文件具有一对一的关系。
总结:用户拥有个人资料,个人资料具有扩展的、专门的个人资料数据。
谈论面向对象层(应用程序),我建议最好避免使用抽象工厂,而只使用存储库:
用户类将有一个“Kind”属性,它是用户配置文件类型的枚举(教练、球员等)。
此外,User 类将有一个“Profile”属性,它本身也应该有一个“Properties”属性。 “Properties”是一种称为“ProfileProperties”的类型,并且有派生它的“TrainerProperties”和“PlayerProperties”。
最后,这将是一些示例用法:
我相信这可能是您正确的解决方案,并且最终可以得到良好的关系和面向对象的设计。
First of all, in my opinion, I'd like to suggest you to don't think a relational design based on the object-oriented software solution on top of it.
Taking last sentence as true, my hint will be each type of entity that has something to do in the business, you'll design a data table for it.
Anyway, I find you could have another relational design. Why don't you create such "Users" table which has basic information like an unique identifier, credentials - and any other basic info you would need for user identification, authentication and authorization -?
Having this, you'd design a relational table called "TrainerUsersProfiles", "PlayerUsersProfiles" and so on.
In fact, "TrainerUsersProfiles", "PlayerUsersProfiles" is something like a profile data, because you've to be an user in order to authenticate and be authorized to application's resources. But an user can have more related information, say it a "profile". Any information as a trainer or player is part of user's profile.
Now is time to find which attributes are shared on trainers and players (and any other one). Such shared attributes should be in user's profile table "UsersProfiles" which has an one-to-one relation to an specific user.
In instance, I'd put any extended profile data in "TrainerUsersProfiles" and "PlayerUsersProfiles", and both (or more) would have a one-to-one relation to some user profile.
Summarizing: An user has a profile, and a profile has an extended, specialized profile data.
Talking about object-oriented layer - the application -, I'd like to suggest it'd better to avoid that abstract factory and just use a repository:
User class would have a "Kind" property, which is an enumeration of user profile kinds (Trainer, Player, and so on).
In addition, User class would have a "Profile" property, which should have a "Properties" property itself too. "Properties" is of a type called like "ProfileProperties" and there's a "TrainerProperties" and "PlayerProperties" deriving it.
Finally, this would be some sample usage:
I believe this could be your right solution and it can end in a good relational and object-oriented design.
这称为“多态持久性”。有多种方法可以做到这一点。它们的共同点是基表中有一个列,其中包含每行中对象的真实类。
OR 映射器使用此列来加载同一表的更多列或连接其他表中的列。
有关更多详细信息,请参阅 Hibernate 文档。这是 来自 Java Tips 的示例。
This is called "Polymorphic persistence". There are various ways to do this. All of them have in common that there is a column in the base table which contains the real class of the object in each row.
The OR mapper uses this column to either load more columns of the same table or join columns in other tables.
See the Hibernate docs for more details. Here is an example from Java Tips.