hibernate学习笔记03---关联

1、多对一关联:
	员工和部门(多个员工属于一个部门,多对一)
	部门类:
		public class Department{
			private int id;
			private String name;
			.....
			getter和setter 方法
			.....
		}
	员工类:
		public class Employee{
			private int id;
			private String name;
			public Department dept;//可以得到部门的全部信息
			//按下面的方式只能知道部门的id,要想知道全部信息还得进行查询
			//private int departId;
			.....
			getter和setter 方法
			.....
			
		}
	表结构:
		department:id,name
		employee:id,name,dept_id(外键)
	前面学的都是一个实体类对应一个表,像现在的员工类就不能很好的映射了;
	员工的映射文件:
		...
		<class name="Employee">
			....
			<many-to-one name="depart" column="dept_id"/>
			....
		</class>
		...
		hibernate 解析到<many-to-one>时 根据属性名(depart)和 
			类名(Employee)可以知道这个属性的类型,从而可以找到
			Department类的映射文件,然后根据dept_id就可以得到一条
			部门信息了;
		ps:hibernate默认的认为这个外检对应另一张表中的主键,如果对应的不是主键则
		需要指出:<many-to-one name="depart" column="dept_id" property-ref="name"/>
	操作类:
		(1)保存;
			......
			Department depart=new Department();
			depart.setName("dept name");
			
			Employee emp=new Employee();
			emp.setDepart(depart);
			emp.setName("emp name");
			.....
			session.save(depart);
			session.save(emp);
			tx.commit();
			.....
			session.close();
			ps: 如果session.save(emp)在session.save(depart)前面,
				执行session.save(emp)时会先给dept_id一个0的值;
				当执行了session.save(depart)后dept_id有值了,
					这是hibernate会在执行更新语句更新Employee表,
					这就是hibernate的强大指出(因为此时对象都是
					持久态,他们的变化都会反映到数据库中的);
		(2)查询:
			employee emp=(Employee)session.get(Employee.class,id);
			System.out.println(emp.getDepart().getName());
			ps:session.get(Employee.class,id)这语句其实是执行了两次查询,
				首先查询"员工表"得到员工信息,然后根据员工信息中的部门id
				在查询"部门表"得到部门表。

2、一对多关联:
	还是上面的例子:从部门角度考虑就是"一对多"
		部门类:
		public class Department{
			private int id;
			private String name;
			private Set<Employee> emps;
			.....
			getter和setter 方法
			.....
		}
		员工类:
		public class Employee{
			private int id;
			private String name;
			public Department dept;//可以得到部门的全部信息
			//按下面的方式只能知道部门的id,要想知道全部信息还得进行查询
			//private int departId;
			.....
			getter和setter 方法
			.....
			
		}		
		表结构:
		department:id,name
		employee:id,name,dept_id(外键)	
		ps: 关系模型没有变化,只是对象模型变了,就是
			在"部门类"中多了个Set<Employee> emps
		映射文件:
			员工的映射文件没有变化:
			<class name="Department">
				<id name="id">
					<generator class="native"/>
				</id>
				<property name="name"/>
				<!--集合中每个元素都是一个Employee对象-->
				<!--根据id=depart_id去Employee对象的表中去找-->
				<set name="emps">
					<key column="depart_id"/>
					<one-to-many class="Employee"/>
				<set>
		操作类:
			(1)查询:
				.....
				Department depart=(Department)session.get(Department.class,id);
				System.out.println(depart.getEmps().size());
				.....
				ps:session.get(Department.class,id)是进行两次数据库访问的
				先查询"部门表"查出部门信息;
				在查询"员工表"根据部门id查询员工信息。
				
3、一对一关联:
	人和身份证---一个人对应一个身份证
	Person类:
		public class Person{
			private int id;
			private String name;
			private IdCard idCard;
			......
			getter和setter方法
			......
		}
	IdCard类:
		public class IdCard{
			//此处id非自增正,而是与Person的id对应的
			private int id;
			private String name;
			private Person person;
			......
			getter和setter方法
			......
		}
	映射文件:
		Person类的映射文件:
			<class name="Person">
				...
				<one-to-one name="idCard"/>
				...
			</class>
		IdCard类的映射文件:
			<class name="IdCard" table="id_card">
				<!--id是从person中拿到的不是自增长的-->
				<id name="id">
					<generator class="foreign">
						<param name="propery">person</param>
					</generator>
				</id>
				<one-to-one name="person" constrained="true"/>
				...
			</class>
		操作类:
			(1)添加:
				.....
				IdCard idCard=new IdCard();
				idCard.setName("身份证");
				
				Person p=new Person();
				p.setName("lid");
				p.setIdCard(idCard);
				
				idCard.setPerson(p);
				
				session.save(p);
				session.save(idCard);
				.....
			(2)查询:
				....
				Person p=(Person)s.get(Person.class,id);
				System.out.println(p.getIdCard().getName());
				....
				
		当然如果IdCard的id是自增长,而是通过外键与person关联:
		IdCard类的映射文件:
			<class name="IdCard" table="id_card">
				<id name="id">
					<generator class="native"/>
				</id>
				<many-to-one name="person" column="person_id" unique="true"/>
				...
			</class>
		Person类的映射文件:
			<class name="Person">
				...
				<one-to-one name="idCard" property-ref="person"/>
				...
			</class>
			
4、多对多关联:如老师和学生(一个老师对应多个学生,一个学生对应多个老师)
	多对多是我们回创建一个中间表,这样就变成两个一对多了;
	Teacher类:
		public class Teacher{
			private int id;
			private String name;
			private Set<Student> students;
			......
			getter 和setter方法
			......
		}
	Student类:
		public class Student{
			private int id;
			private String name;
			private Set<Teacher> teachers;
			......
			getter 和setter方法
			......
		}
	表结构:
		teacher: id,name
		teacher_student:teacher_id,student_id;
		student:id,name;
	映射文件:
		Teacher的映射文件:
			<class name="Teacher">
				......
				<!--中间表是teacher_student-->
				<set name="students" table="teacher_student">
					<key column="teacher_id"/>
					<many-to-many class="Student" column="student_id"/>
				</set>
				......
			</class>
		Student的映射文件:
			<class name="Student">
				......
				<!--中间表是teacher_student-->
				<set name="teachers" table="teacher_student">
					<key column="student_id"/>
					<many-to-many class="Teacher" column="teacher_id"/>
				</set>
				......
			</class>
				
5、组件关联:
		Name类:
			public class Name{
				private String firstName;
				private String lastName;
				......
				getter和setter方法
				......
			}
		
		User类:
			public class User{
				private int id;
				private Name name;
				private Date birthday;
				.....
				getter 、setter方法
			}
		User的映射文件:
			<class name=User">
				......
				<component name="name">
					<property name="firstName" column="first_name"/>
					<property name="lastName" column="last_name"/>
				</component>
				......
			</class>
		ps:当然我们也可以按一对一或者多对一来处理上面的情况,不过那样,用户和
			Name就分别对应一张表了;
			而向上面这种处理只会生成一张表(firstName和lastName分别对应列first_name和last_name)
		
				

你可能感兴趣的:(hibernate学习笔记03---关联)