案例分析:班级clazz与学生student是一对多关系,反过来学生和班级是多对一关系。

hihernate一对多关联映射(双向Clazz<—–>Student)
一对多双向关联映射:
* 在”一”一端的集合上使用@OneToMany和mapperBy,在对方表中加入一个外键指向“一”一端
* 在多一端采用@ManyToOne和@JoinColumn

如果在”一“一端维护一对多关联关系,hibernate会发出多余的udpate语句,所以我们一般在多的一端来维护关联关系。

Student.java

package com.wonders.task.sample.bo;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;

@Entity 
@Table(name="Z_STUDENT") 
public class Student {
    private String id;
    private String name;
    private Clazz clazz;


    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    @Column(name = "ID")
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    @Column(name = "NAME", length = 500)
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    //在“多”的这方定义@ManytoOne,同时引入“一”那方的主键,也是“多”这方的外键。
    @ManyToOne(cascade={CascadeType.ALL})         
    @JoinColumn(name="class_id")     //student类中对应外键的属性:classid 
    public Clazz getClazz() {
        return clazz;
    }
    public void setClazz(Clazz clazz) {
        this.clazz = clazz;
    }
}

Clazz.java


package com.wonders.task.sample.bo;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;


@Entity 
@Table(name="Z_CLASS") 
public class Clazz implements java.io.Serializable{
    /** * Clazz是关系被维护方,Student是关系维护方,要把class的值通过student的setClazz()方法赋给student,最后session.save()保存的是student对象。 */
    private static final long serialVersionUID = -6224738252966513441L;
    private String id;
    private String name;
    private Set<Student> set;

    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    @Column(name = "ID")
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    @Column(name = "NAME", length = 500)
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    //在“一”这方配置@OneToMany,同时配置mapperBy指向当前(“一”)这方,也就是被维护方
    @OneToMany(cascade=CascadeType.ALL,mappedBy="clazz")        //@OneToMany(cascade=CascadeType.ALL,mappedBy="clazz",fetch=FetchType.EAGER) 关闭延迟加载。 
    public Set<Student> getSet() {
        return set;
    }
    public void setSet(Set<Student> set) {
        this.set = set;
    }   
}

Main.java


package com.wonders.task.sample.main;

import java.util.HashSet;
import java.util.Set;

import javax.annotation.Resource;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.wonders.schedule.util.SpringBeanUtil;
import com.wonders.task.sample.ITaskService;
import com.wonders.task.sample.bo.Clazz;
import com.wonders.task.sample.bo.Student;


@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
/* 功能模块入口点,beanid即数据库配置中的name */
@Service("testMain")
@Scope("prototype")
public class TestMain {
    private HibernateTemplate hibernateTemplate;

    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }

    //注入hibernateTemplate
    @Resource(name="hibernateTemplate")
    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }

    public void test(){
        Session session = this.getHibernateTemplate().getSessionFactory().getCurrentSession();
        Clazz c2 = (Clazz) session.get(Clazz.class, "8a81a97c4471c661014471c669360002");
        //Clazz c2 = (Clazz) main.getHibernateTemplate().get(Clazz.class, "8a81a97c4471c661014471c669360002");
        Hibernate.initialize(c2.getSet());

        System.out.println("11111111111111111111111");
        //session.close();
        Set<Student> sss =  c2.getSet();
        System.out.println("22222222222222222");
        for(Student s: sss){

            System.out.println(s.getName());
        }
    }

    public static void main(String[] args){
        ApplicationContext applicationContext = null; 
        String[] fileUrl = new String[]{"classpath*:applicationContext*.xml"}; 
        applicationContext = new ClassPathXmlApplicationContext(fileUrl); 

        Student s1 = new Student();
        Student s2 = new Student();
        Clazz c1 = new Clazz();
        c1.setName("1班");
        s1.setName("z1");
        s1.setClazz(c1);
        s2.setName("z2");
        s2.setClazz(c1);
        Set<Student> set = new HashSet<Student>();
        set.add(s1);set.add(s2);
        c1.setSet(set);
        TestMain main = (TestMain)SpringBeanUtil.getBean("testMain");
        //main.getHibernateTemplate().save(c1);

//      Session session = main.getHibernateTemplate().getSessionFactory().openSession();
//      Clazz c2 = (Clazz) session.get(Clazz.class, "8a81a97c4471c661014471c669360002");
//      //Clazz c2 = (Clazz) main.getHibernateTemplate().get(Clazz.class, "8a81a97c4471c661014471c669360002");
//      Hibernate.initialize(c2.getSet());
//      
//      System.out.println("11111111111111111111111");
//      session.close();
//      Set<Student> sss =  c2.getSet();
//      System.out.println("22222222222222222");
//      for(Student s: sss){
//          
//          System.out.println(s.getName());
//      }
        main.test();
        //main.getHibernateTemplate().delete(c2);
    }
}

级联保存:
方法一:自动维护两表关系,(clazz)mappedby 为被维护方,对应的student为维护方

Student s1 = new Student();
        Student s2 = new Student();
        Clazz c1 = new Clazz();
        c1.setName("1班");
        s1.setName("z1");
        s1.setClazz(c1);
        s2.setName("z2");
        s2.setClazz(c1);
        TestMain main = (TestMain)SpringBeanUtil.getBean("testMain");
        main.getHibernateTemplate().save(s1);
        main.getHibernateTemplate().save(s2);

方法2:手动维护,两方都需要set对应对方的变量

Student s1 = new Student();
        Student s2 = new Student();
        Clazz c1 = new Clazz();
        c1.setName("1班");
        s1.setName("z1");
        s1.setClazz(c1);
        s2.setName("z2");
        s2.setClazz(c1);
        Set<Student> set = new HashSet<Student>(); 
        set.add(s1);set.add(s2);
        c1.setSet(set);
        TestMain main = (TestMain)SpringBeanUtil.getBean("testMain");
        main.getHibernateTemplate().save(c1);