《Hibernate上课笔记》------class6------Hibernate实现一对多关联映射

简介: 《Hibernate上课笔记》------class6------Hibernate实现一对多关联映射

一:一对多关联概念

1.实体一对多关联(1:n)

定义:


20210324153409341.png


如果对于实体集A中的每一个实体,实体集B中有n个实体(n>=0)与之联系,反之,对于实体集B中的每一个实体,实体集A中至多只有一个实体与之联系,则称实体集A与实体集B有一对多联系,记为1:n。

实例:一个班级中有若干名学生,每个学生只在一个班级中学习。


示例:在一些购物网站中,用户和订单之间的关系就是一对多关联关系(一个用户可以有多个订单,而一个订单只属于一个用户。)


20210324153935391.png


2.数据库一对多关联

  • 在关系模型中,只存在外键参照关系,而且是many方参照one方。


20210324154159888.png


二:Hibernate实现单向一对多关联

引例:

通常情况下,在一些购物网站系统中,用户和订单之间的关系就是一对多关联关系,并且对于用户来说需要知道自己有哪些订单,对于商家来说需要知道某个订单属于哪个用户,思考这种情况该如何实现?

1.xml配置实现

用户类:


public class User {
  private int id;
  private String userName;
  private String passWord;
  private Set<Order> orders = new HashSet<>();
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getUserName() {
    return userName;
  }
  public void setUserName(String userName) {
    this.userName = userName;
  }
  public String getPassWord() {
    return passWord;
  }
  public void setPassWord(String passWord) {
    this.passWord = passWord;
  }
  public Set<Order> getOrders() {
    return orders;
  }
  public void setOrders(Set<Order> orders) {
    this.orders = orders;
  }
  @Override
  public String toString() {
    return "User [id=" + id + ", userName=" + userName + ", passWord=" + passWord + ", orders=" + orders + "]";
  }
}

用户配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity">
  <class name="User" table="user">
    <id name="id" type="int">
      <column name="id"></column>
      <generator class="native"></generator>
    </id>
    <property name="userName" column="user_name"
      type="java.lang.String">
    </property>
    <property name="passWord" column="password"
      type="java.lang.String" />
    <set name="orders" cascade="all">
      <key column="user_id"></key>
      <one-to-many class="Order" />
    </set>
  </class>
</hibernate-mapping>

订单类:

public class Order {
  private int id;
  private int price;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  @Override
  public String toString() {
    return "Order [id=" + id + ", price=" + price + ", getId()=" + getId() + ", getClass()=" + getClass()
        + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]";
  }
  public int getPrice() {
    return price;
  }
  public void setPrice(int price) {
    this.price = price;
  }
}

订单配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity">
  <class name="Order" table="n_order">
    <id name="id" type="int">
        <column name="id"></column>
      <generator class="increment"></generator>
    </id>
     <property name="price"></property>
  </class>
</hibernate-mapping>

测试类:

public class Test {
  public static void main(String[] args) {
    // 保存用户
    // saveUser();
    // 保存订单
    // saveOrders();
    // 根据用户查找订单
    // findOrderByUserId();
    // 根据用户id删除订单
    deleteOrderByUserId();
  }
  public static void saveUser() {
    // 1.获取session对象
    Session session = HibernateUtil.openSession();
    Transaction tx = session.beginTransaction();
    User user = new User();
    user.setUserName("张三");
    user.setPassWord("123");
    session.save(user);
    tx.commit();
    session.close();
    // 5.关闭sessionFactory
  }
  public static void saveOrders() {
    // 1.获取session对象
    Session session = HibernateUtil.openSession();
    Transaction tx = session.beginTransaction();
    User user = session.get(User.class, new Integer(1));
    Set<Order> orders = user.getOrders();
    for (int i = 0; i < 3; i++) {
      Order order = new Order();
      order.setPrice(35);
      orders.add(order);
    }
    user.setOrders(orders);
    session.save(user);
    tx.commit();
    session.close();
    // 5.关闭sessionFactory
  }
  public static void findOrderByUserId() {
    Session session = HibernateUtil.openSession();
    Transaction tx = session.beginTransaction();
    User user = session.get(User.class, new Integer(1));
    System.out.println(user.toString());
    tx.commit();
    session.close();
    // 5.关闭sessionFactory
  }
  public static void deleteOrderByUserId() {
    Session session = HibernateUtil.openSession();
    Transaction tx = session.beginTransaction();
    User user = session.get(User.class, new Integer(1));
    session.delete(user);
    tx.commit();
    session.close();
    // 5.关闭sessionFactory
  }
}

