20.从数据库表设计到POJO配置

现在演示“多:多,双向导航”。由于实际项目中,首先进行数据库设计,所以,从数据库设计推出POJO的设计是很必要的.

student<->teacher

数据库表:

many2many

设计思路:

1.2个POJO类,Teacher对应于t_teacher表。Student对应于t_student表。

2.确定导航要求,为双向导航,使用ManyToMany,一端使用mappedBy。2端都是用cascadeType.ALL

3.POJO类的隐式字段自动映射成表中同名字段,所以,方便起见,类的属性与表中普通字段名完全一致

4.在getId上设置@Id,@GeneratedValue

5.在一端使用了ManyToMany的后面设置@JoinTable“外键表”的名字,字段名

POJO类

Student类:

@Entity
@Table(name="t_student")//设置映射的表名
public class Student {
    private int id;
    private String name;//隐式映射为同名字段
    private Set<Teacher> teachers = new HashSet<Teacher>();
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)//自增
    public int getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    @ManyToMany(cascade={CascadeType.ALL})//增删改级联
    @JoinTable(name = "t_student_teacher", joinColumns = { @JoinColumn(name = "student_id") }, inverseJoinColumns = { @JoinColumn(name = "teacher_id") })//映射的连接表名和字段名
    public Set<Teacher> getTeachers() {
        return teachers;
    }
    public void setId(int id) {
        this.id = id;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setTeachers(Set<Teacher> teachers) {
        this.teachers = teachers;
    }
}

Teacher类:

@Entity
@Table(name="t_teacher")//映射的表名
public class Teacher {
    private int id;
    private String name;//隐式映射同名字段名
    private Set<Student> students = new HashSet<Student>();
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)//自增
    public int getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    @ManyToMany(mappedBy="teachers",cascade={CascadeType.ALL})//mappedBy防止冗余。增删改级联
    public Set<Student> getStudents() {
        return students;
    }
    public void setId(int id) {
        this.id = id;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
    
}

测试

save:

Student s1 = new Student();
        s1.setName("s1");
        Student s2 = new Student();
        s2.setName("s2");
        Teacher t1 = new Teacher();
        t1.setName("t1");
        Teacher t2 = new Teacher();
        t2.setName("t2");

        s1.getTeachers().add(t1);
        s1.getTeachers().add(t2);// save s1的时候可以save t1,t2

        s2.getTeachers().add(t1);
        s2.getTeachers().add(t2);// t1,t2被保存过,hibernate会忽略这次保存,但是会插入到“连接表”中

        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        session.save(s1);// 插入s1,既可以插入t1和t2
        session.save(s2);// 插入s2,最后向中间表插入4条记录
        session.getTransaction().commit();

删除

@Test
    public void testDel() {
        // 删除s1,以及“连接表"中拥有s1的记录
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Student s1 = (Student) session.load(Student.class, 10);// load一下
         s1.setTeachers(null);//将关联打破,不去级联删除Teacher中的记录。
        session.delete(s1);
        session.getTransaction().commit();

    }

修改

@Test
    public void testUpadte() {
        // 让连接表中,12只有11号一个老师教
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Student s1 = (Student) session.load(Student.class, 12);// load一下
         Teacher t2 = (Teacher)session.load(Teacher.class, 11);
         s1.getTeachers().clear();
         s1.getTeachers().add(t2);
        session.getTransaction().commit();

    }

查询
@Test
    public void testRead() {
        //读出学生,以及教他的所有老师
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Student s1 = (Student) session.load(Student.class, 12);// load一下
         Set<Teacher> teachers = s1.getTeachers();
         System.out.println("学生姓名:"+s1.getName());
         for(Teacher t:teachers){
             System.out.println("老师姓名:"+t.getName());
         }
         
        session.getTransaction().commit();

    }

posted @ 2013-10-20 14:13  FishBird  阅读(492)  评论(0编辑  收藏  举报