复用 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