Hibernate对象关联映射

对象关系映射(Object Relational Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。

多对一单向关系映射:student-classes

public class Classes implements Serializable{
    private Integer cid;
    private String cname;
    private String ccode;
get/set方法省略

public class Student implements Serializable{
    private Integer sid;
    private String sname;
    private Integer age;
    private String gender;
    private Date birthday;
    private Boolean ismarried;
    private Double wight;
    //班级对象的引用
    private Classes cls;
get/set方法省略

配置Classes.hbm.xml

<hibernate-mapping package="cn.gzsxt.test.many2one">
    <class name="Classes" table="tb_classes">
        <id name="cid"> <generator class="native" /> </id>
        <property name="cname" />
        <property name="ccode" />   
    </class>
</hibernate-mapping>

配置Student.hbm.xml

<hibernate-mapping package="cn.gzsxt.test.many2one">
    <class name="Student" table="tb_student">
        <id name="sid"> <generator class="native" /> </id>
        <property name="sname" />
        <property name="age" />
        <property name="gender" />
        <property name="birthday" />
        <property name="ismarried" />
        <property name="wight" />
        <!-- 配置many-to-one
            name:班级对象的引用名
            class:班级对象的类名
            column:外键名(引用班级对象对应的表)
            foreign-key:外键的约束名
         -->
        <many-to-one name="cls" class="Classes" column="cid" not-null="true" foreign-key="FK_STU_CLS"/>
    </class>
</hibernate-mapping>

执行java文件代码,生成表结构和数据

public class TestMany2One {
    Session session;
    Transaction transaction;
    @Before
    public void setUp() throws Exception {
        session = SessionFactoryUtils.getCurrentSession();
        transaction = session.getTransaction();
        transaction.begin();
    }
    @After
    public void tearDown() throws Exception {
        transaction.commit();
    }
    @Test
    public void createTable(){
        Configuration cfg = new Configuration().configure("/hibernate.cfg.xml");
        SchemaExport export = new SchemaExport(cfg);
        export.create(true,true);
    }
    @Test
    public void save() {
        Student bx = new Student(null, "benxi", 26, "女", new Date(System.currentTimeMillis()), false, 47.5);
        Student zf = new Student(null, "zhangfeng", 22, "男", new Date(System.currentTimeMillis()), false, 77.5);
        Student dhy = new Student(null, "杜红艳", 25, "女", new Date(System.currentTimeMillis()), false, 42.5);

        Classes java = new Classes(null,"java","java0706");
        Classes php = new Classes(null,"php","java0710");

        //分班(学生选择班级)-建立对象关系。学生选择班级
        bx.setCls(java);
        zf.setCls(java);
        dhy.setCls(php);

        /*保存到数据库
         * 先保存多的一方,再保存一的一方
         * 先保存一的一方再保存多的一方会发出多余的update或者执行不通过
         */
        session.save(java);
        session.save(php);
        session.save(bx);
        session.save(zf);
        session.save(dhy);

    }

    //查询学生信息和班级信息
    @Test
    public void qeury(){
        Student stu = (Student) session.get(Student.class, 1);
        System.out.println(stu);
        System.out.println(stu.getCls().getCname());
    }

}

一对多单向关系映射:classes-Student

classes文件

public class Classes implements Serializable{
    private Integer cid;
    private String cname;
    private String ccode;
    //班级中有多个学生
    private Set<Student> stuset = new HashSet<>();

Student文件

public class Student implements Serializable{
    private Integer sid;
    private String sname;
    private Integer age;
    private String gender;
    private Date birthday;
    private Boolean ismarried;
    private Double wight;

classes.hbm.xml文件中,改变如下:

<class name="Classes" table="tb_classes">
    <id name="cid"> <generator class="native" /> </id>
    <property name="cname" />
    <property name="ccode" />
    <!-- 配置one to many -->
    <set name="stuset">
        <!-- 在学生表(多的一方)加上外键 -->
        <key column="c_id"/>
        <one-to-many class="Student"/>
    </set>
</class>
student.hbm.xml文件,改变如下:
<class name="Student" table="tb_student">
        <id name="sid"> <generator class="native" /> </id>
        <property name="sname" />
        <property name="age" />
        <property name="gender" />
        <property name="birthday" />
        <property name="ismarried" />
        <property name="wight" />
        相对于前面,把多对一配置删除
    </class>

操作的java文件;

//分班(学生选择班级)-建立对象关系。班级选择学生
java.getStuset().add(bx);
java.getStuset().add(zf);
php.getStuset().add(dhy);

多对一双向关系映射:Student-Classes

在student和classes文件中,都加入对象引用。
在*.hbm.xml文件中也配置对应的内容
然后在java文件中就可以实现双向选择

/*分班(学生选择班级)-建立对象关系
* 默认情况下,一的一方处于主动(主动权)
* 在学生选择班级,班级也选择学生多的情况下,
* 班级选择生效
*/
bx.setCls(java);
zf.setCls(java);
dhy.setCls(php);
java.getStuset().add(dhy);
php.getStuset().add(bx);

设置Student为主动权:

<!-- 如果需要让多的一方主动,一的一方被动
    需要配置inverse属性-控制反转,只能配置在集合中
    true - 放弃
    false - 不放弃 -->
<set name="stuset" inverse="true">
    <key column="cid"/>
    <one-to-many class="Student"/>
</set>

其他对象关联映射方式:

一对多(单向):
只写xml文件配置

<class name="Classes" table="tb_classes">
    <id name="cid"> <generator class="native" /> </id>
省略。。。
    <!-- 配置one to many -->
    <set name="stuset">
        <!-- 在学生表(多的一方)加上外键 -->
        <key column="c_id"/>
        <one-to-many class="Student"/>
    </set>  
</class>
<class name="Student" table="tb_student">
    <id name="sid"> <generator class="native" /> </id>
    <property name="sname" />
省略。。。
</class>

多对一(单向):

<class name="Student" table="tb_student">
    <id name="sid"> <generator class="native" /> </id>
    省略...
    <!-- 配置many-to-one
        name:班级对象的引用名
        class:班级对象的类名
        column:外键名(引用班级对象对应的表)
        foreign-key:外键的约束名,可以随便起
     -->
    <many-to-one name="cls" class="Classes" column="cid" not-null="true" foreign-key="FK_STU_CLS"/>
</class>
<class name="Classes" table="tb_classes">
    <id name="cid"> <generator class="native" /> </id>
    <property name="cname" />
    <property name="ccode" />
</class>

多对一(双向):

<class name="Student" table="tb_student">
    <id name="sid"> <generator class="native" /> </id>
    省略...   
    <!-- 配置many-to-one
    name:班级对象的引用名
    class:班级对象的类名
    column:外键名(引用班级对象对应的表)
    foreign-key:外键的约束名
    级联操作cascade:当操作一个对象时,此对象引用了其他对象,则其他对象会先同样的操作
     save-upade 级联保存更新
     delete  级联删除
     none   不操作
-->
    <many-to-one cascade="save-update" name="cls" class="Classes" column="cid" not-null="true" foreign-key="FK_STU_CLS"/>
</class>
<class name="Classes" table="tb_classes">
    <id name="cid"> <generator class="native" /> </id>
    <property name="cname" />
    <property name="ccode" />
    <!-- 如果需要让多的一方主动,一的一方被动
          需要配置inverse属性-控制反转,只能配置在集合中
         true - 放弃
          false - 不放弃
        由多的一方管理一的一方比较有效-->
    <set name="stuset" inverse="true">
        <key column="cid"/>
        <one-to-many class="Student"/>
    </set>
</class>

一对一(唯一外键):

<class name="Student" table="tb_student">
    <id name="sid"> <generator class="native" /> </id>
    省略。。。
    <!-- 配置many to one
        保持外键唯一性:unique="true"
     -->
    <many-to-one name="stup" cascade="save-update" class="StudentPager" column="p_id" unique="true"/>
</class>
<class name="StudentPager" table="tb_StudentPager">
    <id name="pid" column="p_id"> <generator class="native" /> </id>
    <property name="pname" />
    <one-to-one name="stu" class="Student"/>
</class>

一对一(主键关联):

<class name="Student" table="tb_student">
    <id name="sid"> <generator class="native" /> </id>
    省略。。。
    <one-to-one name="sp" class="StudentPager" constrained="true"/>

</class>
<class name="StudentPager" table="tb_StudentPager">
    <id name="pid" column="p_id"> 
        <generator class="Student">
            <param name="stu">sp</param>
    </generator>
     </id>
    <property name="pname" />
    </class>

多对多(第一种方式):
两个对象,三张表。建立中间表,存储对应关系

<class name="Student" table="tb_student">
    <id name="sid" type="integer"> <generator class="native" /> </id>
    省略。。。
    <!-- 配置many to many
        table:中间表
        key:存放Student的id,
        many-to-many:存放course对象和表中字段名
     -->
     <set name="courseset" table="tb_stu_sc">
         <key column="sid"/>
         <many-to-many class="Course" column="cid"/>
     </set>
</class>
<class name="Course" table="tb_course">
    <id name="cid" type="integer"> <generator class="native" /> </id>
    <property name="cname" />
     <set name="stuset" table="tb_stu_sc" inverse="true">
         <key column="cid"/>
         <many-to-many class="Student" column="sid"/>
     </set>
</class>

多对多(第二种方式):
三个对象,三张表。中间对象和表存储对应关系

<class name="Course" table="tb_course">
    <id name="cid" type="integer"> <generator class="native" /> </id>
    <property name="cname" />
    <set name="stucour" inverse="true">
         <key column="c_id"/>
         <one-to-many class="StudentCourse"/>
     </set>
</class>
<class name="Student" table="tb_student">
    <id name="sid" type="integer"> <generator class="native" /> </id>
    省略。。。
    <!-- 配置many to many
        table:中间表
        key:存放Student的id,
        many-to-many:存放course对象和表中字段名
     -->
     <set name="stucour" inverse="true">
         <key column="s_id"/>
         <one-to-many class="StudentCourse"/>
     </set>
</class>
<class name="StudentCourse" table="tb_studentcourse">
    <id name="scid" type="integer"> <generator class="native" /> </id>
    省略。。。
    <!-- 配置两个多对一 -->
    <many-to-one name="stu" class="Student" column="s_id"></many-to-one>
    <many-to-one name="course" class="Course" column="c_id"></many-to-one>
</class>

猜你喜欢

转载自blog.csdn.net/zhangfengbx/article/details/78240623