多对一:employee - department reply--thread
<!-- departId外键参考department表 -->
<many-to-one name="depart" column="departId"></many-to-one>
property-ref="name"则外键参考department表中的name字段,
如果不设column,则外键名默认为depart
try {
Department depart = new Department();
depart.setName("ddd");
Employee emp = new Employee();
emp.setDepart(depart);
emp.setName("eeee");
s = HibernateUtil.getSession();
tx = s.beginTransaction();
/*//如果映射文件没设置,这里又注释了,则会出异常,因为emp拿不到depart的id去给depart_id插入
s.save(depart);
//
s.save(emp);*/
//这种保存顺序,会多一条更新语句
s.save(emp);
//emp,depart持久态了,会感知到变化
s.save(depart);
tx.commit();
} finally {
if(s!=null) {
s.close();
}
}
-------------------------------
try {
Department depart = new Department();
depart.setName("ddd");
Employee emp = new Employee();
//建立对象关联
emp.setDepart(depart);
emp.setName("eeee");
Employee emp2 = new Employee();
//建立对象关联
emp2.setDepart(depart);
emp2.setName("eeee2");
Set<Employee> emps = new HashSet<Employee>();
emps.add(emp);
emps.add(emp2);
//会多两条update, update employee departId
//对象模型映射关联
depart.setEmps(emps);
s = HibernateUtil.getSession();
tx = s.beginTransaction();
//如果映射文件没设置,这里又注释了,则会出异常,因为emp拿不到depart的id去给depart_id插入
s.save(depart);
s.save(emp);
s.save(emp2);
/*//这种保存顺序,会多一条更新语句
//<many-to-one name="depart" column="departId" not-null="true"/>
//设置后,会报非空约束,departId --->NULL
s.save(emp);
//emp,depart持久态了,会感知到变化
s.save(depart);*/
tx.commit();
} finally {
if(s!=null) {
s.close();
}
}
一对一映射:Person--- IDCard
基于主键的one2one:IdCard.hbm.xml
constrained="true"保证了建立外键关联,数据模型
<one-to-one name="person" constrained="true"/>
Person p = (Person) s.get(Person.class, 2);
System.out.println(p.getIdCard().getExpiration());;
Hibernate:
select
person0_.id as id3_2_,
person0_.name as name3_2_,
idcard1_.id as id4_0_,
idcard1_.expiration as expiration4_0_,
person2_.id as id3_1_,
person2_.name as name3_1_
from
Person person0_
left outer join
id_card idcard1_
on person0_.id=idcard1_.id
left outer join
Person person2_
on idcard1_.id=person2_.id
where
person0_.id=?
一条两次左外连接
基于外键的一对一,可以描述为多对一,加unique="true"约束
!!!!---》idcard表 会多一个personId外键字段
Person.hbm.xml:
<hibernate-mapping package="com.ethan.domain">
<class name="Person">
<id name="id">
<generator class="native"/>
</id>
<!-- name unique -->
<property name="name"/>
<one-to-one name="idCard" property-ref="person"/>
</class>
</hibernate-mapping>
person类会根据idCard类中的person属性找到对应的idcard记录,property-ref的作用
IdCard.hbm.xml:
<hibernate-mapping package="com.ethan.domain">
<class name="IdCard" table="id_card">
<id name="id">
<generator class="native">
</id>
<!-- name unique -->
<property name="expiration"/>
<!-- 加上unique="true" 则为one2one 多一个外键字段personId,参照person表主键id-->
<many-to-one name="person" column="personId" unique="true"/>
</class>
</hibernate-mapping>
################################################
多对多查询语句,查询三张表:
Hibernate:
select
teacher0_.id as id5_0_,
teacher0_.name as name5_0_
from
Teacher teacher0_
where
teacher0_.id=?
Hibernate:
select
students0_.teacher_id as teacher1_5_1_,
students0_.student_id as student2_1_,
student1_.id as id7_0_,
student1_.name as name7_0_
from
teacher_student students0_
inner join
Student student1_
on students0_.student_id=student1_.id
where
students0_.teacher_id=?
对象有关联,放在一张表里,用组件关联:
<component>
一对一查询:
查主对象,是例外,只发出一条select语句,其他都要发出两条
Person p = (Person) s.get(Person.class, 1);
System.out.println(p.getIdCard().getExpiration());;
查询从对象,就要发出两条:
IdCard idCard = (IdCard) s.get(IdCard.class, 1);
System.out.println(idCard.getPerson().getName());
Hibernate:
select
idcard0_.id as id4_0_,
idcard0_.expiration as expiration4_0_
from
id_card idcard0_
where
idcard0_.id=?
Hibernate:
select
person0_.id as id3_1_,
person0_.name as name3_1_,
idcard1_.id as id4_0_,
idcard1_.expiration as expiration4_0_
from
Person person0_
left outer join
id_card idcard1_
on person0_.id=idcard1_.id
where
person0_.id=?
p1
###############################
hibernate默认不会保存 复杂的级联属性
例如:depart.setEmps(emps);需要设置级联
<set name="emps" cascade="save-update,delete">
delete:删除部门了,员工也跟着删除;老师和学生,不符合逻辑
inverse:放弃维护关系,让学生去记住老师。
可以省update语句,提高效率,双方都设置对相关联时(set集合()时),让多的一方去维护
inverse不能在list,数组中使用,有序的集合,这样不能放弃对关系的维护
它只会在集合中有
多对多,平级的,让谁维护都OK
inverse,多对多默认为false:
t1.setStudents(ss);
t2.setStudents(ss);
/*//产生重复插入中间表,报异常
s1.setTeachers(ts);
s2.setTeachers(ts);*/
会向中间表插记录,这是与多对一,一对一有区别的地方
<!-- departId外键参考department表 -->
<many-to-one name="depart" column="departId"></many-to-one>
property-ref="name"则外键参考department表中的name字段,
如果不设column,则外键名默认为depart
try {
Department depart = new Department();
depart.setName("ddd");
Employee emp = new Employee();
emp.setDepart(depart);
emp.setName("eeee");
s = HibernateUtil.getSession();
tx = s.beginTransaction();
/*//如果映射文件没设置,这里又注释了,则会出异常,因为emp拿不到depart的id去给depart_id插入
s.save(depart);
//
s.save(emp);*/
//这种保存顺序,会多一条更新语句
s.save(emp);
//emp,depart持久态了,会感知到变化
s.save(depart);
tx.commit();
} finally {
if(s!=null) {
s.close();
}
}
-------------------------------
try {
Department depart = new Department();
depart.setName("ddd");
Employee emp = new Employee();
//建立对象关联
emp.setDepart(depart);
emp.setName("eeee");
Employee emp2 = new Employee();
//建立对象关联
emp2.setDepart(depart);
emp2.setName("eeee2");
Set<Employee> emps = new HashSet<Employee>();
emps.add(emp);
emps.add(emp2);
//会多两条update, update employee departId
//对象模型映射关联
depart.setEmps(emps);
s = HibernateUtil.getSession();
tx = s.beginTransaction();
//如果映射文件没设置,这里又注释了,则会出异常,因为emp拿不到depart的id去给depart_id插入
s.save(depart);
s.save(emp);
s.save(emp2);
/*//这种保存顺序,会多一条更新语句
//<many-to-one name="depart" column="departId" not-null="true"/>
//设置后,会报非空约束,departId --->NULL
s.save(emp);
//emp,depart持久态了,会感知到变化
s.save(depart);*/
tx.commit();
} finally {
if(s!=null) {
s.close();
}
}
一对一映射:Person--- IDCard
基于主键的one2one:IdCard.hbm.xml
constrained="true"保证了建立外键关联,数据模型
<one-to-one name="person" constrained="true"/>
Person p = (Person) s.get(Person.class, 2);
System.out.println(p.getIdCard().getExpiration());;
Hibernate:
select
person0_.id as id3_2_,
person0_.name as name3_2_,
idcard1_.id as id4_0_,
idcard1_.expiration as expiration4_0_,
person2_.id as id3_1_,
person2_.name as name3_1_
from
Person person0_
left outer join
id_card idcard1_
on person0_.id=idcard1_.id
left outer join
Person person2_
on idcard1_.id=person2_.id
where
person0_.id=?
一条两次左外连接
基于外键的一对一,可以描述为多对一,加unique="true"约束
!!!!---》idcard表 会多一个personId外键字段
Person.hbm.xml:
<hibernate-mapping package="com.ethan.domain">
<class name="Person">
<id name="id">
<generator class="native"/>
</id>
<!-- name unique -->
<property name="name"/>
<one-to-one name="idCard" property-ref="person"/>
</class>
</hibernate-mapping>
person类会根据idCard类中的person属性找到对应的idcard记录,property-ref的作用
IdCard.hbm.xml:
<hibernate-mapping package="com.ethan.domain">
<class name="IdCard" table="id_card">
<id name="id">
<generator class="native">
</id>
<!-- name unique -->
<property name="expiration"/>
<!-- 加上unique="true" 则为one2one 多一个外键字段personId,参照person表主键id-->
<many-to-one name="person" column="personId" unique="true"/>
</class>
</hibernate-mapping>
################################################
多对多查询语句,查询三张表:
Hibernate:
select
teacher0_.id as id5_0_,
teacher0_.name as name5_0_
from
Teacher teacher0_
where
teacher0_.id=?
Hibernate:
select
students0_.teacher_id as teacher1_5_1_,
students0_.student_id as student2_1_,
student1_.id as id7_0_,
student1_.name as name7_0_
from
teacher_student students0_
inner join
Student student1_
on students0_.student_id=student1_.id
where
students0_.teacher_id=?
对象有关联,放在一张表里,用组件关联:
<component>
一对一查询:
查主对象,是例外,只发出一条select语句,其他都要发出两条
Person p = (Person) s.get(Person.class, 1);
System.out.println(p.getIdCard().getExpiration());;
查询从对象,就要发出两条:
IdCard idCard = (IdCard) s.get(IdCard.class, 1);
System.out.println(idCard.getPerson().getName());
Hibernate:
select
idcard0_.id as id4_0_,
idcard0_.expiration as expiration4_0_
from
id_card idcard0_
where
idcard0_.id=?
Hibernate:
select
person0_.id as id3_1_,
person0_.name as name3_1_,
idcard1_.id as id4_0_,
idcard1_.expiration as expiration4_0_
from
Person person0_
left outer join
id_card idcard1_
on person0_.id=idcard1_.id
where
person0_.id=?
p1
###############################
hibernate默认不会保存 复杂的级联属性
例如:depart.setEmps(emps);需要设置级联
<set name="emps" cascade="save-update,delete">
delete:删除部门了,员工也跟着删除;老师和学生,不符合逻辑
inverse:放弃维护关系,让学生去记住老师。
可以省update语句,提高效率,双方都设置对相关联时(set集合()时),让多的一方去维护
inverse不能在list,数组中使用,有序的集合,这样不能放弃对关系的维护
它只会在集合中有
多对多,平级的,让谁维护都OK
inverse,多对多默认为false:
t1.setStudents(ss);
t2.setStudents(ss);
/*//产生重复插入中间表,报异常
s1.setTeachers(ts);
s2.setTeachers(ts);*/
会向中间表插记录,这是与多对一,一对一有区别的地方