Java学习笔记之Hibernate-用注解方式实现一对多双向关联

来源:互联网 发布:股市行情数据接口 编辑:程序博客网 时间:2024/06/16 03:07

前奏:以学生和班级为例,学生和班级是一对多的关系,所谓一对多双项,是指可以通过班级找到学生并操作学生,学生也可以反过来操作班级,本例子用注解方式实现一对多双项,采用的仍然是MySQL数据库
实体类:学生类 Student.java

package com.web0819;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.Table;@Entity@Table(name = "student")public class Student {    @Id    @Column(name = "sid")    @GeneratedValue(strategy = GenerationType.AUTO)    private int sid;    @Column(name = "name", length = 20)    private String name;    @ManyToOne(cascade={CascadeType.ALL})    @JoinColumn(name="cid")    private Classes classes;    public Classes getClasses() {        return classes;    }    public void setClasses(Classes classes) {        this.classes = classes;    }    public int getSid() {        return sid;    }    public void setSid(int sid) {        this.sid = sid;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Student() {    }    public Student(int sid, String name) {        this.sid = sid;        this.name = name;    }    @Override    public String toString() {        return "Student [sid=" + sid + ", name=" + name + "]";    }}

实体类:班级类 Classes.java

package com.web0819;import java.util.Set;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.OneToMany;import javax.persistence.Table;@Entity@Table(name = "classes")public class Classes {    @Id    @Column(name = "cid")    @GeneratedValue(strategy = GenerationType.AUTO)    private int cid;    @Column(name = "name", length = 20)    private String name;    // 指定一对多关系    @OneToMany(cascade = { CascadeType.ALL },mappedBy="classes")    private Set<Student> students;    public int getCid() {        return cid;    }    public void setCid(int cid) {        this.cid = cid;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @OneToMany(cascade = { CascadeType.ALL }, mappedBy = "classes")    public Set<Student> getStudents() {        return students;    }    public void setStudents(Set<Student> students) {        this.students = students;    }    public Classes() {    }    public Classes(int cid, String name, Set<Student> students) {        this.cid = cid;        this.name = name;        this.students = students;    }}

配置文件: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.username">root</property>    <!-- 链接数据库的密码 -->    <property name="connection.password">lixin123</property>    <!-- 链接数据库的驱动 -->    <property name="connection.driver_class">        com.mysql.jdbc.Driver    </property>    <!-- 链接数据库的url -->    <property name="connection.url">        jdbc:mysql://localhost:3306/test    </property>    <!--         方言        告诉hibernate使用什么样的数据库,hibernate就会在底层拼接什么样的sql语句    -->    <property name="dialect">        org.hibernate.dialect.MySQLDialect    </property>    <!--         根据持久化类生成表的策略        validate   通过映射文件检查持久化类与表的匹配        update   每次hibernate启动的时候,检查表是否存在,如果不存在,则创建,如果存在,则什么都不做了        create   每一次hibernate启动的时候,根据持久化类和映射文件生成表        create-drop    -->    <property name="hbm2ddl.auto">update</property>    <property name="show_sql">true</property>    <property name="format_sql">true</property>    <mapping class="com.web0819.Classes" />    <mapping class="com.web0819.Student" /></session-factory></hibernate-configuration>

测试工具类:HibernateUtils.java

package com.web0819;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;public class HibernateUtils {    private static SessionFactory sessionFactory;    private static ServiceRegistry serviceRegistry;    public static SessionFactory getSessionFactory() {        Configuration configuration = new Configuration();        configuration.configure();        serviceRegistry = new ServiceRegistryBuilder().applySettings(                configuration.getProperties()).buildServiceRegistry();        sessionFactory = configuration.buildSessionFactory(serviceRegistry);        return sessionFactory;    }}

测试类:HibernateTest.java

package com.web0819;import java.util.HashSet;import org.hibernate.Session;import org.hibernate.Transaction;import org.junit.Test;public class HibernateTest {    @Test    public void test1(){        // 测试SessionFactory 和session配置        Session s = HibernateUtils.getSessionFactory().openSession();        System.out.println(s);    }    @Test    public void test2(){        // 添加班级        Session s = HibernateUtils.getSessionFactory().openSession();        Transaction transaction = s.beginTransaction();        Classes classes = new Classes();        classes.setName("1班");        s.save(classes);        transaction.commit();        s.close();    }    @Test    public void test3(){        // 添加学生        Session s = HibernateUtils.getSessionFactory().openSession();        Transaction transaction = s.beginTransaction();        Student student =  new Student();        student.setName("小明");        s.save(student);        transaction.commit();        s.close();    }    @Test    public void test4(){        // 添加班级 建立学生和班级的关系 只保存班级        Session s = HibernateUtils.getSessionFactory().openSession();        Transaction transaction = s.beginTransaction();        // 新建班级        Classes classes = new Classes();        classes.setName("3班");        // 新建学生        Student student =  new Student();        student.setName("小花");        HashSet<Student> students = new HashSet<Student>();        students.add(student);        //建立关系        classes.setStudents(students);        student.setClasses(classes); //如果不写这句话的话 学生的外键会是null        //只保存班级        s.save(classes);        transaction.commit();    }    @Test    public void test5(){        // 添加班级 从数据库中取得学生 建立和班级的关系 保存班级        Session s = HibernateUtils.getSessionFactory().openSession();        Transaction transaction = s.beginTransaction();        // 新建班级        Classes classes = new Classes();        classes.setName("4班");        // 取得学生        Student student =  (Student) s.get(Student.class, 1);        //建立关系        HashSet<Student> students = new HashSet<Student>();        students.add(student);        classes.setStudents(students);        student.setClasses(classes);        //只保存班级        s.save(classes);        transaction.commit();    }    @Test    public void test6(){        // 添加学生 从数据库中取得班级 建立和班级的关系 更新班级        Session s = HibernateUtils.getSessionFactory().openSession();        Transaction transaction = s.beginTransaction();        // 获取班级        Classes classes =(Classes) s.get(Classes.class, 1);        // 新建学生        Student student =  new Student();        student.setName("小红");        //建立关系        student.setClasses(classes);        classes.getStudents().add(student);        //只保存班级        s.update(classes);        transaction.commit();    }    @Test    public void test7(){        //  从数据库中取得班级 和学生  改变学生的班级  只更新班级        Session s = HibernateUtils.getSessionFactory().openSession();        Transaction transaction = s.beginTransaction();        // 获取班级        Classes classes =(Classes) s.get(Classes.class, 1);        // 获取学生        Student student =  (Student) s.get(Student.class, 1);        //建立关系        student.setClasses(classes);        classes.getStudents().add(student);        //只保存班级        s.update(classes);        transaction.commit();    }    @Test    public void test8(){        //  从数据库中取得班级 清空该班所有学生        Session s = HibernateUtils.getSessionFactory().openSession();        Transaction transaction = s.beginTransaction();        // 获取班级        Classes classes =(Classes) s.get(Classes.class, 1);        //建立关系 清空学生        for (Student student : classes.getStudents()) {            student.setClasses(null);        }        //只保存班级        s.update(classes);        transaction.commit();    }    @Test    public void test9(){        //  从数据库中取得班级 删除班级和班级里的学生 只删除班级        Session s = HibernateUtils.getSessionFactory().openSession();        Transaction transaction = s.beginTransaction();        // 获取班级        Classes classes =(Classes) s.get(Classes.class, 1);        s.delete(classes);        transaction.commit();    }    @Test    public void test10(){        // 新建学生 新建班级 建立关系 只保存学生级联保存班级        Session session = HibernateUtils.getSessionFactory().openSession();        Transaction transaction = session.beginTransaction();        // 新建学生        Student student = new Student();        student.setName("a");        //新建班级        Classes classes = new Classes();        classes.setName("1班");        //建立关系        student.setClasses(classes);        session.save(student);        transaction.commit();        session.close();    }    @Test    public void test11(){        // 新建学生 获取班级 建立关系 只保存学生级联保存班级        Session session = HibernateUtils.getSessionFactory().openSession();        Transaction transaction = session.beginTransaction();        // 新建学生        Student student = new Student();        student.setName("b");        //获取班级        Classes classes =(Classes) session.get(Classes.class, 10);        //建立关系        student.setClasses(classes);        classes.getStudents().add(student);        session.save(student);        transaction.commit();        session.close();    }    @Test    public void test12(){        // 获取学生 获取班级 改变关系 只保存学生级联更新班级        Session session = HibernateUtils.getSessionFactory().openSession();        Transaction transaction = session.beginTransaction();        // 获取学生        Student student = (Student) session.get(Student.class, 10);        //获取班级        Classes classes =(Classes) session.get(Classes.class, 8);        //建立关系        student.setClasses(classes);        classes.getStudents().add(student);        session.save(student);        transaction.commit();        session.close();    }    @Test    public void test13(){        // 删除班级 级联删除学生        Session session = HibernateUtils.getSessionFactory().openSession();        Transaction transaction = session.beginTransaction();        //获取班级        Classes classes =(Classes) session.get(Classes.class, 8);        session.delete(classes);        transaction.commit();        session.close();    }}

小结:学生和班级是一对多的关系,学生是多的一方,班级是一的一方,所以在Student类中设置一个属性是Classes classes,在班级类中设置一个属性Set students,这样才能双向关联。
对于注解的配置,在Student类中的classes这没别的说的,以为是对于学生来说是多对一,所以manytoone,@JoinColumn是外键。对于Classes类,对于班级来说是一对多,所以在set集合上配置oneotomany,注意onetomany里面有个属性是mappedby,翻译为中文是由。。。映射,这个属性比较复杂
首先,mappedBy这个注解只能够用在@OntToOne,@OneToMany,@manyToMany中,不能够用在@manyToOne中;
第二,这个注解看网上的意思可以简单地理解为:这个注解用在主表的一方,就是被引用的一方;
第三,这个注解是与@JoinColumn这个注解是互斥的,因为@JoinColumn这个注解使用在拥有外键的表的一方,就是从表的一方。
第四,这个注解的属性值是:指向另外一个类中定义的一个属性,这个属性的类型是当前这个类;有点绕,有点晕,是的;就是说它的属性值指向的是:与之关联类中定义的指向本类的一个属性!