Hibernate关系映射(五)一对多、多对一双向关联@OneToMany @OneToMany Annotation方式

前两篇介绍了一对多和多对一的单向关联,而且前几篇发帖时间都比较紧凑,由于春节期间和收假这段时间都在帮公司的培训中心架构开发一个在线考试系统,所以就耽搁了,不好意思。


那么言归正传,本篇介绍一对多,多对一的双向关联,既然是双向关联,那么一对多和多对一其实是一个意思。首先来构造一个场景,实际应用场景就用前两天开发的在线考试系统的一个部分,是这样的:实体(试卷),有如下属性:Id,名称(name),标准答案(answers),试题列表(Questions);实体(试题),有如下属性:Id,题干内容(name),所属试卷(QuestionnaireId)。
一份试卷有多个试题,但是一个试题只能属于一份问卷,一对多的关系没问题,需求还有,要根据试卷找到包含的所有试题;根据试题找到所属的试卷,那么就需要建立双向关联了。


下面我们看数据库表结构:
这里写图片描述
表结构的图虽然和单向关联没区别,也反应了一个规律:外键在多方。在本例中,t_question表是多的一方,表中有一个字段questionnaireId作为外键指向了t_questionnaire表,并且参考了t_questionnaire表的id这个字段。还有一个规律就是双向关联必须设置mappedBy属性。


下面我们看实体类的书写:

import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;



/*
 * author
 * 试卷
 * */
@Entity
@Table(name="t_questionnaire")
public class Questionnaire {

    private Integer id;
    private String name;
    private String answers;
    private List<Question> questions = new ArrayList<Question>();

    public Questionnaire() {
        super();
    }

    public Questionnaire(Integer id, String name, List<Question> questions) {
        super();
        this.id = id;
        this.name = name;
        this.questions = questions;
    }

    @Id
    @GeneratedValue
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }



    public String getAnswers() {
        return answers;
    }

    public void setAnswers(String answers) {
        this.answers = answers;
    }

    @OneToMany(mappedBy="questionnaire")
    public List<Question> getQuestions() {
        return questions;
    }

    public void setQuestions(List<Question> questions) {
        this.questions = questions;
    }

}

在试卷实体类中设置了一个List< Question >来保存试卷中的所有试题,设置上@OneToMany(mappedBy=”questionnaire”)表示以对方实体类中的关系属性为主导,也就是说被Question类中的questionnaire属性映射。

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


/*
 * author
 * 试题
 * */
@Entity
@Table(name="t_question")
public class Question {

    private Integer id;
    private String name;
    private Questionnaire questionnaire;

    public Question() {
        super();
    }

    public Question(Integer id, String name, Questionnaire questionnaire) {
        super();
        this.id = id;
        this.name = name;
        this.questionnaire = questionnaire;
    }

    @Id
    @GeneratedValue
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @ManyToOne
    @JoinColumn(name="questionnaireId")
    public Questionnaire getQuestionnaire() {
        return questionnaire;
    }

    public void setQuestionnaire(Questionnaire questionnaire) {
        this.questionnaire = questionnaire;
    }

}

属性questionnaire表示该试题属于的试卷,设置上@ManyToOne和@JoinColumn(name=”questionnaireId”),为数据库表中的外键起个新的名字叫做questionnaireId


在配置好hibernate配置文件后开始进行CRUD测试:
首先进行添加数据的测试,testCreate()

     @Test
     public void testCreate(){
      Session session = sessionFactory.getCurrentSession();
      session.beginTransaction();

      Questionnaire qn = new Questionnaire();
      qn.setName("XXX公司3月转正考试");

      Question q1 = new Question();
      q1.setName("1、Java是一门OOP语言吗?A、是  B、不是");
      q1.setQuestionnaire(qn);

      Question q2 = new Question();
      q2.setName("2、Java是哪个公司的作品?A、SUN  B、MicroSoft");
      q2.setQuestionnaire(qn);

      session.saveOrUpdate(qn);
      session.saveOrUpdate(q1);
      session.saveOrUpdate(q2);

      session.getTransaction().commit();
     }

