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----------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是基于 Hibernate 框架创建 Student 类实现 CRUD: 1. 首先创建一个 Student 类,包含 id、name 和 age 三个属性,并在类上添加 `@Entity` 注解,用于将该类映射为数据库表。 ```java @Entity public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; private int age; // 构造方法、getter 和 setter 方法省略 } ``` 2. 在 `hibernate.cfg.xml` 配置文件配置数据库连接信息和 Hibernate 相关属性。 ```xml <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/testdb</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">password</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> </session-factory> </hibernate-configuration> ``` 3. 创建一个 DAO(数据访问对象)类,用于对 Student 对象进行 CRUD 操作。在该类通过 `SessionFactory` 获取 `Session` 对象,然后通过 `Session` 对象进行数据库操作。 ```java public class StudentDAO { private final SessionFactory sessionFactory; public StudentDAO(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public void save(Student student) { Session session = sessionFactory.openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); session.save(student); transaction.commit(); } catch (Exception e) { if (transaction != null) { transaction.rollback(); } e.printStackTrace(); } finally { session.close(); } } public Student get(int id) { Session session = sessionFactory.openSession(); Student student = null; try { student = session.get(Student.class, id); } catch (Exception e) { e.printStackTrace(); } finally { session.close(); } return student; } public void update(Student student) { Session session = sessionFactory.openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); session.update(student); transaction.commit(); } catch (Exception e) { if (transaction != null) { transaction.rollback(); } e.printStackTrace(); } finally { session.close(); } } public void delete(int id) { Session session = sessionFactory.openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); Student student = session.get(Student.class, id); session.delete(student); transaction.commit(); } catch (Exception e) { if (transaction != null) { transaction.rollback(); } e.printStackTrace(); } finally { session.close(); } } } ``` 4. 在应用程序使用 StudentDAO 类进行 CRUD 操作。 ```java public class Application { public static void main(String[] args) { Configuration configuration = new Configuration().configure(); SessionFactory sessionFactory = configuration.buildSessionFactory(); StudentDAO studentDAO = new StudentDAO(sessionFactory); // 创建 Student 对象并保存到数据库 Student student = new Student("Tom", 18); studentDAO.save(student); // 根据 id 获取 Student 对象并更新其 age 属性 student = studentDAO.get(1); student.setAge(19); studentDAO.update(student); // 根据 id 删除 Student 对象 studentDAO.delete(1); } } ``` 以上就是使用 Hibernate 框架创建 Student 类实现 CRUD 的过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值