Hibernate关联关系中的CRUD之C

以一对多的双向关联映射(Teacher——Student)作为实例

其Teacher类和Student类分别为:

package com.model;

import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class Teacher {
	private int id;
	private String name;
	private Set<Student> students = new HashSet<Student>();
	@Id
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@OneToMany(mappedBy="teacher")
	public Set<Student> getStudents() {
		return students;
	}
	public void setStudents(Set<Student> students) {
		this.students = students;
	}
}
package com.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

@Entity
public class Student {
	private int id;
	private String name;
	private Teacher teacher;
	@Id
	@GeneratedValue
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@ManyToOne
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
}

hibernate配置文件为:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory>
		<!-- 连接的数据库驱动 -->
		<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
		<!-- 连接的数据库的url -->
		<property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
		<!-- 连接的数据库的用户名-->
		<property name="connection.username">root</property>
		<!-- 连接的数据库的密码 -->
		<property name="connection.password"></property>
		<!-- 配置Hibernate数据库方言 -->
		<property name="Dialect">org.hibernate.dialect.MySQLDialect</property>
		<!-- 输出执行的SQL语句 -->
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
		<!-- 启动时撤销并重新创建数据库的模式-->
		<property name="hbm2ddl.auto">create</property>
		
		<property name="current_session_context_class">thread</property>
		
		<mapping class="com.model.Teacher"/>
		<mapping class="com.model.Student"/>
	</session-factory>	
</hibernate-configuration>

建立其测试类,测试往Teacher表中添加数据,往Student表中添加数据,是否会自动外键关联

测试类:

package com.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.Test;

import com.model.Student;
import com.model.Teacher;

public class ORMappingTest {

	@Test
	public void test() {
		Configuration cfg = new Configuration();
		cfg.configure();
		ServiceRegistry  serviceRegistry = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry(); 
		SessionFactory  sessionFactory = cfg.buildSessionFactory(serviceRegistry);
		Session session = sessionFactory.getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		Teacher t = new Teacher();
		t.setName("t");
		Student s = new Student();
		s.setName("s");
		session.save(t);
		session.save(s);
		
		transaction.commit();
		sessionFactory.close();
	}
}

测试结果:

Hibernate: 
    create table Student (
        id integer not null auto_increment,
        name varchar(255),
        teacher_id integer,
        primary key (id)
    )
Hibernate: 
    create table Teacher (
        id integer not null,
        name varchar(255),
        primary key (id)
    )
Hibernate: 
    alter table Student 
        add index FKF3371A1B43F43EE8 (teacher_id), 
        add constraint FKF3371A1B43F43EE8 
        foreign key (teacher_id) 
        references Teacher (id)
23:28:32,368  INFO SchemaExport:405 - HHH000230: Schema export complete
Hibernate: 
    insert 
    into
        Teacher
        (name, id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Student
        (name, teacher_id) 
    values
        (?, ?)

查看表内容:

------------结果发现,在student表中的外键teacher_id没有关联到表teacher中------

-----要解决这个问题,有两种方法-----

方法1:测试时在student对象中存储teacher对象,并分别存储两个对象

	Teacher t = new Teacher();
	t.setName("t");
	Student s = new Student();
	s.setName("s");
	s.setTeacher(t);
	session.save(t);
	session.save(s);

测试查看表内容为:

方法2:在Student类中注解@ManyToOne内声明属性值cascade={CascadeType.ALL}

	@ManyToOne(cascade={CascadeType.ALL})
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}

然后,测试类中设置:

		Teacher t = new Teacher();
		t.setName("t");
		Student s = new Student();
		s.setName("s");
		s.setTeacher(t);
		session.save(s);

------此方法在Student类中对Teacher的多对一关联映射中设置了级联,不需要存储对象teacher,在存储对象student时自动将其级联的teacher对象一起存储------

------结果同方法1相同

方法3:在Teacher类中注解@ManyToOne内声明属性值cascade={CascadeType.ALL},而Student类中注解@ManyToOne无任何属性值

	@OneToMany(mappedBy="teacher",cascade={CascadeType.ALL})
	public Set<Student> getStudents() {
		return students;
	}
	public void setStudents(Set<Student> students) {
		this.students = students;
	}

然后,测试类中设置:

		Teacher t = new Teacher();
		t.setName("t");
		Student s1 = new Student();
		s1.setName("s1");
		Student s2 = new Student();
		s2.setName("s2");
		t.getStudents().add(s1);
		t.getStudents().add(s2);
		s1.setTeacher(t);
		s2.setTeacher(t);
		session.save(t);

测试结果:

Hibernate: 
    create table Student (
        id integer not null auto_increment,
        name varchar(255),
        teacher_id integer,
        primary key (id)
    )
Hibernate: 
    create table Teacher (
        id integer not null,
        name varchar(255),
        primary key (id)
    )
Hibernate: 
    alter table Student 
        add index FKF3371A1B43F43EE8 (teacher_id), 
        add constraint FKF3371A1B43F43EE8 
        foreign key (teacher_id) 
        references Teacher (id)
23:49:07,348  INFO SchemaExport:405 - HHH000230: Schema export complete
Hibernate: 
    insert 
    into
        Teacher
        (name, id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Student
        (name, teacher_id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Student
        (name, teacher_id) 
    values
        (?, ?)

查看表:


------此方法在Teacher类中对Student的一对多关联映射中设置了级联,不需要存储对象student,在存储对象teacher时自动将其级联的student对象一起存储------

------此方法必须设置
		s1.setTeacher(t);
		s2.setTeacher(t);


否则student表外键不会关联到表teacher。

----------------------------------------------------------------------------

由此可见,在做关联关系表的CRUD时,需要考虑表的关系,方法1和2较简单也较常见。

-----------------cascade={CascadeType.ALL}只影响CRUD的C、U、D----------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值