当使用list集合映射时,需要在order表中添加一个额外字段来表示插入顺序

20210324155808154.png

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity">
  <class name="User" table="user">
    <id name="id" type="int">
      <column name="id"></column>
      <generator class="native"></generator>
    </id>
    <property name="userName" column="user_name"
      type="java.lang.String">
    </property>
    <property name="passWord" column="password"
      type="java.lang.String" />
    <list name="orders" cascade="all">
      <key column="user_id"></key>
      <index column="order_index"></index>
      <one-to-many class="Order" />
    </list>
  </class>
</hibernate-mapping>

当使用Map集合映射时,需要在Order表中添加也给额外字段来记录Map中key的值

20210324160134800.png

映射配置文件:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity">
  <class name="User" table="user">
    <id name="id" type="int">
      <column name="id"></column>
      <generator class="native"></generator>
    </id>
    <property name="userName" column="user_name"
      type="java.lang.String">
    </property>
    <property name="passWord" column="password"
      type="java.lang.String" />
    <map name="orders" cascade="all">
      <key column="user_id"></key>
      <index column="order_key" type="string"></index>
      <one-to-many class="Order" />
    </map>
  </class>
</hibernate-mapping>

二:Hibernate双向一对多关联

目的:通过用户可以找到订单,通过订单也可以找到用户

1.使用xml文件方式完成配置

数据库表结构同上,只是配置文件发生改变

User类:

public class User {
  private int id;
  private String userName;
  private String passWord;
  private Map<String, Order> orders = new HashMap<>();
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getUserName() {
    return userName;
  }
  public void setUserName(String userName) {
    this.userName = userName;
  }
  public String getPassWord() {
    return passWord;
  }
  public void setPassWord(String passWord) {
    this.passWord = passWord;
  }
  public Map<String, Order> getOrders() {
    return orders;
  }
  public void setOrders(Map<String, Order> orders) {
    this.orders = orders;
  }
  @Override
  public String toString() {
    return "User [id=" + id + ", userName=" + userName + ", passWord=" + passWord + ", orders=" + orders + "]";
  }
}

User类配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity">
  <class name="User" table="user">
    <id name="id" type="int">
      <column name="id"></column>
      <generator class="native"></generator>
    </id>
    <property name="userName" column="user_name"
      type="java.lang.String">
    </property>
    <property name="passWord" column="password"
      type="java.lang.String" />
    <map name="orders" cascade="all">
      <key column="user_id"></key>
      <index column="order_key" type="string"></index>
      <one-to-many class="Order" />
    </map>
  </class>
</hibernate-mapping>

Order类:

public class Order {
  private int id;
  private int price;
  private User user;
  public User getUser() {
    return user;
  }
  public void setUser(User user) {
    this.user = user;
  }
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  @Override
  public String toString() {
    return "Order [id=" + id + ", price=" + price + ", getId()=" + getId() + ", getClass()=" + getClass()
        + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]";
  }
  public int getPrice() {
    return price;
  }
  public void setPrice(int price) {
    this.price = price;
  }
}

Order类配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity">
  <class name="Order" table="n_order2">
    <id name="id" type="int">
      <column name="id"></column>
      <generator class="increment"></generator>
    </id>
    <property name="price"></property>
    <many-to-one name="user" column="user_id" class="User"></many-to-one>
  </class>
</hibernate-mapping>

2.使用注解方式完成配置

User类:

