实体类
Student.java
public class Student {
private int id;
private String name;
private String no;
private ClassRoom classroom;
省略get,set
}
ClassRoom.java
public class ClassRoom {
private int id;
private String name;
private int grade;
private Set<Student> stus;//在oneToMany时,在多的一方建立外键,而一的一方表现形式是set<>那个对象的 集合
省略get,set
}
hbm文件
Student.hbm.xml
<hibernate-mapping package="org.th.model">
<class name="Student" table="t_student" >
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<property name="no"></property>
<!--many-to-one 用来映射多对一, 那么表示对象中属性名称, column用来表示外键的名称 -->
<!-- 当设置了cascade的时候,会自动完成关联。如果添加时没有关联对象 ,会自动创建一个关联对象
最佳实践:如果没有特殊情况不要使用cascade,特别注意:可能使用cascade的地方一般是一的一方进行删除时使用
特殊需求才会使用cascade的add,正常情况的add都是程序员自己完成添加
-->
<many-to-one name="classroom" column="cid" cascade="all" ></many-to-one>
</class>
</hibernate-mapping>
ClassRoom.hbm.xml
<hibernate-mapping package="org.th.model">
<class name="ClassRoom" table="t_classroom">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<property name="grade"></property>
<!-- inverse=true表示不再自己这一端维护关系 -->
<set name="stus" lazy="extra" inverse="true">
<key column="cid" />
<one-to-many class="Student" />
</set>
</class>
</hibernate-mapping>
测试类:
/**
*
* @Title: testAdd01
* @Description: 先添加1的,在添加多的
* @param
* @return void 返回类型
* @throws
*/
@Test
public void testAdd01() {
Session session = null;
try {
session = HibernateUtil.openSession();
session.beginTransaction();
// 先添加ClassRoom
ClassRoom c = new ClassRoom();
c.setName("java高级班");
c.setGrade(10);
session.save(c);
Student s = new Student();
s.setName("猪八戒");
s.setNo("001");
s.setClassroom(c);
session.save(s);
Student s2 = new Student();
s2.setName("孙悟空");
s2.setNo("002");
s2.setClassroom(c);
session.save(s2);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if (session != null)
session.getTransaction().rollback();
} finally {
if (session != null)
HibernateUtil.close(session);
}
}
/**
*
* @Title: testAdd02
* @Description:先添加多的,在添加1的
* @param
* @return void 返回类型
* @throws
*/
@Test
public void testAdd02() {
Session session = null;
try {
session = HibernateUtil.openSession();
session.beginTransaction();
Student s = new Student();
s.setName("煞神");
s.setNo("003");
session.save(s);
Student s2 = new Student();
s2.setName("唐僧");
s2.setNo("004");
session.save(s2);
ClassRoom c = new ClassRoom();
c.setName("java高级班");
c.setGrade(10);
session.save(c);
// 上面会发出三条新增sql
// 此时还会两条update
s.setClassroom(c);
s2.setClassroom(c);
// 最佳实践:一定要先添加一的一方,之后再添加多的一方
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if (session != null)
session.getTransaction().rollback();
} finally {
if (session != null)
HibernateUtil.close(session);
}
}
/**
*
* @Title: testAdd02
* @Description: student的关联对象classroom也是延迟加载
* @param
* @return void 返回类型
* @throws
*/
@Test
public void testLoad01() {
Session session = null;
try {
session = HibernateUtil.openSession();
session.beginTransaction();
Student s = (Student) session.load(Student.class, 1);
System.out.println(s.getName());
// 此时student的关联对象classroom也是延迟加载的,会再发出一条sql来取
System.out.println(s.getClassroom().getName());
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if (session != null)
session.getTransaction().rollback();
} finally {
if (session != null)
HibernateUtil.close(session);
}
}
@Test
public void testAdd03() {
Session session = null;
try {
session = HibernateUtil.openSession();
session.beginTransaction();
// 先添加ClassRoom
ClassRoom c = new ClassRoom();
c.setName("java高级班");
c.setGrade(10);
// 此时数据库中没有ClassRoom没有存储,所以在添加student的时候会抛出异常 但.xml文件中设置了
// cascade="all" 会自动创建关联对象
Student s = new Student();
s.setName("猪八戒");
s.setNo("001");
s.setClassroom(c);
session.save(s);
Student s2 = new Student();
s2.setName("孙悟空");
s2.setNo("002");
s2.setClassroom(c);
session.save(s2);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if (session != null)
session.getTransaction().rollback();
} finally {
if (session != null)
HibernateUtil.close(session);
}
}
/**
*
* @Title: testDelete01
* @Description: 当多的一方使用cascade时,删除某一个多的,就会报错
* @param
* @return void 返回类型
* @throws
*/
@Test
public void testDelete01() {
Session session = null;
try {
session = HibernateUtil.openSession();
session.beginTransaction();
Student student = (Student) session.load(Student.class, 1);
session.delete(student);// 这时候,cascade会制动关联classroom对象进行删除,而classroom在Student中有其他关联的话,就会报错
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if (session != null)
session.getTransaction().rollback();
} finally {
if (session != null)
HibernateUtil.close(session);
}
}