1. 集合映射
案例:
老师与课程关系(一个老师可以带多门课程)
1.实体类设计
package demo2;
import java.util.HashSet;
import java.util.Set;
/**
* Created by admin on 2017/6/19.
*/
public class Teacher {
private int teaId;
private String teaName;
//一个老师对应多门课程
private Set<String> course = new HashSet<String>();
get方法 ....
set方法 ....
}
2.映射文件配置
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="demo2" auto-import="true">
<class name="Teacher" table="t_teacher">
<id name="teaId" column="id">
<generator class="native"></generator>
</id>
<property name="teaName" column="teaName"></property>
<set name="course" table="t_course">
<key column="tId"></key>
<element column="course" type="java.lang.String" length="20"></element>
</set>
</class>
</hibernate-mapping>
set集合属性的映射
name 指定要映射的set
table 集合属性要映射到的表
key 指定集合表(t_address)的外键字段
element 指定集合表的其他字段
type 元素类型,一定要指定
3.测试
package demo2;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
/**
* Created by admin on 2017/6/19.
*/
public class Test {
private static SessionFactory sf;
static {
sf = new Configuration()
.configure()
.addClass(Teacher.class)
.buildSessionFactory();
}
@org.junit.Test
public void test() {
Teacher t = new Teacher();
t.getCourse().add("语文");
t.getCourse().add("数学");
t.setTeaName("张三");
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
session.save(t);
tx.commit();
session.close();
sf.close();
}
}
4.运行结果
关联映射
案例:
老师与学生的关系(一个老师教多个学生,多个学生拥有一个老师)
1.实体类设计
Teacher.java
package demo4;
import java.util.HashSet;
import java.util.Set;
/**
* Created by admin on 2017/6/19.
*/
public class Teacher {
private int teaId;
private String teaName;
//一对多 一个老师对应多个学生
private Set<Student> students = new HashSet<>();
get方法 ....
set方法 ....
}
Student.java
package demo4;
/**
* Created by admin on 2017/6/19.
*/
public class Student {
private int stuId;
private String stuName;
private String stuClass;
//多对一 多个学生对应一个老师
private Teacher teacher;
get方法 ....
set方法 ....
}
2.配置映射文件
Student.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="demo4" auto-import="true">
<class name="Student" table="t_student">
<id name="stuId" column="id">
<generator class="native"></generator>
</id>
<property name="stuName" column="stuName"></property>
<property name="stuClass" column="stuClass"></property>
<many-to-one name="teacher" column="teaId" class="demo4.Teacher"></many-to-one>
</class>
<!--
many-to-one 元素
属性:
name:映射类属性的名字
column:关联的字段
class:关联类的名字
cascade:设置操作中的级联策略 可选值为 all所有操作情况均进行级联、none所有操作情况均不进行级联、save-update执行save和update操作时级联、delete执行删除操作时级联
fetch:设置抓取数据的策略 默认值为select序列选择抓取 可选值为join外连接抓取
update:进行update操作时是否包含此字段
insert:进行insert操作时是否包含此字段
property-ref:指定关联类的一个属性,这个属性将会和本类的外键相对应(当外键参照一键时需要指定改属性)
-->
</hibernate-mapping>
Teacher.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="demo4" auto-import="true">
<class name="Teacher" table="t_teacher">
<id name="teaId" column="id">
<generator class="native"></generator>
</id>
<property name="teaName" column="teaName"></property>
<set name="students" table="t_student">
<key column="teaId"></key>
<one-to-many class="demo4.Student"></one-to-many>
</set>
</class>
<!--
set集合属性的映射
name 指定要映射的set集合的属性
table 集合属性要映射到的表
key 指定集合表(t_address)的外键字段
element 指定集合表的其他字段
type 元素类型,一定要指定
-->
</hibernate-mapping>
3.测试 Test.jiav(一对多)
package demo4;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
/**
* Created by admin on 2017/6/19.
*/
public class Test {
private static SessionFactory sf;
static {
sf = new Configuration()
.configure()
.addClass(Teacher.class)
.addClass(Student.class)
.buildSessionFactory();
}
@org.junit.Test
public void test() {
//保存 一对多,一的一方的操作
//老师
Teacher t = new Teacher();
t.setTeaName("张老师");
//学生对象
Student s1 = new Student();
s1.setStuName("张三");
s1.setStuClass("数学");
Student s2 = new Student();
s2.setStuName("李四");
s2.setStuClass("语文");
//关系
t.getStudents().add(s1);
t.getStudents().add(s2);
//保存
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
session.save(s1);
session.save(s2);
session.save(t);
tx.commit();
session.close();
sf.close();
}
}
测试 Test.jiav(多对一)
package demo4;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
/**
* Created by admin on 2017/6/19.
*/
public class Test2 {
private static SessionFactory sf;
static {
sf = new Configuration()
.configure()
.addClass(Teacher.class)
.addClass(Student.class)
.buildSessionFactory();
}
@org.junit.Test
public void test() {
//保存 多对一 多的一方的操作
//老师
Teacher t = new Teacher();
t.setTeaName("李老师");
//学生对象
Student s1 = new Student();
s1.setStuName("Jack");
s1.setStuClass("数学");
Student s2 = new Student();
s2.setStuName("Tom");
s2.setStuClass("语文");
//关系
// t.getStudents().add(s1);
// t.getStudents().add(s2);
s1.setTeacher(t);
s2.setTeacher(t);
//保存
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
session.save(t); //先保存一的方法
session.save(s1);
session.save(s2); //再保存多的一方
tx.commit();
session.close();
sf.close();
}
}
4.运行结果
总结:
在一对多与多对一的关联关系中,保存数据最好的通过多的一方来维护关系,这样可以减少update语句的生成,从而提高hibernate的执行效率!
配置一对多与多对一,这种叫“双向关联”
只配置一对多, 叫“单项一对多”
只配置多对一, 叫“单项多对一”
注意:
配置了哪一方,哪一方才有维护关联关系的权限!