1.单向多对一配置
基础配置
<!-- Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.driver.jdbcDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
<property name="connection.username">scott</property>
<property name="connection.password">tiger</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.OracleDialect</property>
<!-- Echo all executed SQL to stdout -->
<property name="format_sql">true</property>
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping name="hbm/Student.hbm.xml"></mapping>
<mapping name="hbm/Teacher.hbm.xml"></mapping>
One 配置对象
clas Student
private int sid;
private String sname;
private Teacher teacher;
Many
class Student
private int tid;
private String tname;
private Student student;
Mapping配置文件
many:
<!-- 参考文档 《Hibernate Reference Documentation》 for 3.5.6-Final -->
<hibernate-mapping package="com.hxzy.manyone">
<!-- 类名 -->
<class name="com.hxzy.manytoone.entity.Teacher" table="teacher">
<!-- 生成id主键 -->
<id name="tid" column="tid">
<generator class="sequence"><!-- 生成序列 -->
<param name="sequence">
seq_teacher
</param>
</generator>
</id>
<!-- 属性name -->
<property name="name" not-null="true"></property>
<many-to-one name="Student" class="com.hxzy.manytoone.entity.Student" column="s_id" cascade="save-update">
</many-to-one>
<!-- column(可选):外键字段的名称。也可以通过嵌套的 <column> 指定 -->
<!-- class(可选 — 默认是通过反射得到的属性类型):被关联的类的名字。 -->
<!--cascade(级联)(可选)表明操作是否从父对象级联到被关联的对象 -->
</class>
</hibernate-mapping>
one:
<hibernate-mapping package="com.hxzy.manyone">
<class name="com.hxzy.manytoone.entity.Student" table="student">
<id name="sid" column="sid">
<generator class="sequence">
<param name="sequence">
seq_student
</param>
</generator>
</id>
<property name="name" not-null="true"></property>
</class>
</hibernate-mapping>
dao层
Session session = null;
/**
* 获取session
* */
public Session getSession() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory= cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
return session;
}
public void addTeacher(Teacher teacher) {
session = getSession();
Transaction ts = session.beginTransaction();
try {
session.save(teacher);//存入老湿信息
ts.commit();//提交事务
}catch(Exception e) {
e.printStackTrace();
ts.rollback();//报错则回滚
}finally {
session.close();
}
}
测试代码
@Test
public void test1() {
DaoImpl daoImpl = new DaoImpl();
Teacher t1 = new Teacher();
Teacher t2 = new Teacher();
Student s1 = new Student();
s1.setSname("gz1");
t1.setTname("gt1");
t1.setStudent(s1);
t2.setTname("gt2");
t2.setStudent(s1);
daoImpl.addObject(s1);
daoImpl.addObject(t1);
daoImpl.addObject(t2);
}
创建的库
框架在数据库中的操作
create table Teacher(Id bigint not null primary key,sid bigint not null )//在teacher中创建主键tid,外键sid并和student中的sid关联
create table Student ( sid bigint not null primary key )//创建sid主键
2.单向一对一配置
基于外键关联的单向一对一关联和单向多对一关联几乎是一样的。唯一的不同就是单向一对一关
联中的外键字段具有唯一性约束。
xml中其他不变仅在多对一节点添加unique=“true”
<!-- 单向一对一关联 -->
<many-to-one name="student"
class="com.hxzy.manyone.entity.Student" unique="true"
column="stu_id" not-null="true" />
3.基于外键关联的单向一对多关联是一种很少见的情况,并不推荐使用。
对于这种关联关系最好使用连接表。
4.使用连接表的一对多
基于连接表的单向一对多关联 应该优先被采用。请注意,通过指定unique=“true”,我们可以把多
样性从多对多改变为一对多。
<!--many-->
student:
<class name="com.hxzy.manymany.entity.Student" table="student">
<id name="sid" column="sid">
<generator class="sequence">
<param name="seuqence">seq_student</param>
</generator>
</id>
<property name="sname" not-null="true"></property>
</class>
<!-- one-->
teacher:
<!-- 类,id,name -->
<class name="com.hxzy.manymany.entity.Teacher" table="teacher">
<id name="tid" column="tid">
<generator class="sequence">
<param name="sequence">seq_teacher</param>
</generator>
</id>
<property name="tname" not-null="true"></property>
<!-- 基于连接表的单向一对多 -->
<set name="set" table="teacher_student"><!-- 新表-->
<key column="tid" />
<many-to-many column="sid" unique="true"
class="com.hxzy.manymany.entity.Student" />
</set>
</class>
teacher类:
private int tid;
private String tname;
private Set<Student> set = new HashSet<Student>();
student类
private int sid;
private String sname;
private Teacher teacher;
test:
@Test
public void test1() {
DaoImpl daoImpl = new DaoImpl();
Teacher t1 = new Teacher();
Set<Student> set = new HashSet<Student>();
Student s1 = new Student();
Student s2 = new Student();
s1.setSname("gz1");
s2.setSname("gz2");
set.add(s1);
set.add(s2);
t1.setTname("gt1");
t1.setSet(set);
daoImpl.addObject(s1);
daoImpl.addObject(s2);
daoImpl.addObject(t1);
}
最终形成的数据库结构
可以看到,(tid,sid)作为连接表的主键,sid和tid为连接表的外键,从而将student的主键sid化作了teacher的外键
.多对多
单向多对多
<!-- 类名 -->
<class name="com.hxzy.manyone.entity.Teacher" table="teacher">
<!-- 生成id主键 -->
<id name="id" column="id">
<generator class="sequence">
<!-- 生成序列 -->
<param name="sequence">
seq_teacher
</param>
</generator>
</id>
<!-- 属性name -->
<property name="name" not-null="true"></property>
<!--生成新表,将id中stu_id关联 -->
<set name="Student" table="teacher_sutdent">
<key column="id" />
<many-to-many column="stu_id"
class="com.hxzy.manyone.entity.Student" />
</set>
</class>
测试代码
@Test
public void Test1() {
DaoImpl daoImpl = new DaoImpl();
Student student1 = new Student();
Student student2 = new Student();
Teacher teacher1 = new Teacher();
// Teacher teacher2 = new Teacher();
Set<Student> set1 = new HashSet<Student>();
student1.setName("a");
student2.setName("b");
teacher1.setName("gz");
// teacher2.setName("gz1");
set1.add(student1);
set1.add(student2);
teacher1.setSet(set1);
daoImpl.addObject(student1);
daoImpl.addObject(student2);
daoImpl.addObject(teacher1);
// daoImpl.addTeacher(teacher2);
效果如下
生成一个新表t_s,其主键为stu_id,外键为(id(来自teacher),stu_id),与student中的外键stu_id关联,与teacher中的外键stu_id关联
teacher表
student表
5.双向关联
双向多对一关联 是最常见的关联关系
<class name="com.hxzy.manymany.entity.Teacher" table="teacher">
<id name="tid" column="tid">
<generator class="sequence">
<param name="sequence">seq_teacher</param>
</generator>
</id>
<property name="tname" not-null="true"></property>
<!-- 基于外键的双向多对一 many -->
<many-to-one name="student"
class="com.hxzy.manymany.entity.Student" column="sid"
cascade="save-update" />
</class>
<class name="com.hxzy.manymany.entity.Student" table="student">
<id name="sid" column="sid">
<generator class="sequence">
<param name="seuqence">seq_student</param>
</generator>
</id>
<property name="sname" not-null="true"></property>
<!-- 基于外键的双向多对一 :one -->
<set name="set" inverse="true">
<key column="sid" />
<one-to-many class="com.hxzy.manymany.entity.Teacher" />
</set>
</class>
Class Many:
public class Teacher {
private int tid;
private String tname;
private Student student;
Class One:
public class Student {
private int sid;
private String sname;
Set<Teacher> set = new HashSet<Teacher>();
Test:
public class Test1 {
@Test
public void test1() {
DaoImpl daoImpl = new DaoImpl();
Teacher t1 = new Teacher();
Teacher t2 = new Teacher();
Set<Teacher> set1 = new HashSet<Teacher>();
Student s1 = new Student();
t1.setTname("gt1");
t2.setTname("gt2");
set1.add(t1);
set1.add(t2);
s1.setSname("gz1");
s1.setSet(set1);
daoImpl.addObject(t1);
daoImpl.addObject(t2);
daoImpl.addObject(s1);
}
}
生成的数据库结构
双向一对一关联基于外键关联也很常见
teacher:
<class name="com.hxzy.manymany.entity.Teacher" table="teacher">
<id name="tid" column="tid">
<generator class="sequence">
<param name="sequence">seq_teacher</param>
</generator>
</id>
<property name="tname" not-null="true"></property>
<!-- 基于外键关联的双向一对一关联 -->
<many-to-one name="student" column="sid"
class="com.hxzy.manymany.entity.Student" unique="true"
not-null="true" />
</class>
student:
<class name="com.hxzy.manymany.entity.Student" table="student">
<id name="sid" column="sid">
<generator class="sequence">
<param name="seuqence">seq_student</param>
</generator>
</id>
<property name="sname" not-null="true"></property>
<!-- 基于外键的双向一对一 :one -->
<one-to-one nam="teacher" property-ref="student"
class="com.hxzy.manymany.entity.Teacher" />
</class>
teacher:
public class Teacher {
private int tid;
private String tname;
private Student student;
}
student:
public class Student {
private int sid;
private String sname;
private Teacher teacher;
test:
@Test
public void test1() {
DaoImpl daoImpl = new DaoImpl();
Teacher t1 = new Teacher();
Teacher t2 = new Teacher();
Student s1 = new Student();
Student s2 = new Student();
t1.setTname("gt1");
t2.setTname("gt2");
s1.setSname("gz1");
s2.setSname("gz2");
t1.setStudent(s1);
t2.setStudent(s2);
daoImpl.addObject(s1);
daoImpl.addObject(s2);
daoImpl.addObject(t1);
daoImpl.addObject(t2);
}
基于主键关联的一对一关联则需要使用特定的id生成器
teachet:
<class name="com.hxzy.manymany.entity.Teacher" table="teacher">
<id name="tid" column="tid">
<generator class="sequence">
<param name="sequence">seq_teacher</param>
</generator>
</id>
<property name="tname" not-null="true"></property>
<!-- 基于主键关联的一对一关联需要使用特定的id生成器 -->
<one-to-one name="student"
class="com.hxzy.manymany.entity.Student" />
</class>
student:
<class name="com.hxzy.manymany.entity.Student" table="student">
<!-- 基于主键关联的一对一关联需要使用特定的id生成器 -->
<id name="sid" column="tid">
<generator class="foreign">
<param name="property">teacher</param>
</generator>
</id>
<property name="sname" not-null="true"></property>
<!-- 基于主键关联的一对一关联需要使用特定的id生成器 -->
<one-to-one name="teacher"
class="com.hxzy.manymany.entity.Teacher" constrained="true" />
</class>
test:
@Test
public void test1() {
DaoImpl daoImpl = new DaoImpl();
Teacher t1 = new Teacher();
Teacher t2 = new Teacher();
Student s1 = new Student();
Student s2 = new Student();
t1.setTname("gt1");
t2.setTname("gt2");
s1.setSname("gz1");
s2.setSname("gz2");
s1.setTeacher(t1);//引用他人主键的一方中set他人属性
s2.setTeacher(t2);
daoImpl.addObject(t1);
daoImpl.addObject(t2);
daoImpl.addObject(s1);
daoImpl.addObject(s2);
}
生成的数据库如下: