Hibernate ORM框架——续第二章:Hibernate映射关系:单向关联

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate ORM框架——续第二章:Hibernate映射关系:单向关联相关的知识,希望对你有一定的参考价值。

一:课堂笔记

**********单表映射***************
    1.只有一个实体类映射一个表
    2.有一个实体类+ 一个或者多个值类型,合在一起
    映射为一个表
    
**********多表映射***************
定义:类有多个映射为多个表

**********数据库层面,如ORM无关************** 2个表之间要建立关系?该如何做?有多少种方法 假定有2个表,分别为A,B 3种关系 a)主键关联:A表的主键对应B表的主键,(一对一的关系) 在数据库种如何建立这种关系? 假定A做为主表,在B表里面的某个字段既是主键也是外键
b)外键关联: c)连接表关联(中间表关联): 中间表关联既可以做一对一,也可以做一对多,也可以做多对多关联 但实际项目中,出现中间表关联的时候,一般就是多对多 多对多关系,在数据库层面本质上“不支持”。 一般是把多对多关系拆分为2个一对多
**********代码层面************** 类与类之间有什么关系?有纵向的继承关系 横向的“关联” 比如下面有一个关联关系 public class Person{ private Address addr } 在类层面关系是2方面 public class Address{ private Person p } 除了上面类与类之间有一对一的关系,还有一对多的关系 ************ 由于类之间有单,双向的问题,也有一对一,一对多的问题 表之间建立关系又有三种类型。 在课程中,只学: 单向关系: 一对一 一对多 多对一 双向关系: 一对一 一对多 多对一 多对多

二、多对一的关系(代码)

(1)hibernate.cfg,xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
        <property name="connection.username">myuser</property>
        <property name="connection.password">123</property>
        
        <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <!-- <property name="hbm2ddl.auto">create</property> -->
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        
        <mapping resource="entity/StudentMapping.xml"/>
        <mapping resource="entity/ClassInfoMapping.xml"/>
    </session-factory>
</hibernate-configuration>        
        

(2.1)实体1

package entity;

public class ClassInfo {
    private String cno;
    private String cname;
    
    public String getCno() {
        return cno;
    }
    public void setCno(String cno) {
        this.cno = cno;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }

}

(2.2)实体2

package entity;

public class Student {
    private String sno;
    private String sname;
    
    //单向关联:多对一
    //学生:班级=N:1-->一般在多的这边写外键
    //所以classinfo的映射文件不需要改,只需要改Student的映射文件
    private ClassInfo cinfo;
    
    
    public ClassInfo getCinfo() {
        return cinfo;
    }
    public void setCinfo(ClassInfo cinfo) {
        this.cinfo = cinfo;
    }
    
    
    public String getSno() {
        return sno;
    }
    public void setSno(String sno) {
        this.sno = sno;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    
    
}

(3.1)班级实体映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="entity">
    <class name="ClassInfo" table="classinfo">
        <id name="cno" column="cid">
            <generator class="assigned"></generator>
        </id>
        <property name="cname"></property>
    </class>
</hibernate-mapping>               
        

(3.2)学生实体映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="entity">
    <class name="Student" table="student">
        <id name="sno" column="sid">
            <generator class="assigned"></generator>
        </id>
        <property name="sname"></property>
        
        <!-- 
        单向关联:多对一
        学生:班级=N:1                一般在多的这边写外键
        所以classinfo的映射文件不需要改,只需要改Student的映射文件 
        column="rcno"的意思为:设定持久化类属性对应的表的外键
        -->
        <many-to-one name="cinfo" column="rcno"></many-to-one>
        <!-- 通过cinfo的持久化类属性的名称,系统会自动找到对应的ClassInfoMapping映射文件 -->
    </class>
</hibernate-mapping>               
        

(4)HibernateUtil工具类不变

(5)test包的Main.java

package test;


import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import entity.ClassInfo;
import entity.Student;
import util.HibernateUtil;

public class Main {

    public static void main(String[] args) {

        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session s = sf.openSession();
        Transaction tx = s.beginTransaction();

        /*先创建一个班级*/
        ClassInfo cinfo1 = new ClassInfo();
        cinfo1.setCno("1");
        cinfo1.setCname("132");
        s.save(cinfo1);
        
        
        /*创建两个学生共用132班*/
        Student stu1 = new Student();
        stu1.setSno("1");
        stu1.setSname("lss");
        stu1.setCinfo(cinfo1);
        s.save(stu1);
        
        
        Student stu2 = new Student();
        stu2.setSno("2");
        stu2.setSname("zss");
        stu2.setCinfo(s.get(ClassInfo.class, "1"));
        s.save(stu2);
        
        tx.commit();
        s.close();
        
        
        //不论是多对一的关联关系还是一对多的关联关系,所创建出来的数据库代码都是一样的
        //说明:此方法同时创建两张表
        //同时创建两张表
          /*Hibernate: 
            
            create table classinfo (
               cid varchar2(255 char) not null,
                cname varchar2(255 char),
                primary key (cid)
            )
          Hibernate: 
              
              create table student (
                 sid varchar2(255 char) not null,
                  sname varchar2(255 char),
                  rcno varchar2(255 char),
                  primary key (sid)
              )
          Hibernate: 
            
            alter table student 
               add constraint FKlj3is017vndc46gtd2cpyrk0l 
               foreign key (rcno) 
               references classinfo*/
        
    }

}

 

 

三、一对多的关系(代码)

(1)hibernate.cfg,xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
        <property name="connection.username">myuser</property>
        <property name="connection.password">123</property>
        
