(9)ManyToMany-CRUD

老师与学生是多对多的关系,一个老师可以教多个学生,一个学生也可以被多个老师教
student类

@Entity
public class student {

    private int id;
    private String name;
    private Set<teacher> ts=new HashSet<teacher>();

    @Id
    @GeneratedValue
    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;
    }
    @ManyToMany(cascade={CascadeType.ALL})
    public Set<teacher> getTs() {
        return ts;
    }
    public void setTs(Set<teacher> ts) {
        this.ts = ts;
    }   
}

Teacher类

/*
 * 单向:老师知道教的学生集合,但是学生不知道被哪个老师教
 */
@Entity 

public class teacher {

    private int id;
    private String name;
    private Set<student> s=new HashSet<student>();

    @Id //必须加在getId上面
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    @ManyToMany(mappedBy="ts",cascade={CascadeType.ALL})

    //定义中间表的名称,列名:joinColumns,inverseJoinColumns是预防组合主键的时候。
    public Set<student> getS() {
        return s;
    }
    public void setS(Set<student> s) {
        this.s = s;
    }   
}

Test:

@Test
    public void StudentSave() {
        student s1=new student();
        s1.setName("s1");

        student s2=new student();
        s2.setName("s2");

        teacher t1=new teacher();
        t1.setName("t1");

        t1.getS().add(s1);
        t1.getS().add(s2);
        s1.getTs().add(t1);
        s2.getTs().add(t1);



        Session session=sf.getCurrentSession();
        session.beginTransaction();
        //保存教师t1或者学生s1、s2均可。
        //session.save(t1);
        session.save(s1);
        session.save(s2);
        session.getTransaction().commit();

    }

    @Test
    public void StudentRead() {


        StudentSave();
        Session session=sf.getCurrentSession();
        session.beginTransaction();
        student s=(student) session.get(student.class, 1);//在多对多中,因为都会有多端的,所以读取时默认是lazy
        System.out.println("此学生被几个老师教?"+s.getTs().size());//当查询与teacher有关时,才会发与老师有关的select语句

        session.getTransaction().commit();
    }
    //多对多,则从哪一端读都是一样的。
    @Test
    public void StudentUpdate() {


        StudentSave();
        Session session=sf.getCurrentSession();
        session.beginTransaction();
        student s=(student) session.get(student.class, 1);
        s.setName("ss1");
        //当没有下面的有关teacher语句时,不会发与teacher有关的语句
        Iterator it=s.getTs().iterator();
        while(it.hasNext()){
            teacher t=(teacher) it.next();
            t.setName("tt1");
        }

        session.getTransaction().commit();
    }

    @Test
    public void StudentDelete() {


        StudentSave();
        Session session=sf.getCurrentSession();
        session.beginTransaction();
        student s=(student) session.get(student.class, 1);//在级联操作中。若只删除1号学生,则要先断与teacher的级联操作关系
        //s.getTs().clear();//虽然断了与teacher的关系,但是student与t_s还有关系,所以也会删除它
        session.delete(s);

        session.getTransaction().commit();
    }

    @Test
    public void StudentDelete2() {


        StudentSave();
        Session session=sf.getCurrentSession();
        session.beginTransaction();
        session.createQuery("delete student s where s.id=1").executeUpdate();
        session.getTransaction().commit();
    }

同onetomany一样,在删除时,在有级联的情况下,要用HQL语句。此时它与HQL查询语句不同,要+.executeUpdate()。这样就不会影响到其他的表了,即使别的表与此表有关系,比如主外键的关系,也不会影响到其他表,无论有无级联操作。

posted @ 2017-11-13 16:45  测试开发分享站  阅读(131)  评论(0编辑  收藏  举报