班级(一)--->学生(多)
package com.xh.hibernate.beans;
import javax.persistence.*;
/**
* Created by root on 17-5-12.
*/
@Entity
@Table
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id",nullable = false,unique = true)
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "cid")
private Classes classes;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Classes getClasses() {
return classes;
}
public void setClasses(Classes classes) {
this.classes = classes;
}
}
package com.xh.hibernate.beans;
import javax.persistence.*;
import java.util.Set;
/**
* Created by root on 17-5-12.
*/
@Entity
@Table
public class Classes {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id",nullable = false,unique = true)
private Long id;
private String name;
@OneToMany(mappedBy = "classes",cascade = {CascadeType.ALL} )
private Set<Student> students;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!--hibernate_first要操作的数据库-->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hbm2ddl.auto">update</property>
<!--是否在控制台输出操作的sql语句-->
<property name="hibernate.show_sql">true</property>
<mapping class="com.xh.hibernate.beans.Student" ></mapping>
<mapping class="com.xh.hibernate.beans.Classes" ></mapping>
</session-factory>
</hibernate-configuration>
测试类;
package com.xh.hibernate;
import com.xh.hibernate.beans.Classes;
import com.xh.hibernate.beans.Student;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import java.util.HashSet;
import java.util.Set;
/**
* Unit test for simple App.
*/
public class AppTest {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
@Test
public void saveStu() {
Session session = sessionFactory.openSession();
Transaction transation = session.getTransaction();//获得事务
transation.begin();//开启事务
Student student = new Student();
student.setName("s1");
session.save(student);
transation.commit();//提交事务
}
/**
* saveStu():
* MariaDB [test]> select * from Student;
* +----+------+------+
* | id | name | cid |
* +----+------+------+
* | 1 | s1 | NULL |
* +----+------+------+
*/
@Test
public void saveClas() {
Session session = sessionFactory.openSession();
Transaction transation = session.getTransaction();//获得事务
transation.begin();//开启事务
Classes classes = new Classes();
Set c1 = new HashSet();
classes.setName("1b");
Student student1 = new Student();
student1.setName("1b-s1");
Student student2 = new Student();
student2.setName("1b-s2");
c1.add(student1);
c1.add(student2);
//保存Classes之前先要让Student拥有Classes
student1.setClasses(classes);
student2.setClasses(classes);
classes.setStudents(c1);
//session.save(classes);
session.persist(classes);
transation.commit();//提交事务
}
/**
@Test
public void saveClas() {
Session session = sessionFactory.openSession();
Transaction transation = session.getTransaction();//获得事务
transation.begin();//开启事务
Classes classes = new Classes();
Set c1 = new HashSet();
classes.setName("1b");
Student student1 = new Student();
student1.setName("1b-s1");
Student student2 = new Student();
student2.setName("1b-s2");
c1.add(student1);
c1.add(student2);
classes.setStudents(c1);
session.save(classes);
transation.commit();//提交事务
}
*saveClas():
*MariaDB [test]> select * from Student;
+----+-------+------+
| id | name | cid |
+----+-------+------+
| 1 | s1 | NULL |
| 2 | 1b-s1 | NULL |
| 3 | 1b-s2 | NULL |
+----+-------+------+
MariaDB [test]> select * from Classes;
+----+------+
| id | name |
+----+------+
| 1 | 1b |
+----+------+
Student的外键为空,是因为Classes不负责维护关系,好像mappedBy 就意味inverse=true
hibernate默认只能是多的一方维护关系。
所以在保存Classes之前先要让Student拥有Classes。
于是添加:
@Test
public void saveClas() {
Session session = sessionFactory.openSession();
Transaction transation = session.getTransaction();//获得事务
transation.begin();//开启事务
Classes classes = new Classes();
Set c1 = new HashSet();
classes.setName("1b");
Student student1 = new Student();
student1.setName("1b-s1");
Student student2 = new Student();
student2.setName("1b-s2");
c1.add(student1);
c1.add(student2);
//保存Classes之前先要让Student拥有Classes
student1.setClasses(classes);
student2.setClasses(classes);
classes.setStudents(c1);
session.save(classes);
transation.commit();//提交事务
}
MariaDB [test]> select * from Student;
+----+-------+------+
| id | name | cid |
+----+-------+------+
| 1 | s1 | NULL |
| 2 | 1b-s1 | NULL |
| 3 | 1b-s2 | NULL |
| 4 | 1b-s1 | 2 |
| 5 | 1b-s2 | 2 |
+----+-------+------+
MariaDB [test]> select * from Classes;
+----+------+
| id | name |
+----+------+
| 1 | 1b |
| 2 | 1b |
+----+------+
*/
@Test
public void delClasses(){
Session session = sessionFactory.openSession();
Transaction transation = session.getTransaction();//获得事务
transation.begin();//开启事务
//System.out.println(session.get(Classes.class,5L).toString());
Classes classes=(Classes)session.get(Classes.class,7L);
for (Student s:classes.getStudents()){
s.setClasses(null);
}
session.delete(classes);
transation.commit();//提交事务
}
/**
*首先看看数据库
* MariaDB [test]> select * from Classes;
+----+------+
| id | name |
+----+------+
| 5 | 1b |
+----+------+
1 row in set (0.00 sec)
MariaDB [test]> select * from Student;
+----+-------+------+
| id | name | cid |
+----+-------+------+
| 12 | s1 | NULL |
| 13 | 1b-s1 | 5 |
| 14 | 1b-s2 | 5 |
+----+-------+------+
执行后:
MariaDB [test]> select * from Student;
+----+------+------+
| id | name | cid |
+----+------+------+
| 12 | s1 | NULL |
+----+------+------+
1 row in set (0.00 sec)
说明级联删除了
如果我不想级联删除,希望只删除Classes,Student的cid置空
1、先修改Classes的cascade = {CascadeType.ALL}改为:
cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH}
2、session.save(classes);改为
session.persist(classes);
否则不会级联保存学生
现在的数据库:
MariaDB [test]> select * from Student;
+----+-------+------+
| id | name | cid |
+----+-------+------+
| 12 | s1 | NULL |
| 15 | 1b-s1 | 7 |
| 16 | 1b-s2 | 7 |
+----+-------+------+
3 rows in set (0.00 sec)
MariaDB [test]> select * from Classes;
+----+------+
| id | name |
+----+------+
| 6 | 1b |
| 7 | 1b |
+----+------+
2 rows in set (0.00 sec)
@Test
public void delClasses(){
Session session = sessionFactory.openSession();
Transaction transation = session.getTransaction();//获得事务
transation.begin();//开启事务
//System.out.println(session.get(Classes.class,5L).toString());
Classes classes=(Classes)session.get(Classes.class,7L);
session.delete(classes);
transation.commit();//提交事务
}
Cannot delete or update a parent row: a foreign key constraint fails (`test`.`Student`, CONSTRAINT `FK_ot8tyy5l6tvxn3xxphmx1efl6` FOREIGN KEY (`cid`) REFERENCES `Classes` (`id`))
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
看来不用CascadeType.REMOVE 并非智能的不删除关联对象
好像Hibernate不会自动置空(也许有,但我目前还没有发现),所以要手动:
@Test
public void delClasses(){
Session session = sessionFactory.openSession();
Transaction transation = session.getTransaction();//获得事务
transation.begin();//开启事务
//System.out.println(session.get(Classes.class,5L).toString());
Classes classes=(Classes)session.get(Classes.class,7L);
for (Student s:classes.getStudents()){
s.setClasses(null);
}
session.delete(classes);
transation.commit();//提交事务
}
MariaDB [test]> select * from Student;
+----+-------+------+
| id | name | cid |
+----+-------+------+
| 12 | s1 | NULL |
| 15 | 1b-s1 | NULL |
| 16 | 1b-s2 | NULL |
+----+-------+------+
3 rows in set (0.00 sec)
MariaDB [test]> select * from Classes;
+----+------+
| id | name |
+----+------+
| 6 | 1b |
+----+------+
1 row in set (0.00 sec)
*/
}