我正在为 Web 应用程序使用 Java + Spring 框架。我没有使用任何 ORM 工具。相反,我尝试使用简单的 DAO/DTO 模式将数据库关系建模为 Java 对象。每当 DTO 与数据库中的单个表完全对应时,它就非常简单。但是如果有表使用外键引用其他表,我不确定最好的方法是什么。在 Stackoverflow 中寻找类似的答案,但找不到符合我需要的答案。我想举一个非常具体的例子——假设有两个实体用户和组。我有一个 User DTO 和 Group DTO,每个都有 UserDao(JdbcUserDao) 和 GroupDao(JdbcGroupDao)。
现在我在数据库中有一个连接用户和组的关系。一个用户可以属于多个组。表名为 User_Group_Association,具有以下 DB 定义:
用户ID |群组编号
这里的user_id是指向user表的外键。同样group_id 指的是组表。当我用 Java 为这个 DTO 建模时,我应该做这样的事情吗:
public class UserGroupAssoc {
private int userId;
private int groupId;
//Setters and getters follow
}
或者应该是这样的:
public class UserGroupAssoc {
private User user;
private Group group;
//Setters and getters follow
}
特定的 UI 用例:我想显示用户名及其所属的相应组名。像这样的——
名称 -> 组名
Keshav -> 管理员、最终用户、报告管理员
Kiran -> ReportAdmin
Pranav -> 最终用户
在 DTO 设计的第一种方法中,我需要再次从数据库中获取用户详细信息(名称)和组详细信息(名称)。在第二种方法中,我需要在构建 UserGroupAssoc 对象本身时获取 User 和 Group 对象。
在可能的第三种方法中,我可以按如下方式设计 UserGroupAssoc DTO:
public class UserGroupAssoc {
private String userName;
private String groupName;
private int userId;
private int groupId;
//Setters and getters follow
}
在这第三种方法中,我在 SQL 中连接表以仅获取用例所需的字段,然后相应地为 DTO 建模。
实现这种情况的标准方法是什么?在 DTO 设计中连接表是否合适?有观点认为一个DTO应该只对应一张表,关联的对象应该聚合在app层。这有从数据库中获取多个对象的开销吗?对正确的方法太困惑了,抱歉解释这么长!
最佳答案
免责声明:我不是 ORM 专家...
...但在经典中many-to-many relations您不需要第三个数据模型 (UserGroupAssoc)。 User 类将包含一组 Group:
public class User {
// ... user fields ...
List<Group> groups;
// ... getters/setters ...
}
如果您还需要反向关系(一个组包含用户),Group 类将如下所示:
public class Group {
// ... group fields ...
List<User> users;
// ... getters/setters ...
}
同样,经典的做法是在集合(User 和 Group 而不是 userId 和 groupId)。
只有在关联表 (User_Group_Association) 包含除 user_id 和 group_id 之外的其他内容(可能是一些授权)时,您通常才需要第三个域对象允许将用户添加到组的代码,无论如何):
user_id | group_id | auth_code
在这种情况下,UserGroupAssoc 类可能具有以下结构:
public class UserGroupAssoc {
private User user;
private Group group;
private String authorizationCode;
// ... setters/getters ...
}
User 和 Group 之间的多对多关系将转换为与这个新领域对象的两个多对一关系。通常优先使用域对象(User 和 Group 而不是 userId 和 groupId)。
Which is the standard approach to achieve this scenario?
好吧,如果您使用的是 ORM 框架,那将是该框架执行此操作的标准方式。但是因为您有自定义的 ORM 解决方案,所以很难说。
Is joining tables alright in the DTO design?
为什么应用层的DTO设计要受数据库联表的影响?这是 object-relational impedance mismatch 的案例也许还有 law of leaky abstraction因为您无法将关系域完全抽象为保持 1:1 对应关系的对象域。
Some have opinions that one DTO should correspond to only ONE table and the associated objects should be aggregated in the app layer. That has overhead of doing multiple object fetches from DB right?
ORM 有一些局限性(对于您可能遇到的某些问题,请再次参阅对象关系阻抗不匹配)并且很难对您的域对象进行建模以适应关系数据库的约束,反之亦然。报告是这方面的一个很好的例子。
一份报告通常会聚合来自多个表格的数据。这对于某些 SQL 连接当然没有问题,但是您将如何将结果映射到 DTO?正如你自己所说...
Whenever the DTO exactly corresponds to a single table in the database, it is very straight forward
...但是报告结果不会映射到单个表,它必须映射到更多表的片段。
根据您在应用程序中的需求,您最终可能会得到一些看起来很奇怪的类或看起来很笨拙的 SQL。您最终可能会运行比获取正确的对象模型和它们之间的关联所需的更多的查询;或者您可能有更多类似的 DTO,只是为了限制访问数据库的次数并获得更好的性能。
所以我想说的是(再次声明我不是 ORM 专家)并不是所有的应用程序都适合 ORM;但如果您考虑继续使用它,可以查看 Hibernate/JPA 如何解决这些问题,或者甚至继续使用它们。
关于java - 设计具有外键关系的 DTO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8769606/
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#
我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/