• Hibernate实体关系映射(OneToMany、ManyToOne双边)——完整实例


    双边关系是最常见的配置。在多方有一方的引用,一方也有多方的引用。双边关系能够很方便地查询数据。看一个班级与学生的双边关系。

    班级(Clazz类)与学生(Student类):一对多关系。班级中有学生属性,学生中有班级属性,二者是双边关系。(Class是关键字,不能用)

    分析:Clazz为一方,Student为多方。Clazz中有Student集合属性,Student中也有Clazz类型属性。

    环境:MyEclipse10,新建Web Project名为hibernate

        

    1、Clazz.java

    Clazz类中有一个id主键、一个name属性、一个List<Student>集合代表该班级内的学生。班级与学生关系是一对多,这里使用@OneToMany配置,并用mappedBy属性配置与该List<Student>属性对应的是Student类中的clazz属性。具体的关联配置都在Student的clazz属性上。

    双边关系中,控制权一般交给多方,因此这里的@OneToMany没有设置数据库的外键列,而只配置了一个mappedBy属性,值为clazz,告诉hibernate,配置信息要到Student类的clazz属性中找。

    package com.hibernate.bean;
    
    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Map;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.MapKey;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;
    
    import org.hibernate.annotations.Cascade;
    import org.hibernate.annotations.CascadeType;
    
    @Entity
    @Table(name = "tb_class")
    public class Clazz {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Integer id;
    
        private String name;
    
        @OneToMany(mappedBy = "clazz")
        @Cascade(value = CascadeType.DELETE_ORPHAN)
        private List<Student> students = new ArrayList<Student>();
    
        // @OneToMany(mappedBy = "clazz")
        // @MapKey(name="name")
        // private Map<String, Student> students = new HashSet<String, Student>();
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public List<Student> getStudents() {
            return students;
        }
    
        public void setStudents(List<Student> students) {
            this.students = students;
        }
    
    }

    2、Student.java

      Student类中有一个id主键以及name姓名、sex性别两个普通属性,还有一个Clazz类型的属性clazz,代表所在的班级。该属性与Clazz中的List<Student>集合属性是对应的。从逻辑上来讲,某student的clazz属性为某clazz,该clazz的List<Student>中必定还有改student。配置了mappedBy后,hibernate能自动维护这种关系。

      Student与Clazz是多对一的关系,多对一使用@ManyToOne配置,另外用@JoinColumn配置关联的列名。这里用tb_student表的class_id列tb_class的id主键列连接。这里同时配置了级联保存类型为PERSIST,创建student时,会自动将clazz也写进数据库。

    package com.hibernate.bean;
    
    import javax.persistence.CascadeType;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    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 = "tb_student")
    public class Student {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Integer id;
    
        @ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST })
        @JoinColumn(name = "class_id")  //外键为class_id
        private Clazz clazz;
    
        private String name;
    
        private String sex;
    
        public Clazz getClazz() {
            return clazz;
        }
    
        public void setClazz(Clazz clazz) {
            this.clazz = clazz;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
    }

    3、hibernate.cfg.xml(src目录下)

    <?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="show_sql">true</property>
          <property name="format_sql">true</property>
          <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
          <property name="connection.url">jdbc:oracle:thin:@192.168.1.2:1521:orcl</property>
          <property name="connection.username">daym2</property>
          <property name="connection.password">daym2</property>
          <property name="connection.isolation">2</property>
           <property name="hbm2ddl.auto">create</property> 
           <property name="javax.persistence.validation.mode">none</property>
    
          <!-- SQL方言,这边设定的是Oracle -->
          <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
            
          <property name="current_session_context">thread</property>
          <mapping class="com.hibernate.bean.Cat" /> 
          <mapping class="com.hibernate.bean.Person" />
          <mapping class="com.hibernate.bean.Email" />
          <mapping class="com.hibernate.bean.Clazz" />
          <mapping class="com.hibernate.bean.Student" />
        </session-factory>
    </hibernate-configuration>

    4、TestClazzStudent.java

    package com.hibernate.bean;
    import java.util.List;
    
    import org.hibernate.Session;
    
    import com.hibernate.bean.Clazz;
    import com.hibernate.bean.Student;
    import com.hibernate.bean.HibernateSessionFactory;
    
    public class TestClazzStudent {
    
        @SuppressWarnings("all")
        public static void main(String[] args) throws Exception {
    
            Clazz clazz = new Clazz();
            clazz.setName("三年二班");
    
            Student student1 = new Student();
            student1.setName("周周");
            student1.setSex("");
    
            Student student2 = new Student();
            student2.setName("李四");
            student2.setSex("");
    
            Session session = HibernateSessionFactory.getSession();
            session.beginTransaction();
    
            // 保存进数据库
            session.persist(clazz);
            session.persist(student1);
            session.persist(student2);
    
            // 设置班级
            student1.setClazz(clazz);
            student2.setClazz(clazz);
            // clazz.getStudents().add(student1);
            // clazz.getStudents().add(student2);
    
            session.getTransaction().commit();
            session.close();
    
            session = HibernateSessionFactory.getSession();
            session.beginTransaction();
    
            // 查询名为“三年二班”的班级 然后输出学生
            Clazz c = (Clazz) session.createQuery(
                    " select c from Clazz c where c.name = :name ").setParameter(
                    "name", "三年二班").uniqueResult();
    
            System.out.println("三年二班 的所有学生:");
            for (Student s : c.getStudents()) {
                System.out.println("	姓名:" + s.getName() + ", 性别:" + s.getSex());
            }
    
            // 直接查询班级为“三年二班”的学生
            List<Student> students = session.createQuery(
                    " select s from Student s where s.clazz.name = :name ")
                    .setParameter("name", "三年二班").list();
    
            System.out.println("三年二班 的所有学生:");
            for (Student s : students) {
                System.out.println("	姓名:" + s.getName() + ", 性别:" + s.getSex());
            }
    
            session.getTransaction().commit();
            session.close();
    
        }
    
    }

    5、log4j.properties (src目录下)

    log4j.rootLogger=INFO,stdout
    log4j.category.org.hibernate.tool.hbn2ddl=DEBUG
    log4j.category.org.hibernate.SQL=DEBUG
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n
  • 相关阅读:
    单调队列 POJ 2823
    大组合数取mod lucas 定理
    多校4
    多校2
    2016多校1
    百度之星 初赛B续
    iot-web增加apis-namespace组件
    25.75k8s
    新项目增加gradlew
    vue图片点击放大预览v-viewer
  • 原文地址:https://www.cnblogs.com/Donnnnnn/p/6249644.html
Copyright © 2020-2023  润新知