hibernate的多对多解析

问题?hibernate的多对多的解析

环境:先搭建hibernate环境

注:在这里我们选择,由持久化类和映射文件来生成表(因为这样做的话,只在多对多的两个之间生成一个中间表。共三张表)。如果由表来生成持久化类和映射文件的话,它会生成一个联合组件类。相对来说在操作上。困难度加大了,也复杂化了。

                   

案例:

先写两个持久化类和相应的映射文件

Course.java

package cn.itcast.hibernate.manyTOmanyDomain;

import java.io.Serializable;
import java.util.Set;

public class Course implements Serializable{
	private Long cid;
	private String cname;
	private String description;
	private Set<Students> students;//Students多的方
	
	
	public Long getCid() {
		return cid;
	}

	public void setCid(Long cid) {
		this.cid = cid;
	}

	public String getCname() {
		return cname;
	}

	public void setCname(String cname) {
		this.cname = cname;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public Set<Students> getStudents() {
		return students;
	}

	public void setStudents(Set<Students> students) {
		this.students = students;
	}

	
}


Students.java

package cn.itcast.hibernate.manyTOmanyDomain;

import java.io.Serializable;
import java.util.Set;

public class Students implements Serializable{
	private Long sid;
	private String sname;
	private String description;
	private Set<Course> courses;//Course多的一方
	
	public Long getSid() {
		return sid;
	}

	public void setSid(Long sid) {
		this.sid = sid;
	}

	public String getSname() {
		return sname;
	}

	public void setSname(String sname) {
		this.sname = sname;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public Set<Course> getCourses() {
		return courses;
	}

	public void setCourses(Set<Course> courses) {
		this.courses = courses;
	}


}

Course.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="cn.itcast.hibernate.manyTOmanyDomain.Course">
		<id name="cid" length="5">
			<generator class="increment"></generator>
		</id>
		<property name="cname" length="20"></property>
		<property name="description" length="100"></property>
		
		<set name="students" table="student_course" cascade="save-update">
			<key>
				<column name="cid"></column>
			</key>
			<many-to-many class="cn.itcast.hibernate.manyTOmanyDomain.Students" column="sid"></many-to-many>
		</set>
	</class>
</hibernate-mapping>

Students.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="cn.itcast.hibernate.manyTOmanyDomain.Students">
		<id name="sid" type="java.lang.Long" length="5">
			<generator class="increment"></generator>
		</id>
		<property name="sname" type="java.lang.String" length="20"></property>
		<property name="description" length="100"></property>
		<!-- 
			table就是用来描述第三张表
			column,这个外键,就是在那张表,外键就填谁
		 -->
		<set name="courses" table="student_course" cascade="save-update">
			<key>
				<column name="sid"></column>
			</key>
			<many-to-many class="cn.itcast.hibernate.manyTOmanyDomain.Course" column="cid"></many-to-many>
		</set>
	</class>
</hibernate-mapping>

最后就是配置文件了.hibernate.cfg.xml文件

因为在这里我是放再跟持久化文件和映射文件同一个包下的。所以相对来说。工具类就得采用上一次所说的第二种方式了(在configur(URL)中写配置文件的地址。第一种方式,是配置文件就根目录下,就不用写。)


hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<!-- 
		一个session-factory只能连接一个数据库,一般我们也只写一个。
	-->
<session-factory>
	<!-- 
		数据库的用户名
	-->
	<property name="connection.username">root</property>
	<!-- 
		数据库的密码
	-->
	<property name="connection.password">root</property>
	<!-- 
		数据库的url:itcast_sh_hibernate是你用的数据库
	-->
	<property name="connection.url">
		jdbc:mysql://localhost:3306/itcast_sh_hibernate
	</property>
	<!-- @hbm2ddl.auto
		作用:根据持久化类和映射文件生成表
		validate:验证持久化类在映射文件中描述正不正确,只验证
		create-drop:hibernate容器开启的时候生成表,关闭的时候删除表(不用)
		create:hibernate容器开启的时候生成表(不用)
		update:表示hibernate开启的时候,先检查持久化类和映射问件和表到底对应不对应,
		不对应的话,我新建一个表。对应的话,验证描述正不正确(validate)
	-->
	<property name="hbm2ddl.auto">update</property>

	<!-- 
		显示hibernate内部生成的sql语句
	-->
	<property name="show_sql">true</property>

	<!--@mapping resource
		表示和映射文件相对应
	-->
	<mapping
		resource="cn/itcast/hibernate/manyTOmanyDomain/Course.hbm.xml" />
	<mapping
		resource="cn/itcast/hibernate/manyTOmanyDomain/Students.hbm.xml" />

</session-factory>
</hibernate-configuration>

最后就是写读取配置文件的工具类了。( 注:这里的@Before是指先执性子类的static,最后在执性父类的static,不然url就传不过去了)

HibernateUtil.java

package cn.itcast.hibernate.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Before;

public class HibernateUtil {
	public static SessionFactory sessionfactory;
	public static String url;

