我正在改变Java中的ORM,我想知道在非ORM设置中处理多对一和多对一关系的最佳方法是什么。
在我的Customer.java
课程中,我有:
private Long id;
private String name;
private Date dob;
//About 10 more fields
private List<Pet> pets;
在Pet.java
我有:
private String id;
private String name;
private Customer owner;
我的Pet数据库表看起来像这样
id BIGSERIAL PRIMARY KEY,
name VARCHAR(20),
owner_id BIGSERIAL REFERENCES...
现在我意识到,如果我运行一个连接两个表的查询,我会返回一个“平面”数据结构,其中包含Customer
和Pet
的字段以及任何外键。在这种情况下,处理数据的常用/最有效方法是什么?
一个。通过调用customer.setName(resultSet.getString(("name"))
...来手动重建对象图
湾通过将返回的数据转换为Map<String, Object>
来原样使用它?
数据流是:从数据库中读取数据 - &gt;呈现给JSON以供AngularJS前端使用 - &gt;修改后的数据被发送回服务器进行验证 - &gt;域逻辑应用 - &gt;保存到数据库。
答案 0 :(得分:1)
目前最好的选择是:
在所有这些情况下,您编写自己的SQL查询,大多数情况下它们将导致连接查询。顺便提一下,您给出的示例不是嵌套对象。
答案 1 :(得分:1)
如果您想在单个查询中同时阅读Customer和Pet以获得更好的性能,可以执行以下操作:
List<Customer> customers = new ArrayList<>();
String sql = "SELECT c.id AS cust_id" +
", c.name AS cust_name" +
", c.dob AS cust_dob" +
", p.id AS pet_id" +
", p.name AS pet_name" +
" FROM Customer c" +
" LEFT JOIN Pet p ON p.owner_id = c.id" +
" WHERE c.name LIKE ?" +
" ORDER BY c.id";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, "%DOE%");
try (ResultSet rs = stmt.executeQuery()) {
Customer customer = null;
while (rs.next()) {
long cust_id = rs.getLong("cust_id");
if (customer == null || customer.getId() != cust_id) {
customer = new Customer();
customer.setId(cust_id);
customer.setName(rs.getString("cust_name"));
customer.setDob(rs.getDate("cust_dob"));
customers.add(customer);
}
long pet_id = rs.getLong("pet_id");
if (pet_id != 0) {
Pet pet = new Pet();
pet.setId(pet_id);
pet.setName(rs.getString("pet_name"));
pet.setOwner(customer);
customer.addPet(pet);
}
}
}
}