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映射关系:单向关联的主要内容,如果未能解决你的问题,请参考以下文章