有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java缺少表别名会退回到只使用字段名

我的桌子

N
ID|T_ID
1|1
2|2

T
ID|NAME
1|T1
2|T2

使用以下表格

com.db.N N_TABLE = N.as("N_TABLE");
com.db.T T_TABLE = T.as("T_TABLE");
com.db.T T2_TABLE = T.as("T2_TABLE"); //Random alias, not used in query

SelectQuery selectQuery = create.selectQuery();
selectQuery.addFrom(N_TABLE);
selectQuery.addJoin(T_TABLE, JoinType.LEFT_OUTER_JOIN, T_TABLE.ID.eq(N_TABLE.T_ID));

Result<Record> result = selectQuery.fetch();
for (Record record : result) {
  System.out.println(record.get(T2_TABLE.NAME));
}

它会给出一个模糊警告,但即使alias出错,它仍然会得到该值。我希望它返回“null”,我猜它会退回到只使用字段名

知道我应该如何使用它来获得“null”以防出现错误的别名吗

编辑

我将尝试提供一个更具体的例子

我的桌子如下

CREATE TABLE user
(
  id bigserial NOT NULL,
  username character varying(200) NOT NULL,
  last_name character varying(100),
  created_user_id bigint NOT NULL,
  modified_user_id bigint NOT NULL,
  CONSTRAINT pk_user PRIMARY KEY (id),
  CONSTRAINT user_username_key UNIQUE (username)
)

表中的数据

3;"admin";"admin";3;3
4;"test";"test";4;3

代码

//Input params
Long userId = 4L;
boolean includeModifiedUser = false;

User userTable = USER.as("userTable");
User modifiedUserTable = USER.as("modifiedUserTable");

SelectQuery selectQuery = create.selectQuery();
selectQuery.addFrom(userTable);

//In some cases I want to include the last modifier in the query
if (includeModifiedUser) {
    selectQuery.addJoin(modifiedUserTable, JoinType.LEFT_OUTER_JOIN, modifiedUserTable.ID.eq(userTable.MODIFIED_USER_ID));
}

selectQuery.addConditions(userTable.ID.eq(userId));
Record record = selectQuery.fetchOne();

System.out.println(record.get(userTable.LAST_NAME)); //prints "test1"
System.out.println(record.get(modifiedUserTable.LAST_NAME)); //prints "test1", would expect null as modifiedUserTable is currently not joined

在jooq 3.9.3和3.9.5上测试


共 (1) 个答案

  1. # 1 楼答案

    按设计工作

    在SQL中,结果集中没有限定的列名。相反,结果集(与任何其他表一样)有一组列,每列都有一个名称,这由jOOQ的Field.getName()描述。现在,“不幸的是”,在顶级SELECT语句中,在所有SQL方言中,以及在jOOQ中,都允许有重复的列名。当您连接两个表并且两个表都有ID列时,这非常有用。这样,就不必因为出现歧义而重命名每一列

    如果表/结果中有重复的列名,jOOQ将应用^{}中描述的算法

    This will return:

    • A field that is the same as the argument field (by identity comparison).
    • A field that is equal to the argument field (exact matching fully qualified name).
    • A field that is equal to the argument field (partially matching qualified name).
    • A field whose name is equal to the name of the argument field.
    • null otherwise.

    If several fields have the same name, the first one is returned and a warning is logged.

    如您所见,这里的基本原理是,如果结果集中的字段与您在结果集中查找的字段之间没有完全或部分标识或限定名称相等,则使用Field.getName()中的字段名称来查找字段

    关于列匹配模糊性的旁注

    首先,您提到日志中有一个“模棱两可的匹配”警告,该警告随后消失。该警告表示两列经过相同的Field.getName(),但它们都不是前面描述的“精确”匹配。在这种情况下,您将得到第一列作为匹配项(出于历史原因),以及该警告,因为这可能不是您想要做的