使用 JDBC 在一对多中获取 "many"

Getting the "many" in one-to-many using JDBC

我现在有两个table,它们是一对多的关系。一家餐厅 table,映射到多个检查。我的 postgres tables 是这样定义的:

CREATE TABLE restaurant (
    id UUID NOT NULL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    zip VARCHAR(255),
    address VARCHAR(255),
    phone VARCHAR(255)
);

CREATE TABLE inspection (
    restaurant_id UUID NOT NULL,
    date VARCHAR(255) NOT NULL,
    score int,
    violation VARCHAR(255),
    risk VARCHAR(255),
    FOREIGN KEY (restaurant_id) REFERENCES restaurant(id)
);

我不确定在查询餐厅时如何推断所有检查。我正在使用 resultSet.getString("fieldName") 获取餐厅的所有字段,但是当我尝试 resultSet.getString("inspection") 时它不起作用。我需要什么代码才能进行这些检查?这是我当前获取所有餐厅的查询。

@Override
    public Optional<Restaurant> selectRestaurantById(UUID id) {
        final String sql = "SELECT * FROM restaurant WHERE id = ?"; 
        List<Restaurant> res = jdbcTemplate.query(
                sql, 
                new Object[] {id}, 
                (resultSet, i) -> {
            UUID restaurant_id = UUID.fromString(resultSet.getString("id"));
            String name = resultSet.getString("name");
            String zip = resultSet.getString("zip");
            String address = resultSet.getString("address");
            String phone = resultSet.getString("phone");

            // How do I get an ArrayList of inspections from postgres??
            Restaurant r = new Restaurant(restaurant_id, name, zip, address, phone);
            return r;
        });
        Restaurant found = res.size() > 0 ? res.get(0) : null;
        return Optional.ofNullable(found);
    }

与java或JDBC无关。启动一个基本的 sql 终端(如果你在终端上使用 postgres,psql,那会很好)并首先学习 SQL。幸运的是,在网上可以找到很多教程:)

查询只会产生另一个 table,然后您可以对其进行循环。 SELECT * FROM foo 只是.. 让你 table。请记住,只是 table。餐厅 table 就是这样。餐馆。里面的任何地方都无法检查。 FOREIGN KEY 不是魔法,SQL 也没有真正意义上的一对多关系。至少,不是这样定义的——他们有连接的概念,它可以让你在任何你想要的东西之间临时定义这种关系。定义中不需要 FOREIGN KEY

FOREIGN KEY 所做的一切,就是对数据库说:你能为这个字段做一个索引吗,并且,请让任何事务失败,否则会写入这个 table 一行,其中'restaurant_id' 字段的值与餐厅 table 中某行的 'id' 值不匹配。它和 CHECK v > 0 一样有趣。只需检查提交的 运行。就这些了。

SELECT r.*, i.* FROM restaurant r LEFT JOIN inspection i ON i.restaurant_id = r.id WHERE r.id = ? 会做到这一点 - 可以这么说,这就是一个新的 'table'。包含行中的每一列,以及检查中的每一列。如果餐厅有 0 次检查,您会得到 1 行,其中每个 i. 相关字段都是 NULL(因为 LEFT JOIN;如果您编写了 INNER JOIN,您根本不会得到那些餐厅)。对于有 10 次检查的餐厅,您会得到 10 行,其中所有 r. 相关字段都是重复的。

如果这听起来很烦人 - 是的,我明白了。然后 运行 第二个查询:SELECT * FROM inspection WHERE restaurant_id = ?,抓取数据,填充你的数组列表。

注意:您的 tabledef 很奇怪。 score 应该有一个 NOT NULL 限制。