	@Before
	public void init(){
		Configuration configuration=new Configuration();
		configuration.configure(url);
		sessionfactory=configuration.buildSessionFactory();
	}
}

最后就是写测试文件了。注意,一定要先建库(MySql)
package cn.itcast.hibernate.manyTOmanyTest;


import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.itcast.hibernate.manyTOmanyDomain.Course;
import cn.itcast.hibernate.manyTOmanyDomain.Students;
import cn.itcast.hibernate.util.HibernateUtil;

/**
 * 1、新建一个课程
 * 2、新建一个学生
 * 3、新建课程的同时新建学生 级联
 * 4、已经存在一个课程,新建一个学生,建立课程和学生之间的关系
 * 5、已经存在一个学生,新建一个课程,建立课程和学生之间的关系
 * 6、已经存在一个课程,已经存在一个学生,建立关联
 * 7、把已经存在的一些学生加入到已经存在的一个课程中
 * 8、把一个学生加入到一些课程中
 * 9、把多个学生加入到多个课程中
 * 10、把一个已经存在的学生从一个已经的课程中移除
 * 11、把一些学生从一个已经存在的课程中移除
 * 12、把一个学生从一个课程转向到另外一个课程
 * 13、删除课程
 * 14、删除学生
 * @author Think
 *
 */
public class CreateTable extends HibernateUtil{
	static{ 
		url="cn/itcast/hibernate/manyTOmanyDomain/hibernate.cfg.xml";
	}
	@Test
	public void CreateTable1(){
		
	}
/*	 * 1、新建一个课程
	 * 2、新建一个学生
	 * 3、新建课程的同时新建学生 级联*/
	@Test
	public void testSaveStudent_Cascade_Course_Save(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Students student = new Students();
		student.setSname("班长2");
		student.setDescription("牛人");
		
		Course course = new Course();
		course.setCname("生理卫生");
		course.setDescription("很好");
//通过操作student表级联操作course表(这个的要求是在students映射文件中,必须要有save-upate)
//		Set<Course> courses = new HashSet<Course>();
//		courses.add(course);
//		student.setCourses(courses);
//		session.save(student);
//		
		
//通过course表级联操作操作student表(这个的要求是在course映射文件中,必须要有save-upate)
		Set<Students> students=new HashSet<Students>();
		students.add(student);
		course.setStudents(students);
		session.save(course);
		transaction.commit();
		session.close();
	}
	
	/**
	 * 已经存在一个课程,新建一个学生,建立课程和学生之间的关系
	 *    从课程角度出发
	 * 已经存在一个学生,新建一个课程,建立课程和学生之间的关系
	 */
	@Test
	public void testUpdateCourse_Cascade_Student_Save_R(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
//		Course course = (Course)session.get(Course.class, 1L);
//		Students student = new Students();
//		student.setSname("班迷");
//		student.setDescription("班丝:班长的钢丝");
//		course.getStudents().add(student);
		
		
//		session.save(student);
		//这个是在course映射文件中没有save-update的时候做,又student操作course
		Students students=(Students)session.get(Students.class, 1L);
		Course course=new Course();
		course.setCname("大神2");
		course.setDescription("非常牛逼");
		
		students.getCourses().add(course);
		transaction.commit();
		session.close();
	}
	
	//已经存在一个课程,已经存在一个学生,建立关联
	@Test
	public void testR(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Course course = (Course)session.get(Course.class, 1L);
		Students student = (Students)session.get(Students.class, 2L);
//		student.getCourses().add(course);
		course.getStudents().add(student);
		transaction.commit();
		session.close();
	}

	/**
	 * 把学生3,4加入到课程1中
	 */
	@Test
	public void testR_Some(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Course course = (Course)session.get(Course.class, 1L);
		Students student3 = (Students)session.get(Students.class, 3L);
		Students student4 = (Students)session.get(Students.class, 4L);
		course.getStudents().add(student3);//很明显较相对来说,由课程来加入学生效率高
		course.getStudents().add(student4);
		transaction.commit();
		session.close();
	}
	
	/**
	 * 把一个学生加入到一些课程中
	 */
	@Test
	public void testR_Some_2(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Students student = (Students)session.get(Students.class, 3L);
		List<Course> courseList = session.createQuery("from Course where cid in(1,2,3)").list();
		student.getCourses().addAll(courseList);
		transaction.commit();
		session.close();
	}
	
	/**
	 * 把一个课程加入到一些学生中
	 */
	@Test
	public void testR_Some_3(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Course course = (Course)session.get(Course.class, 3L);
		List<Students> studentsList = session.createQuery("from Students where sid in(1,2,3,4)").list();
		course.getStudents().addAll(studentsList);
		transaction.commit();
		session.close();
	}
	
	/**
	 * 把学生从一个课程转移到另外一个课程
	 */
	@Test
	public void testTransform(){
		Session session = sessionfactory.openSession();
		Transaction transaction = session.beginTransaction();
		Students student = (Students) session.get(Students.class, 3L);
		Course course2 = (Course)session.get(Course.class, 2L);
		Course course3 = (Course)session.get(Course.class, 3L);
		
		student.getCourses().remove(course3);
		student.getCourses().add(course2);
		transaction.commit();
		session.close();
	}
}

案例:下载 案例


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值