【问题标题】:Hibernate: Insert records to tables(one-to-many relationship)Hibernate:向表中插入记录(一对多关系)
【发布时间】:2017-01-15 11:50:35
【问题描述】:

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

课程表

----------------------
|course_id|coursename|
----------------------
|    1    |   java   |
----------------------
|    2    |   c++    |
----------------------

Course_Student 表

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

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

    }
}

【问题讨论】:

  • 你不觉得你提到的关系和你的实现是相反的吗?我的意思是一个学生可以注册几门课程,对吧?所以,一个学生类应该有一个课程列表。你不觉得吗?
  • 在我看来,如果我把A list of student 放在Course 课上也是一样的。如果我错了,请纠正我

标签: java hibernate


【解决方案1】:

您的关联是多对多的典型示例:每个学生注册几门课程,每门课程都有几个学生参加。所以应该是多对多,而不是单对多。

此外,cascade=ALL 在这种情况下没有意义:如果您删除一门课程,您不希望所有参加该课程的学生也被删除。您应该移除级联。

还有:

List<Student> student

这是一个列表。它包含几个学生。所以你应该把它命名为students,而不是student。将其命名为 student 非常令人困惑:我给人的感觉是一个学生参加了一门课程。选择更好的名字。同一个学生不应该多次参加同一门课程,课程中学生的顺序无关紧要,所以你应该使用Set&lt;Student&gt;而不是List&lt;Student&gt;

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&lt;Student&gt;,再次添加它不会修改集合。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    相关资源
    最近更新 更多