Hibernate:将记录插入表(一对多关系)

时间:2017-01-15 11:50:36

标签: java hibernate

我的数据库中有以下表格。

课程表

----------------------
|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");

    }
}

1 个答案:

答案 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>,再次添加它不会修改集合