为了账号安全,请及时绑定邮箱和手机立即绑定

休眠中的外键,为什么创建对象,如何更新引用实体中的记录

休眠中的外键,为什么创建对象,如何更新引用实体中的记录

凤凰求蛊 2022-01-06 17:45:08
我是 Hibernate 环境的新手。我有一个基本问题,我仍在努力理解为什么人们选择 Hibernate 而不是 SQL。我有两张表,可以说一张是用户,一张是书。一个用户可以拥有多本书,但一本书只有一个所有者。如果我使用 SQL,我尝试写在Table User,   int uid  PRIMARY KEY (uid)Table Book,    int bid    int oid //ownerid    PRIMARY KEY (bid)    FOREIGN KEY (oid) REFERENCES User(uid) 我无法在 Hibernate 中执行此操作。我尝试了以下方法:生成了一个没有任何关系的用户表,只有@Iduid 的注解。@Entity@Table(name="USER")public class User {    @Id    @GeneratedValue(strategy = GenerationType.AUTO)    @Column(name = "uid")    private Long uid;    public Long getUid()    { return uid;}}生成了一个书桌,但我无法理解这一点。互联网上的一切都说我需要使用@ManyToOne和@JoinColumns。如果我使用它们,我需要有一个对象:@Entity@Table(name = "BOOK")public class Book{    @ManyToOne    @JoinColumn(name="uid",       referencedColumnName = "What should I write here?")    @Column(name ="oid") //owner id    private User user;}1- 为什么我需要在书表中为我的 uid 创建一个用户对象?我只想用外键约束在我的书籍表中存储一个用户 ID(如果用户不存在,那么这本书也不能存在)2-另外,如果我想访问所有者的用户 ID,我应该使用这个:public Long getOwnerId(){ return user.getUid();}3- 如果我想更改书的所有者,我该怎么做?由于我的 book 对象中有一个完整的用户成员,我如何只更新我的 book 表中的 ownerid?
查看完整描述

3 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

在 ManyToOne 实体中,您只需要在 @JoinColumn 注释中指定外键的名称,如下所示:


@Entity

@Table(name = "BOOK")

public class Book{

   //private Long bid;


   @ManyToOne

   @JoinColumn(name="oid")

   private User user;

}

参数referencedColumnName最常用于多对多关系。



查看完整回答
反对 回复 2022-01-06
?
繁星淼淼

TA贡献1775条经验 获得超11个赞

Hibernate 是一个对象关系映射器,以通常的面向对象的方式表示关系数据库的基于表的数据结构,仅此而已。


您不必使用@ManyToOne、@OneToMany 等注释。您可以这样做:


@Entity

@Table(name="USER")

public class User {

    @Id

    @Column(name = "uid")

    private Long uid;


    // setters and getters

}


@Entity

@Table(name = "BOOK")

public class Book {


    @Id

    @Column(name = "bid")

    private Long bid;


    @Column(name = "oid")

    private Long oid;


    // setters and getters

}


EntityManager em;

Long uid = em.createQuery("SELECT u.uid FROM User u WHERE ....", Long.class).getSingleResult();

book.setUid(uid);

大多数开发人员不想处理那么多的 ID 和数据库访问等。他们只想以一种自然的面向对象的方式访问他们的业务模型,然后 hibernate 或 JPA 进来了:


EntityManager em;

User user1 = em.find(User.class, 1L);

Book book1 = new Book();

book1.setUser(user1);    

您不必为每个 Book 实例创建一个 User 实例。只需重用现有的 User 实例。

在您的示例中,我将执行以下操作:


@Entity

@Table(name="USER")

public class User {

    // ...

    @OneToMany(mappedBy = "user")

    private Collection<Book> books = new ArrayList<>();


    public void add(Book book) {

        book.setUser(this);

        books.add(book);

    }


    public void remove(Book book) {

        book.setUser(null);

        books.remove(book);

    }

}


@Entity

@Table(name = "BOOK")

public class Book {

    // ...

    @ManyToOne

    @JoinColumn(name="oid", referencedColumnName = "uid")

    private User user;

}


EntityManager em;

User user1 = em.find(User.class, 1L);

Book book1 = new Book();

Book book2 = new Book();

user1.addBook(book1);

user1.addBook(book2);


book1.getUser(); // user1

book2.getUser(); // user1    

是的,如果你想处理裸 ID


通过 setter 设置另一个用户。book表中对应的uid会被更新。


book1.setUser(user2);


将导致声明


update BOOK set oid = 2 where bid = 1;


查看完整回答
反对 回复 2022-01-06
?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

为什么我需要在 book 表中为我的 uid 创建一个用户对象?


您无需对数据库表进行任何更改。Hibernate 将从 book 表中读取 oid,并将Book.user使用此 oid 标识的 User 类型的对象填充该字段。


这样,例如,当您在应用程序中显示有关一本书的信息时,并且希望显示所有者的姓名时,您需要做的就是


display(book.getUser().getName());

不必获取用户的 ID,然后执行第二个数据库查询来获取用户。


如果我想访问所有者的用户 ID,我应该使用这个:


是的。或者您不添加任何方法,因为任何调用者都可以book.getUser().getUid()自己完成。


如果我想更改书的所有者,我应该怎么做?


假设您拥有新所有者的 uid,您将获得由此 ID 标识的用户,并在书上设置:


User newOwner = entityManager.find(User.class, newOwnerId);

// or User newOwner = entityManager.getReference(User.class, newOwnerId);

// depending on what you prefer

book.setUser(newOwner);

关于您对多对一的映射,这是错误的。您需要阅读 Hibernate 手册和 javadoc,而不是随意尝试。它应该只是


@ManyToOne

@JoinColumn(name = "oid")

private User user;


查看完整回答
反对 回复 2022-01-06
  • 3 回答
  • 0 关注
  • 163 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信