java—hibernate中的外键,为什么要创建对象,如何更新引用实体中的记录

njthzxwz  于 2021-06-18  发布在  Mysql
关注(0)|答案(3)|浏览(205)

我不熟悉冬眠环境。我有一个基本的问题,我仍然试图理解为什么人们选择hibernate而不是sql。
我有两张table,一张是用户,一张是书。
一个用户可以有许多书,但一本书只有一个所有者。
如果我使用sql,我会尝试在

Table User, 
  int uid
  PRIMARY KEY (uid)

Table Book,
    int bid
    int oid //ownerid
    PRIMARY KEY (bid)
    FOREIGN KEY (oid) REFERENCES User(uid)

我不能在冬眠状态下这样做。我试过以下方法:
只生成了一个没有任何关系的用户表 @Id uid的注解。

@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-为什么我需要为book表中的uid创建用户对象?我只想在带有外键约束的books表中存储一个userid(如果用户不存在,那么book也不能存在)
2-另外,如果我想访问所有者的userid,我应该使用以下命令:

public Long getOwnerId()
{
 return user.getUid();
}

3-如果我想换书的主人,我该怎么办?既然在我的book对象中有一个完整的用户成员,那么如何只更新book表中的ownerid呢?

carvr3hs

carvr3hs1#

在manytone实体中,只需在@joincolumn注解中指定外键的名称,如下所示:

@Entity
@Table(name = "BOOK")
public class Book{
   //private Long bid;

   @ManyToOne
   @JoinColumn(name="oid")
   private User user;
}

这个 referencedColumnName parameter最常用于许多关系。

velaa5lx

velaa5lx2#

为什么需要在book表中为uid创建用户对象?
不需要对数据库表进行任何更改。hibernate将从book表中读取oid,并填充 Book.user 具有此oid标识的用户类型的对象的字段。
这样,当您在应用程序中显示关于某本书的信息时,例如,您希望显示所有者的姓名,您所需要做的就是

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

不必获取用户的id,然后执行第二个数据库查询来获取用户。
如果我想访问所有者的userid,我应该使用以下命令:
对。或者您不添加任何方法,因为任何调用者都可以这样做 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);

关于你绘制的多通Map,这是错误的。您需要阅读hibernate手册和javadoc,而不是随意尝试。它应该是简单的

@ManyToOne
@JoinColumn(name = "oid")
private User user;
ohtdti5x

ohtdti5x3#

hibernate是一个对象关系Map器,它以一种通常的面向对象的方式表示关系数据库中基于表的数据结构。
您不必使用诸如@manytone、@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);

大多数开发人员不想用ids和数据库访问等来处理那么多问题。他们只想以一种自然的面向对象的方式访问他们的业务模型,于是hibernate或jpa应运而生:

EntityManager em;
User user1 = em.find(User.class, 1L);
Book book1 = new Book();
book1.setUser(user1);

您不必为每个图书示例创建一个用户示例。只需重用现有的用户示例。
在您的示例中,我将执行以下操作:

@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

是的,如果你想处理裸身份证
通过setter设置另一个用户。book表中相应的uid将被更新。
book1.setuser(user2);
将导致声明

update BOOK set oid = 2 where bid = 1;

相关问题