单向的多对一: 只需要n(多)这端访问1(一)这端的情况!没有1的端访问多的端的时候。
比如: 班主任老师 和学生
一对多:从老师的角度,一个老师对应多个学生
多对一:从学生的角度,多个学生对应一个老师
一、 POJO 类 及 xxx.hbm.xml 配置文件
public class Student {
private int id;
private String sname;
private Teacher teacher;
...
}
public class Teacher {
private Integer id;
private String tname;
....
}
从老师的角度:单向1(老师), 映射没变化
<class name="cn.jq.hibernate5.model.Teacher" table="T_TEACHER">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<property name="tname" type="java.lang.String">
<column name="t_name" />
</property>
</class>
从老师的角度:单向n(学生)many-to-one , 映射用个 package 属性,方便管理包名
<hibernate-mapping package="cn.jq.hibernate5.model">
<class name="Student" table="T_STUDENT">
<id name="id" type="int">
<column name="id" />
<generator class="native" />
</id>
<property name="sname" type="java.lang.String">
<column name="s_name" />
</property>
<!--
name: 为Student(多)类 这端的属性名
calss: 为Teacher(yi)类 这端的 全限定类名(此处使用了package属性)
column: 为Student(多)表 的外键名
-->
<many-to-one name="teacher" class="Teacher">
<column name="teacher_id" />
</many-to-one>
</class>
</hibernate-mapping>
二、 junit 测试
public class Hibernate5Test {
SessionFactory sessionFactory = null;
Session session = null;
Transaction transaction = null;
@Before
public void init() {
Configuration configuration = new Configuration().configure();
StandardServiceRegistry serviceRegistry = configuration.getStandardServiceRegistryBuilder().build();
sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction();
}
@After
public void destory() {
transaction.commit();
session.close();
sessionFactory.close();
}
}
建表 sql :
Hibernate:
create table T_STUDENT (
id integer not null auto_increment,
s_name varchar(255),
teacher_id integer,
primary key (id)
) engine=InnoDB
Hibernate:
create table T_TEACHER (
id integer not null auto_increment,
t_name varchar(255),
primary key (id)
) engine=InnoDB
Hibernate:
alter table T_STUDENT
add constraint FK7gnkgubne3mlxj43gqwtf4a97
foreign key (teacher_id)
references T_TEACHER (id)
从老师的角度
1、 新增:推荐先插入一(1)的这端, 效率高!
结论: 先插入 Teacher(1) 这端数据,发起3条 insert 语句。
先插入 Student(多) 这端数据,发起3条 insert 和 2条 update 语句,
扫描二维码关注公众号,回复:
2735975 查看本文章
![](/qrcode.jpg)
@Test
public void test() {
Teacher teacher = new Teacher("老师1");
Student student1 = new Student();
student1.setSname("学生1");
Student student2 = new Student();
student2.setSname("学生2");
//建立单向多对一关联关系
student1.setTeacher(teacher);
student2.setTeacher(teacher);
session.save(teacher);
session.save(student1);
session.save(student2);
}
2. 删除:
结论: 删除 Student (多) 这端数据,可正常删除,Teacher(1) 这端数据 没影响 。
删除 Teacher (1) 这端数据, 会出错, 因为受到 外键约束。
@Test
public void test() {
Teacher teacher = session.load(Teacher.class, 1);
session.delete(teacher); //报错
}
3. 修改: 正常修改, 没问题
@Test
public void test() {
Teacher teacher = session.load(Teacher.class, 1);
teacher.setTname("老师11");
session.save(teacher);
Student student = session.get(Student.class, 2);
student.setSname("学生22");
session.save(student);
}
4. 查询:
结论: 默认情况下, 查询多(n)这端对象, 只要没使用到关联的对象, 不会发起关联的对象的查询!
因为使用的懒加载, 所以在使用关联对象之前关闭session, 必然发生赖加载异常!
@Test
public void test() {
Teacher teacher = session.load(Teacher.class, 1);
System.out.println(teacher);
Student student = session.get(Student.class, 2);
System.out.println(student.getTeacher().getTname());
}