• 映射:一对一(人与身份)和多对多(老师对学生)


    一、一对一:

    第一种情况:IdCard类的ID 既是主键又是外键

    package dao.po;  
    //
    public class Person  {  
        private int id; //ID
        private String name;//姓名  
        private IdCard idCard; //身份证(对象)  
    }  
    package dao.po;  
    //身份主类 
    public class IdCard{  
        private int id;//ID  
        private String address;//地址  
        private Person person; //身份证的主人  
    }  
    <?xml version="1.0"?>  
    <!DOCTYPE hibernate-mapping PUBLIC   
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
    <hibernate-mapping package="dao.po">  
        <class name="Person">       
            <id name="id">  
                <generator class="native"/>  
            </id>       
            <property name="name" not-null="true" length="255" column="`name`"/> 
            <!-- 这里做一对一映射    -->  
           <!-- 没什么好说的,就是一 one-to-one -->          
           <one-to-one name="idCard" ></one-to-one>  
        </class> 
    </hibernate-mapping>  
    <?xml version="1.0"?>  
    <!DOCTYPE hibernate-mapping PUBLIC   
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
    <hibernate-mapping package="dao.po">  
        <class name="IdCard" table="id_card">       
            <id name="id">  
                <!-- 注意:  -->  
                <!-- 本类的id 既是主键,又是外键  -->  
              <!-- IdCard对象的是从对象, Person是主对象, 先有主,后有从.  -->           
                <generator class="foreign">  
                    <!-- 此处的person是IdCard类的一个属性 -->  
                    <param name="property">person</param>  
                </generator>
            </id>       
            <property name="address" not-null="true" length="255" column="`address`"/>
            <!-- 此处的person是IdCard类的一个属性 -->  
            <!-- constrained="true" 对生成的数据表产生约束,id_card表的id既是主键,又是外键 -->    
            <!-- constrained="false" 表结构上没有约束, 取何值对对象关系没影响,只是对表结构有影响-->  
            <one-to-one name="person" constrained="true"/>  
        </class>
    </hibernate-mapping>  

      保存与查询:

    package dao;  
    import org.hibernate.Hibernate;  
    import org.hibernate.Session;  
    import org.hibernate.Transaction;  
    import dao.po.IdCard;  
    import dao.po.Person;  
    public class One2One{
        public static void main(final String[] args){  
            add();  
            final IdCard c1 = query(5);  
            System.out.println(c1.getPerson().getName());  
        }
        //保存
        public static void add(){  
            final Person p1 = new Person();  
            p1.setName("小明");
            final IdCard c1 = new IdCard();  
            c1.setAddress("北京市海淀区上地");  
            p1.setIdCard(c1); //建立关联(不能少)  
           c1.setPerson(p1); //建立关联(不能少)  
            Session session = null;  
            try{  
                session = HibernateUtil.getSeesion();  
                final Transaction tx = session.beginTransaction();  
                //session.save(p1); //  
                session.save(c1); //身份证是从对象依赖于主对象, "身份证"依赖于"人",   
               //保存 c1 , 也会自动保存 他依赖的p1,前题是c1 与p1要关联 
                tx.commit();
                //SQL 如下:  
                //Hibernate: insert into Person (`name`) values (?)  
                //Hibernate: insert into id_card (`address`, id) values (?, ?)  
                //虽然只执行了session.save(c1) , 但有两个insert 
            }finally{  
                if (session != null){  
                    session.close();  
                }  
            }  
        }  
        //查询 身份证
        public static IdCard query(final int id){  
            Session session = null;  
            try{  
                session = HibernateUtil.getSeesion();  
                final IdCard c1 = (IdCard) session.get(IdCard.class, id);  
                Hibernate.initialize(c1.getPerson());  
                return c1;  
                //SQL 如下:  
                //Hibernate: select idcard0_.id as id3_0_, idcard0_.`address` as address2_3_0_ from id_card idcard0_ where idcard0_.id=?  
                //Hibernate: select person0_.id as id2_1_, person0_.`name` as name2_2_1_, idcard1_.id as id3_0_, idcard1_.`address` as address2_3_0_ from Person person0_ left outer join id_card idcard1_ on person0_.id=idcard1_.id where person0_.id=?  
                //注意person表又连了id-card表  
            }finally{  
                if (session != null){  
                    session.close();  
                }  
            }  
        }  
    }  

    第二种情况:IdCard类的ID 只是主键, IdCard类多对一属性 person_id做 外键,指向Person类的主键。

      这种情况有点像 多对一,关系如下图:

      两个配置文件内容如下

     

    二、多对多:

      多对多由于在性能和操作都不大理想,所以使用很少。实际使用中最好转换为一对多的模型。Hibernate会为我们创建中间关联表,转换成两个一对多。

    package dao.po;  
    import java.util.Set;  
    //学生类  
    public class Student{  
        private int id;
        private String name;
        private Set<Teacher> teachers;  
    }  
    package dao.po;  
    import java.util.Set;  
    //老师类 
    public class Teacher{  
        private int id;
        private String name;
        private Set<Student> students;  
    }
    <?xml version="1.0"?>  
    <!DOCTYPE hibernate-mapping PUBLIC   
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
    <hibernate-mapping package="dao.po">
        <class name="Student">          
            <id name="id">  
                <generator class="native"/>  
            </id>       
            <property name="name" not-null="true" length="255" column="`name`"/>   
            <!-- name="teachers" 表示:Student类中有一个属性叫teachers (是Set集合)-->  
            <!-- table="teacher_student" 表示:中间表表名叫teacher_student -->           
            <set name="teachers" table="teacher_student">
                <!-- column="student_id" 表示:中间表teacher_student的字段-->  
                <!-- Student类的id与中间表teacher_student的字段student_id对应-->  
                <key column="student_id"/>
                <!-- column="teacher_id" 表示:中间表teacher_student的字段-->  
                <!-- class="Teacher" 表示:中间表teacher_student的字段teacher_id与 Teacher类的id对应-->  
                <many-to-many class="Teacher" column="teacher_id"/>  
            </set>  
        </class>
    </hibernate-mapping>    
    <?xml version="1.0"?>  
    <!DOCTYPE hibernate-mapping PUBLIC   
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
    <hibernate-mapping package="dao.po">
        <class name="Teacher">          
            <id name="id">  
                <generator class="native"/>  
            </id>       
            <property name="name" not-null="true" length="255" column="`name`"/>    
            <set name="students" table="teacher_student">  
                <key column="teacher_id"/>              
                <many-to-many class="Student" column="student_id"/>  
            </set>  
        </class>
    </hibernate-mapping> 

      保存操作:

    package dao; 
    import java.util.HashSet;  
    import java.util.Set;    
    import org.hibernate.Session;  
    import org.hibernate.Transaction;  
    import dao.po.Student;  
    import dao.po.Teacher;  
    public class Many2Many {  
        public static void main(final String[] args){  
            add();  
        }  
        //添加几个老师与学生 
        public static void add(){  
            final Teacher t1 = new Teacher();  
            t1.setName("语文老师"); 
            final Teacher t2 = new Teacher();  
            t2.setName("数学老师");
            final Student s1 = new Student();  
            s1.setName("学生小明");
            final Student s2 = new Student();  
            s2.setName("学生小红");
            //final Set<Teacher> set_t = new HashSet<Teacher>();  
            //set_t.add(t1);  
            //set_t.add(t2); 
            final Set<Student> set_s = new HashSet<Student>();  
            set_s.add(s1);  
            set_s.add(s2);
            //给老师set 学生  
            t1.setStudents(set_s); //建立关联,只在一方面建立关联就行了, 不可给学生set()了老师,再老师set()了学生  
            t2.setStudents(set_s); //建立关联,只在一方面建立关联就行了, 不可给学生建了关联,再老师建关联
            //给学生set老师,不可以再做
            Session session = null;  
            try{  
                session = HibernateUtil.getSeesion();  
                final Transaction tx = session.beginTransaction();  
                session.save(t1);  
                session.save(t2);  
                session.save(s1);  
                session.save(s2);
                tx.commit();
            }finally{  
                if (session != null){  
                    session.close();  
                }  
            }  
        }
    }  
    // 中间表teacher_student 表结构如下 :  
    //| teacher_student | CREATE TABLE `teacher_student` (  
    //  `teacher_id` int(11) NOT NULL,  
    //  `student_id` int(11) NOT NULL,  
    //  PRIMARY KEY  (`student_id`,`teacher_id`),  
    //  KEY `FK2E2EF2DE4BF3A147` (`teacher_id`),  
    //  KEY `FK2E2EF2DE3B5856A7` (`student_id`),  
    //  CONSTRAINT `FK2E2EF2DE3B5856A7` FOREIGN KEY (`student_id`) REFERENCES `student  
    //` (`id`),  
    //  CONSTRAINT `FK2E2EF2DE4BF3A147` FOREIGN KEY (`teacher_id`) REFERENCES `teacher  
    //` (`id`)  
    //) ENGINE=InnoDB DEFAULT CHARSET=utf8 |  
  • 相关阅读:
    自动交互式脚本--expect
    如何搭建web服务器 使用Nginx搭建反向代理服务器
    linux安装yaf(ubuntu教程)
    如何使用Apache的ab工具进行网站性能测试
    网虚拟主机----云服务器
    handlebars Helper用法
    网络基础知识学习
    使用清华开源镜像安装tensorflow
    安卓开发笔记(二十五):ViewPager的简单介绍和使用
    轻松搞定表白女朋友:Android版APP (零基础也可前往Github免费下载软件)
  • 原文地址:https://www.cnblogs.com/goloving/p/7613049.html
Copyright © 2020-2023  润新知