双向多对多映射(参考张龙老师的)

本文介绍Hibernate框架中多对多关系的实现方法,包括Student与Course类的设计、XML映射文件详解及数据库配置,并提供创建表和测试用例的示例代码。

1.学生类文件:Student.java:

package org.yang.hibernate.model;

import java.util.Set;

public class Student
{
    private String id;
    private String name;
 
   private Set<Course> courses;
    
    public Student() {}

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Set<Course> getCourses() {
        return courses;
    }

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

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

    public void setCourses(Set<Course> courses) {
        this.courses = courses;
    }
}

2.课程类文件:Course.java

package org.yang.hibernate.model;

import java.util.Set;

public class Course
{
    private String id;
    private String name;
  
 private Set<Student> students;
    
    public Course() {}

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Set<Student> getStudents() {
        return students;
    }

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

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

    public void setStudents(Set<Student> students) {
        this.students = students;
    }
    
}

3.Student.hbm.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <class name="org.yang.hibernate.model.Student" table="student">
        <id name="id" column="id" type="string">
            <generator class="uuid"></generator>
        </id>
        <property name="name" column="name" type="string"></property>
        
      
 <!-- <set>标签中的table表示连接表的名字 -->
        <!-- cascade注意不要写为all,因为它是多对多的关系删除一方并不代表另一方也要删除,因为还有可能有其他与要删除的一方关联 -->
        <!-- inverse为true表示类Course不维护关联表,而是由对方(Student)来维护 -->
        <set name="courses" table="student_course" cascade="save-update" inverse="true">
            <!-- student_id为连接表中的复合主键(与course_id组合而成),同时又是参照student主键id的外键 -->
            <!-- 即参照表student外键的名字 -->
            <key column="student_id"></key>
            
            <!-- column中的course_id表示在连接表中的字段的名字,它是与student_id组合成复合主键,同时这个值又是参考Course的id的 -->
            <!-- 即被关联的类的名字,表明集合中存放的全部是该类的对象 -->
            <!-- column表示参照course表的外键名字 -->
            <many-to-many class="org.yang.hibernate.model.Course" column="course_id"></many-to-many>
        </set>

        
    </class>
</hibernate-mapping>

4. Course.hbm.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <class name="org.yang.hibernate.model.Course" table="course">
        <id name="id" column="id" type="string">
            <generator class="uuid"></generator>
        </id>
        <property name="name" column="name" type="string"></property>
        
        <!-- table表示连接表的名字 -->
        <!-- cascade注意不要写为all,因为它是多对多的关系删除一方并不代表另一方也要删除,因为还有可能有其他与要删除的一方关联 -->
        <!-- inverse为false表示由(students)来维护关联表 -->
        <set name="students" table="student_course" cascade="save-update" inverse="false">
            <!-- column=course_id表示参照course表的外键名字,即参照当前<class>标签中的<table>属性值表的外键 -->
            <key column="course_id"></key>
            
            <!-- column表示Student在连接表中的外键 -->
            <!-- column=student_id表示参照student表的外键的名字 -->
            <many-to-many class="org.yang.hibernate.model.Student" column="student_id"></many-to-many>
        </set>
  
     
    </class>
</hibernate-mapping>



5.主配置文件:hibernate.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >
<hibernate-configuration>
  <session-factory>
        <property name="connection.driver_class">org.postgresql.Driver</property>
        <property name="connection.url">jdbc:postgresql://localhost:5432/hibernate</property>
        <property name="hibernate.connection.username">postgres</property>
        <property name="hibernate.connection.password">yang</property>
        <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
        <property name="current_session_context_class">thread</property>
        <property name="show_sql">true</property>
        <!--
        <property name="format_sql">true</property>
         -->
        <mapping resource="Course.hbm.xml"/>
        <mapping resource="Student.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

6.生成数据库表的文件:CreateTable.java

package org.yang.hibernate;

import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

public class CreateTable
{
    public static void main(String[] args)
    {
        SchemaExport export = new SchemaExport(new Configuration().configure());
        export.create(true, true);
    }
}


7 测试文件:

package org.yang.hibernate;

import java.util.Iterator;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.yang.hibernate.model.Course;
import org.yang.hibernate.model.Student;

public class HibernateTest
{
    private static final SessionFactory sessionFactory;
    static {
        try
        {
            sessionFactory = new Configuration().configure().buildSessionFactory();
        }
        catch(Throwable ex)
        {
            System.err.println("Initial SessionFactory failed " + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
    
    public static void main(String[] args)
    {
        /*
        Student student = new Student();
        student.setName("yangzhiyong1");
        
        Course course = new Course();
        course.setName("Math1");
        
        student.setCourses(new HashSet<Course>());
        course.setStudents(new HashSet<Student>());
        
        student.getCourses().add(course);
        //course.getStudents().add(student);
        
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try
        {
            tx = session.beginTransaction();
            session.save(student);
            tx.commit();
        }
        catch (Exception e)
        {
            if (null != tx)
            {
                tx.rollback();
            }
            e.printStackTrace();
        }
        finally
        {
            session.close();
        }
        */
        
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        Student student = null;
        try
        {
            tx = session.beginTransaction();
            student = (Student)session.get(Student.class, "ff80818133d5c7450133d5c747050000");
            Set<Course> courses = student.getCourses();
            for (Iterator<Course> iterator = courses.iterator(); iterator.hasNext(); )
            {
                System.out.println(iterator.next().getName());
            }
            tx.commit();
        }
        catch (Exception e)
        {
            if (null != tx)
            {
                tx.rollback();
            }
            e.printStackTrace();
        }
        finally
        {
            session.close();
        }
        
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值