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

前奏:以学生和班级为例,学生和班级是一对多的关系,所谓一对多双项,是指可以通过班级找到学生并操作学生,学生也可以反过来操作班级,本例子用注解方式实现一对多双项,采用的仍然是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这个注解使用在拥有外键的表的一方,就是从表的一方。
第四,这个注解的属性值是:指向另外一个类中定义的一个属性,这个属性的类型是当前这个类;有点绕,有点晕,是的;就是说它的属性值指向的是:与之关联类中定义的指向本类的一个属性!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值