复用 8.2 Hibernate:多对一单向关联(unidirectional)应用场景。
1 重新定义映射类:
1.1 表 person
的映射类定义:
package hibernate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "person")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
@Column(name = "birth")
private Date birth;
@OneToMany
@JoinColumn(name = "owner_id",
foreignKey = @ForeignKey(name = "FK_PHONE"))
private List<Phone> phones = new ArrayList<>();
public Person() {}
public Person(String name, Date birth) {
this.name = name;
this.birth = birth;
}
// 省略 Getters 和 Setters ...
}
1.2 表 phone
的映射类定义:
package hibernate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "phone")
public class Phone {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "imei")
private String imei;
@Column(name = "number")
private String number;
public Phone() {}
public Phone(String imei, String number) {
this.imei = imei;
this.number = number;
}
// 省略 Getters 和 Setters ...
}
2 测试
2.1 新增
@Test
public void testInsert() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Person person = new Person("Jack", new Date());
Phone phone1 = new Phone("866661234567890", "18012345678");
session.save(phone1);
person.getPhones().add(phone1);
Phone phone2 = new Phone("866660987654321", "18087654321");
session.save(phone2);
person.getPhones().add(phone2);
session.save(person);
transaction.commit();
session.close();
sessionFactory.close();
}
注意:
(1) 新增一对多关系数据时,默认需要分别保存“一”方数据和“多”方数据,且“多”方数据可以单独保存,但是保存“一”方数据依赖于保存“多”方数据;
(2) 如果想实现级联新增,则需要设置 @OneToMany
的 cascade
属性。
2.2 删除
2.2.1 单独删除“多”方数据成功
@Test
public void test() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
List<Phone> phones = session.createQuery(" FROM Phone").list();
for (Phone phone : phones) {
session.delete(phone);
}
transaction.commit();
session.close();
sessionFactory.close();
}
2.2.2 单独删除“一”方数据成功,因为没有将 phone
中外键 owner_id
设置为 NOT NULL
@Test
public void test() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Person person = (Person) session.createQuery(" FROM Person").list().get(0);
session.delete(person);
transaction.commit();
session.close();
sessionFactory.close();
}
如果想实现级联删除,则需要设置 @OneToMany
的 cascade
属性。
2.3 更新
@Test
public void test() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Person person = (Person) session.createQuery(" FROM Person").list().get(0);
person.setName("Tommy");
person.setBirth(new Date());
String imei = "86000000000000";
String number = "1300000000";
for (int i = 0; i < person.getPhones().size(); i++) {
person.getPhones().get(i).setImei(imei + (i + 1));
person.getPhones().get(i).setNumber(number + (i + 1));
}
session.save(person);
transaction.commit();
session.close();
sessionFactory.close();
}
运行测试,person
及其关联的 phone
记录已经级联更新了。
2.4 查询
@Test
public void test() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Person person = (Person) session.createQuery(" FROM Person").list().get(0);
System.out.println("Person Name : " + person.getName());
System.out.println("Person Birth : " + person.getBirth());
for (int i = 0; i < person.getPhones().size(); i++) {
System.out.println("---------- Person's Phone " + (i + 1) + " ----------");
System.out.println("Phone IMEI : " + person.getPhones().get(i).getImei());
System.out.println("Phone Number : " + person.getPhones().get(i).getNumber());
}
transaction.commit();
session.close();
sessionFactory.close();
}
运行测试,打印结果:
Person Name : Jack
Person Birth : 2017-07-09 22:27:00.0
......
---------- Person's Phone 1 ----------
Phone IMEI : 866661234567890
Phone Number : 18012345678
---------- Person's Phone 2 ----------
Phone IMEI : 866660987654321
Phone Number : 18087654321