        <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <!-- <property name="hbm2ddl.auto">create</property> -->
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>

      <mapping resource="entity/StudentMapping.xml"/>
      <mapping resource="entity/ClassInfoMapping.xml"/>

    </session-factory>
</hibernate-configuration>        
        

(2.1)实体1

package entity;

import java.util.Set;

public class ClassInfo {
    private String cno;
    private String cname;
    //这里表明一个班级有多个学生
    //用Set集合的原因,是因为Set里面不能放重复的数据
    //现实的情况是没有2个完全一样的人(学生)
    //Set最好是用接口声明,而不要用具体的Set接口的实现类来声明
    
    //单向关联:一对多
    //班级:学生=1:N
    //所以Student的映射文件不需要改,只需要改classinfo的映射文件
    private Set<Student> sinfo;
    
    public Set<Student> getSinfo() {
        return sinfo;
    }
    public void setSinfo(Set<Student> sinfo) {
        this.sinfo = sinfo;
    }
    public String getCno() {
        return cno;
    }
    public void setCno(String cno) {
        this.cno = cno;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }

    
    
}

 

(2.2)实体2

package entity;

public class Student {
    private String sno;
    private String sname;
    
    public String getSno() {
        return sno;
    }
    public void setSno(String sno) {
        this.sno = sno;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    
    
}

 

(3.1)班级实体映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="entity">
    <class name="ClassInfo" table="classinfo">
        <id name="cno" column="cid">
            <generator class="assigned"></generator>
        </id>
        <property name="cname"></property>

      <!--
      set name="sinfo":持久化类的属性名
      key column="rsno":外键名称
      one-to-many class="Student":类名
      -->

        <set name="sinfo">
            <key column="rsno"></key>
            <one-to-many class="Student"/>
        </set>
    </class>
</hibernate-mapping>               
        

 

(3.2)学生实体映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="entity">
    <class name="Student" table="student">
        <id name="sno" column="sid">
            <generator class="assigned"></generator>
        </id>
        <property name="sname"></property>
    </class>
</hibernate-mapping>               
        

 

(4)HibernateUtil工具类不变

(5)test包的Main.java

package test;


import java.util.HashSet;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import entity.ClassInfo;
import entity.Student;
import util.HibernateUtil;

public class Main {

    public static void main(String[] args) {

        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session s = sf.openSession();
        Transaction tx = s.beginTransaction();

        ClassInfo cinfo1 = new ClassInfo();
        cinfo1.setCno("1");
        cinfo1.setCname("132");
        
        Student stu1 = new Student();
        stu1.setSno("1");
        stu1.setSname("lss");
        s.save(stu1);
        
        Student stu2 = new Student();
        stu2.setSno("2");
        stu2.setSname("zss");
        s.save(stu2);
        
        Set<Student> set = new HashSet<Student>();  
        set.add(stu1);
        set.add(stu2);
        
        cinfo1.setSinfo(set);
        
        s.save(cinfo1);
        
        tx.commit();
        s.close();
        
        
        
        
        
        
        
        
        
        //说明:此方法同时创建两张表
        //同时创建两张表
        /*Hibernate: 
            
            create table classinfo (
               cid varchar2(255 char) not null,
                cname varchar2(255 char),
                primary key (cid)
            )
        Hibernate: 
            
            create table student (
               sid varchar2(255 char) not null,
                sname varchar2(255 char),
                rsno varchar2(255 char),
                primary key (sid)
            )
        Hibernate: 
            
            alter table student 
               add constraint FK2gv2uqo8k36ytnfwv1y007t8i 
               foreign key (rsno) 
               references classinfo*/ 
        
    }

}

 

 /*以上个人整理笔记,如果有误或者有不懂的地方,欢迎评论与指出*/








以上是关于Hibernate ORM框架——续第二章:Hibernate映射关系:单向关联的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate快速上手

hibernate入门知识-01

一 Mybatis概述&与Hibernate的区别&CRUD

ORM 解决方案(JPA;Hibernate)与 JDBC

python学习之路web框架续

解释一下啥是MVC,IOC,AOP,ORM,JNDI,,Hibernate,SSO、Portal