目录
一:一对多关联概念
1.实体一对多关联(1:n)
定义:
如果对于实体集A中的每一个实体,实体集B中有n个实体(n>=0)与之联系,反之,对于实体集B中的每一个实体,实体集A中至多只有一个实体与之联系,则称实体集A与实体集B有一对多联系,记为1:n。
实例:一个班级中有若干名学生,每个学生只在一个班级中学习。
示例:在一些购物网站中,用户和订单之间的关系就是一对多关联关系(一个用户可以有多个订单,而一个订单只属于一个用户。)
2.数据库一对多关联
- 在关系模型中,只存在外键参照关系,而且是many方参照one方。
二: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表中添加一个额外字段来表示插入顺序
配置文件:
<?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的值
映射配置文件:
<?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;
}
}