@Entity
@Table(name = "user")
public class User {
  private int id;
  private String userName;
  private String passWord;
  private Map<String, Order> orders = new HashMap<>();
  @Id
  @GeneratedValue(generator = "nat")
  @GenericGenerator(name = "nat", strategy = "native")
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  @Column(name = "user_name")
  public String getUserName() {
    return userName;
  }
  public void setUserName(String userName) {
    this.userName = userName;
  }
  public String getPassWord() {
    return passWord;
  }
  public void setPassWord(String passWord) {
    this.passWord = passWord;
  }
  @OneToMany(mappedBy = "user", targetEntity = Order.class, cascade = CascadeType.ALL)
  @MapKeyColumn(name = "order_key")
  public Map<String, Order> getOrders() {
    return orders;
  }
  public void setOrders(Map<String, Order> orders) {
    this.orders = orders;
  }
  @Override
  public String toString() {
    return "User [id=" + id + ", userName=" + userName + ", passWord=" + passWord + ", orders=" + orders + "]";
  }
}

Order类:

@Entity
@Table(name = "n_order2")
public class Order {
  private int id;
  private int price;
  private User user;
  @ManyToOne
  @JoinColumn(name = "user_id")
  public User getUser() {
    return user;
  }
  public void setUser(User user) {
    this.user = user;
  }
  @Id
  @GeneratedValue(generator = "nat")
  @GenericGenerator(name = "nat", strategy = "native")
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  @Override
  public String toString() {
    return "Order [id=" + id + ", price=" + price + ", getId()=" + getId() + ", getClass()=" + getClass()
        + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]";
  }
  public int getPrice() {
    return price;
  }
  public void setPrice(int price) {
    this.price = price;
  }
}
相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
相关文章
|
2月前
|
Java 数据库连接 API
解锁高效开发秘籍:深入探究 Hibernate 如何优雅处理一对多与多对多关系,让数据映射再无烦恼!
【9月更文挑战第3天】Hibernate 是 Java 领域中最流行的 ORM 框架之一,广泛用于处理实体对象与数据库表之间的映射。尤其在处理复杂关系如一对多和多对多时,Hibernate 提供了丰富的 API 和配置选项。本文通过具体代码示例,展示如何使用 `@OneToMany`、`@JoinColumn`、`@ManyToMany` 和 `@JoinTable` 等注解优雅地实现这些关系,帮助开发者保持代码简洁的同时确保数据一致性。
41 4
|
SQL XML Java
Hibernate框架【四】——基本映射——多对一和一对多映射
Hibernate框架【四】——基本映射——多对一和一对多映射
166 0
|
Java 数据库连接
hibernate一对多关系操作
hibernate一对多关系操作
166 1
hibernate一对多关系操作
|
Java 关系型数据库 数据库连接
《Hibernate上课笔记》---class1---Hibernate简介
《Hibernate上课笔记》---class1---Hibernate简介
71 0
《Hibernate上课笔记》---class1---Hibernate简介
|
XML Java 数据库连接
《Hibernate上课笔记》----class4----Hibernate继承关系映射实现详解
《Hibernate上课笔记》----class4----Hibernate继承关系映射实现详解
92 0
《Hibernate上课笔记》----class4----Hibernate继承关系映射实现详解
|
XML Java 数据库连接
《Hibernate上课笔记》-----class5----Hibernate实现一对一关联映射
《Hibernate上课笔记》-----class5----Hibernate实现一对一关联映射
67 0
《Hibernate上课笔记》-----class5----Hibernate实现一对一关联映射
|
XML Java 数据库连接
《Hibernate上课笔记》-----class7----Hibernate实现多对多关联映射
《Hibernate上课笔记》-----class7----Hibernate实现多对多关联映射
91 0
《Hibernate上课笔记》-----class7----Hibernate实现多对多关联映射
|
SQL Java 数据库连接
《Hibernate上课笔记》-----class8----Hibernate的检索方式和检索策略
《Hibernate上课笔记》-----class8----Hibernate的检索方式和检索策略
107 0
《Hibernate上课笔记》-----class8----Hibernate的检索方式和检索策略
|
Java 数据库连接 数据库
《Hibernate上课笔记》----class2----Hibernate的增删改查操作
《Hibernate上课笔记》----class2----Hibernate的增删改查操作
105 0
|
SQL Java 数据库连接
《Hibernate上课笔记》-----class3----Hibernate的单实体映射
《Hibernate上课笔记》-----class3----Hibernate的单实体映射
118 0