结果如下:
这里写图片描述
这里写图片描述


读取数据操作,testRead()

     @Test
     public void testRead(){
         Session session = sessionFactory.getCurrentSession();
         session.beginTransaction();

         Questionnaire qn = (Questionnaire) session.load(Questionnaire.class, 1);
         List<Question> qList = qn.getQuestions();
         System.out.println(qn.getName());
         for(Question q : qList){
             System.out.println(q.getName());
         }

         System.out.println("~~~~~~~~~~~~~~~~~");
         Question q1 = (Question) session.load(Question.class, 1);
         System.out.println(q1.getName()+"属于"+q1.getQuestionnaire().getName());


         session.getTransaction().commit();
     }

结果:

Hibernate: 
    select
        questionna0_.id as id4_0_,
        questionna0_.name as name4_0_,
        questionna0_.answers as answers4_0_ 
    from
        t_questionnaire questionna0_ 
    where
        questionna0_.id=?
XXX公司3月转正考试
Hibernate: 
    select
        questions0_.questionnaireId as question3_1_,
        questions0_.id as id1_,
        questions0_.id as id5_0_,
        questions0_.name as name5_0_,
        questions0_.questionnaireId as question3_5_0_ 
    from
        t_question questions0_ 
    where
        questions0_.questionnaireId=?
1、Java是一门OOP语言吗?A、是  B、不是
2、Java是哪个公司的作品?A、SUN  B、MicroSoft
~~~~~~~~~~~~~~~~~
1、Java是一门OOP语言吗?A、是  B、不是属于XXX公司3月转正考试

修改操作,testUpdate()

     @Test
     public void testUpdate(){
         Session session = sessionFactory.getCurrentSession();
         session.beginTransaction();

         //设置上答案
         Questionnaire qn = (Questionnaire) session.load(Questionnaire.class, 1);
         qn.setAnswers("A,A");

         session.saveOrUpdate(qn);


         session.getTransaction().commit();
     }

结果如图:
这里写图片描述


最后测试删除数据操作,testDelete()

     @Test
     public void testDelete(){
         Session session = sessionFactory.getCurrentSession();
         session.beginTransaction();

        Question q = (Question) session.load(Question.class, 2);
        session.delete(q);

         session.getTransaction().commit();
     }

结果:
这里写图片描述


下一篇介绍多对多映射,希望能对你有所帮助

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hibernate是一个Java持久化框架,它能够将Java对象映射到数据库中的表格,同时支持各种关系数据库,如MySQL、Oracle等。在Hibernate中,对于一对一、一对多和多对多的关系,我们可以通过以下方式进行映射。 一对一关系:在Hibernate中,可以通过主键关联和外键关联来实现一对一关系映射。主键关联是指两个实体之间的关联通过主键来进行,可以使用@PrimaryKeyJoinColumn注解将两个实体关联起来。外键关联是指通过一个实体引用另一个实体的主键作为外键,使用@JoinColumn注解来指定外键属性。 一对多关系:在Hibernate中,一对多关系通常通过外键关联来实现。在一的一方,使用@OneToMany注解来定义一对多关系,同时使用@JoinColumn注解指定外键属性。在多的一方,使用@ManyToOne注解来定义多对一关系,并使用@JoinColumn注解指定外键属性。 多对多关系:在Hibernate中,多对多关系通常通过中间表来实现。在多对多的两个实体中,使用@ManyToMany注解来定义多对多关系。同时,需要在中间表中创建两个外键,分别与两个实体的主键关联,并使用@JoinTable注解来指定中间表的表名和两个外键的列名。 总结:通过Hibernate的注解方式,可以方便地实现一对一、一对多和多对多关系映射。通过合理地使用注解,可以减少编写映射文件的工作量,提高开发效率。同时,Hibernate还提供了在运行时自动生成表结构的功能,可以根据Java实体类来动态创建或更新对应的数据库表格,从而提高系统的可维护性和灵活性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值