我的数据库中有以下表格。
课程表
----------------------
|course_id|coursename|
----------------------
| 1 | java |
----------------------
| 2 | c++ |
----------------------
Course_Student Table
----------------------
|course_id|student_id|
----------------------
学生表
------------------------
|student_id|studentname|
------------------------
我正在使用的关系是一对多。学生可以注册许多课程。
我想要实现的是,如果学生(简)注册课程,该记录将被插入到Student和Course_Student表中。如果同一个学生(jane)注册另一门课程,学生记录将不会被插入学生表,而只会插入Course_Student表。
由于我刚接触hibernate,我不确定如何实现上述要求。请帮我。谢谢。
学生POJO课程
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column
int student_id;
@Column
String studentname;
public Student(int student_id, String studentname) {
this.student_id = student_id;
this.studentname = studentname;
}
public int getStudent_id() {
return student_id;
}
public void setStudent_id(int student_id) {
this.student_id = student_id;
}
public String getStudentname() {
return studentname;
}
public void setStudentname(String studentname) {
this.studentname = studentname;
}
@Override
public String toString() {
return "Student [student_id=" + student_id + ", studentname=" + studentname + "]";
}
}
课程POJO课程
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
public class Course {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column
int course_id;
@Column
String coursename;
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
List<Student> student = new ArrayList<Student>();
public Course(int course_id, String coursename, List<Student> student) {
this.course_id = course_id;
this.coursename = coursename;
this.student = student;
}
public int getCourse_id() {
return course_id;
}
public void setCourse_id(int course_id) {
this.course_id = course_id;
}
public String getCoursename() {
return coursename;
}
public void setCoursename(String coursename) {
this.coursename = coursename;
}
public List<Student> getStudent() {
return student;
}
public void setStudent(List<Student> student) {
this.student = student;
}
@Override
public String toString() {
return "Course [course_id=" + course_id + ", coursename=" + coursename + ", student=" + student + "]";
}
}
HibernateUtils CLass
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
private static SessionFactory sessionFactory = null;
private static SessionFactory getSessionFactory() {
if(sessionFactory==null) {
//Locate and read hibernate.cfg.xml file default in src/main/java
sessionFactory = new Configuration().configure().buildSessionFactory();
return sessionFactory;
}
else {
return sessionFactory;
}
}
public static Session getCurrentSession() {
return getSessionFactory().getCurrentSession();
}
public static Session openSession() {
return getSessionFactory().openSession();
}
public static void closeSession(Session session) {
if(session.isOpen()) {
session.clear();
}
}
}
申请类
import org.hibernate.Session;
public class Application {
//a student can apply many courses
public static void applyCourse(String coursename, String studentname) {
Session session = HibernateUtils.openSession();
session.beginTransaction();
Course course = session.get(Course.class, coursename);
//not sure how to implement this part please help
for(int i =0; i < course.getStudent().size(); i++) {
if(course.getStudent().get(i).getStudentname().equals(studentname)) {
//if student record exist,add to Course_Student table but don't add to Student table
}
else {
//if student record doesn't exist,add to Course_Student table and Student table
}
}
session.save(course);
HibernateUtils.closeSession(session);
}
public static void main(String[] args) {
Application.applyCourse("java", "jane");
Application.applyCourse("c++", "jane");
}
}
答案 0 :(得分:2)
您的协会是多对多的典型例子:每个学生注册几门课程,每门课程由几名学生参加。所以它应该是ManyToMany,而不是OneToMany。
此外,cascade = ALL在这种情况下没有意义:如果删除课程,则不希望所有参加课程的学生也被删除。你应该删除级联。
此外:
List<Student> student
这是一个清单。它包含几个学生。因此,您应将其命名为students
,而不是student
。将其命名为student
非常令人困惑:我觉得单个学生可以参加课程。选择更好的名字。同一个学生不应该多次参加同一个课程,并且课程中学生的顺序无关紧要,所以你应该使用Set<Student>
而不是List<Student>
Course course = session.get(Course.class, coursename);
这不正确。 Session.get()将唯一标识符作为参数。不是课程名称。如果是课程,则需要传递ID,而不是其名称。或者您需要一个查询(使用HQL)来查找具有该名称的课程。
//not sure how to implement this part please help
for(int i =0; i < course.getStudent().size(); i++) {
if(course.getStudent().get(i).getStudentname().equals(studentname)) {
//if student record exist,add to Course_Student table but don't add to Student table
}
else {
//if student record doesn't exist,add to Course_Student table and Student table
}
}
这不是正确的逻辑。你不应该只在课程的学生中寻找学生。否则,您只能找到已经注册课程的学生。最有可能的是,学生已经存在,但尚未注册课程。在这种情况下,您不应该重新创建学生。所以正确的逻辑是
Student student = findStudentByName(studentName);
if (student == null) {
student = createStudent(studentName);
}
course.addStudent(student);
请注意,即使学生已经存在并且已经参加课程,再次将其添加到课程也不是问题:由于该集合是Set<Student>
,再次添加它不会修改集合