Hiberante(五) OneToMany_xml 双向关联

实体类

   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);
		}
	}

 

 

 

 

你可能感兴趣的:(xml)