014 一对多关联映射 单向(one-to-many)

在对象模型中,一对多的关联关系,使用集合来表示。

实例场景:班级对学生;Classes(班级)和Student(学生)之间是一对多的关系。

 

多对一、一对多的区别:

多对一关联映射:在多的端加入一个外键指向一的端,它维护的关系是多指向一的。

一对多关联映射:在一的端加入一个外键(集合)指向多的端,它维护的关系是一指向多的。

两者使用的策略是一样的,只是各自所站的角度不同。

 

Classes实体类:

public class Classes {

    private int id;

    private String name;
    //一对多通常使用Set来映射,Set是不可重复内容。
    //注意使用Set这个接口,不要使用HashSet,因为hibernate有延迟加载,
    private Set students;
    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;
    }
    public String getStudents() {
        return students;
    }
    public void setStudents(String students) {
        this.students= students;
    }

 

 

 

 

Students实体类:

public class Student {

    private int id;

    private String name;

 

    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;

    }

}

 

 

Student映射文件:

<hibernate-mapping>

    <class name="com.wjt276.hibernate.Student" table="t_student">

        <id name="id" column="id">

            <generator class="native"/>

        </id>

        <property name="name" column="name"/>

    </class>

</hibernate-mapping>

 

 

 

Classes映射文件:

<hibernate-mapping>

    <class name="com.wjt276.hibernate.Classes" table="t_classess">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="name" column="name"/>      
        <!--<set>标签 映射一对多(映射set集合),name="属性集合名称",然后在用<key>标签,在多的一端加入一个外键(column属性指定列名称)指向一的一端,再采用<one-to-many>标签说明一对多,还指定<set>标签中name="students"这个集合中的类型要使用完整的类路径(例如:class="com.wjt276.hibernate.Student") -->

        <set name="students">
            <key column="classesid"/>
            <one-to-many class="com.wjt276.hibernate.Student"/>
        </set>

    </class>

 

 

导出至数据库(hbmàddl)生成的SQL语句:

create table t_classes (id integer not null auto_increment, name varchar(255), primary key (id))

create table t_student (id integer not null auto_increment, name varchar(255), classesid integer, primary key (id))

alter table t_student add index FK4B90757070CFE27A (classesid), add constraint FK4B90757070CFE27A foreign key (classesid) references t_classes (id)

数据库表结构如下:

一对多 单向存储实例:

session = HibernateUtils.getSession();

            tx = session.beginTransaction();
            Student student1 = new Student();
            student1.setName("10");
            session.save(student1);//必需先存储,否则在保存classess时出错.

            Student student2 = new Student();
            student2.setName("祖儿");
            session.save(student2);//必需先存储,否则在保存classess时出错.

           
            Set<Student> students = new HashSet<Student>();
            students.add(student1);
            students.add(student2);        
            Classes classes = new Classes();
            classes.setName("wjt276");
            classes.setStudents(students);         
            session.save(classes);         
            //提交事务

            tx.commit();

 

生成的SQL语句:

Hibernate: insert into t_student (name) values (?)

Hibernate: insert into t_student (name) values (?)

Hibernate: insert into t_classes (name) values (?)

Hibernate: update t_student set classesid=? where id=?

Hibernate: update t_student set classesid=? where id=?

一对多,在一的一端维护关系的缺点:

    因为是在一的一端维护关系,这样会发出多余的更新语句,这样在批量数据时,效率不高。

    还有一个,当在多的一端的那个外键设置为非空时,则在添加多的一端数据时会发生错误,数据存储不成功。

一对多 单向数据加载:

 

session = HibernateUtils.getSession();

            tx = session.beginTransaction(); 
            Classes classes = (Classes)session.load(Classes.class, 2);

            System.out.println("classes.name=" + classes.getName());

            Set<Student> students = classes.getStudents();

            for (Iterator<Student> iter = students.iterator();iter.hasNext();){

                Student student = iter.next();
                System.out.println(student.getName());
            }
          
            //提交事务
            tx.commit();

 

加载生成SQL语句:

Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from t_classes classes0_ where classes0_.id=?

Hibernate: select students0_.classesid as classesid1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_ from t_student students0_ where students0_.classesid=?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值