zoukankan      html  css  js  c++  java
  • 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=?

  • 相关阅读:
    this指向
    作用域链
    入门
    一、servlet之初见
    jdbc之mysql
    第六章、树和二叉树
    第七章、暴力求解法
    机试
    第十三章、字符串
    栈和队列
  • 原文地址:https://www.cnblogs.com/crazylqy/p/4078801.html
Copyright © 2011-2022 走看看