代码之家  ›  专栏  ›  技术社区  ›  Sharon Ben Asher

ActiveJDBC:save()仅为自动生成的主键生成insert?

  •  3
  • Sharon Ben Asher  · 技术社区  · 9 年前

    我最近开始使用ActiveJDBC。我有下表(postgresql)

    CREATE TABLE users (
        id                   uuid PRIMARY KEY,
        email                text UNIQUE NOT NULL,
        password             text,
        <some more nullable columns>
        created_at           timestamp with time zone NOT NULL default (now() at time zone 'utc'),
        updated_at           timestamp with time zone
    );
    

    如您所见,主键的类型为uuid,没有任何类型的自动生成值。

    这是我的User类,它为表建模:

    public class User extends Model
    {
        public User() {
            setId(UUID.randomUUID());  // sets value to primary key
        }
    ...
    }
    

    这是我创建新行并插入的尝试:

        User u = new User();
        System.out.println(u.saveIt());
    

    实际上,我预期插入会失败,因为我没有为必填电子邮件列设置任何值。然而,只是得到了false作为返回值。当我打开日志记录时,我看到框架生成了一个更新sql而不是insert:

    [main] INFO org.javalite.activejdbc.DB - Query: "UPDATE users SET email = ?, ..., updated_at = ? WHERE id = ?", with parameters: <null>, <null>, <null>, <null>, <null>, <null>, <null>, <2016-01-07 17:30:46.025>, <0621fbdb-5b95-4ee7-a474-8ee9165e2982>, took: 1 milliseconds
    

    所以我看了看 save() 方法内部 org.javalite.activejdbc.Model 类并看到了这段代码:

        if (getId() == null) {
            result = insert();
        } else {
            result = update();
        }
    

    这是否意味着id列必须为空才能生成插入?如果这是真的,这是不可接受的,所以我一定错过了什么。

    1 回复  |  直到 9 年前
        1
  •  4
  •   ipolevoy    9 年前

    @sharonbn,请参阅本文档页: http://javalite.io/surrogate_primary_keys . ActiveJDBC依赖于自动生成的ID。如果ID==null,则框架假定这是一条新记录,并生成INSERT语句。如果非空,则假定该记录已经存在,并生成UPDATE。

    在您的情况下,您需要显式调用 user.insert() 而不是 user.saveIt() 。当开发人员希望控制ID管理时,这是一种“专家”模式。此外,该方法 user.update() 是私人的。因此,要插入新记录,您将拨打

    user.insert();

    以及更新:

    user.save(); // or: user.saveIt();

    ,这取决于你想要什么。