在关联关系映射的关系中,存在多对一,一对多,多对一或一对多双向的关系。
分别举几个实例:
一个销售人员可以有很多汽车订单,每一个汽车订单只能由一个销售人员负责。
多对一单向映射:
针对汽车订单角度的关系:
Salesman.java
package com.it.manytoone;
public class Salesman {
private int sid;
private String salesname;
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSalesname() {
return salesname;
}
public void setSalesname(String salesname) {
this.salesname = salesname;
}
}
新建实现类Carorder.java,在Carorder类中将多个对象的实现类写入。Carorder作为多个Salesman所对应的单个对象。
package com.it.manytoone;
public class Carorder {
private int cid;
private String carname;
private Salesman salesman;
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getCarname() {
return carname;
}
public void setCarname(String carname) {
this.carname = carname;
}
public Salesman getSalesman() {
return salesman;
}
public void setSalesman(Salesman salesman) {
this.salesman = salesman;
}
}
新建HibernateUtil.java,此类用于通过session工厂产生Session对象,con.configure就调用cfg文件。
package com.it.manytoone;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory factory;
static{
Configuration con=new Configuration();
con.configure();
factory=con.buildSessionFactory();
}
public static Session getSession(){
return factory.openSession();
}
}
hibernate.cfg.xml:其中调用Salesman.hbm.cml和Carorder.hbm.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">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="connection.username">scott</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="myeclipse.connection.profile">orcl</property>
<property name="connection.password">tiger</property>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver
</property>
<property name="show_sql">true</property>
<mapping resource="com/it/manytomany/Saleman.hbm.xml" />
<mapping resource="com/it/manytomany/Carorder.hbm.xml" />
</session-factory>
</hibernate-configuration>
Salesman.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.it.manytoone.Salesman" table="SALESMAN" schema="SCOTT">
<id name="sid" type="int">
<column name="SID" precision="22" scale="0" />
<generator class="assigned"></generator>
</id>
<property name="salesname" type="java.lang.String">
<column name="SALESNAME" length="20" />
</property>
</class>
</hibernate-mapping>
Carorder.hbm.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping package="com.it.manytoone">
<class name="Carorder" table="CARORDER" schema="SCOTT">
<id name="cid" type="int">
<column name="CID" precision="22" scale="0" />
<generator class="assigned" />
</id>
<property name="carname" type="java.lang.String">
<column name="CARNAME" length="20" />
</property>
<many-to-one name="salesman" column="salesid" class="Salesman" not-null="true" ></many-to-one>
</class>
</hibernate-mapping>
在单个对象中写入多对一的标签用于两种对象之间关联的映射:
<many-to-one name="salesman" column="salesid" class="Salesman" not-null="true" ></many-to-one>
manytoone.sql:
create table SALESMAN
(
SID INTEGER primary key not null,
SALESNAME VARCHAR2(20)
);
-- Create table CARORDER
create table CARORDER
(
CID INTEGER not null,
CARNAME VARCHAR2(20),
SALESID INTEGER,
foreign key (salesid) references salesman(sid)
);
create table ADDRESS
(
AID INTEGER primary key not null,
CITY VARCHAR2(20),
STREET VARCHAR2(20),
NUM INTEGER,
foreign key (aid) references salesman(sid)
);
注意关联关系,在Carorder单个对象的表中有多个对象Salesman的表。address地址中有多个Salesman对象对应的地址。
基本插入和查询方法:
public static void insert(){
Session session=HibernateUtil.getSession();
Carorder order=new Carorder();
order.setCid(1001);
order.setCarname("bsj");
Salesman sales=new Salesman();
sales.setSid(101);
sales.setSalesname("zhangsan");
order.setSalesman(sales);
session.save(sales);
session.save(order);
// session.delete(sales);
session.beginTransaction().commit();
session.close();
}
public static void query(){
Session session=HibernateUtil.getSession();
Carorder order=new Carorder();
order=(Carorder)session.get(Carorder.class, 1001);
System.out.println("---------");
System.out.println(order.getSalesman().getSalesname());
session.beginTransaction().commit();
session.close();
}
如果我们没有在测试程序里session.save(Carorder),直接执行程序,会报错,可以在<many-to-one/>中配置cascade属性:
<many-to-one name="Carorder" column="Cid" cascade="save-update"/>
在这里配cascade属性,表示两个杜希昂之间操作为联动关系。
一对多单向映射:
针对销售人员的角度:
package com.it.onetomany;
public class Carorder {
private int cid;
private String carname;
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getCarname() {
return carname;
}
public void setCarname(String carname) {
this.carname = carname;
}
}
Salesman.java:
像这种时候,我们就需要在销售人员类中添加一个对汽车订单对象的集合了。这个集合可以是set、list、map、array数组的有关容器(其中set中的对象不可重复,相对性能也比较高,建议使用set)
package com.it.onetomany;
import java.util.Set;
public class Salesman {
private int sid;
private String salesname;
private Set carorder;
public Set getCarorder() {
return carorder;
}
public void setCarorder(Set carorder) {
this.carorder = carorder;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSalesname() {
return salesname;
}
public void setSalesname(String salesname) {
this.salesname = salesname;
}
}
Salesman.hbm.xml:加入set标签
<set name="carorder" table="carorder">//
<key column="salesid"></key>//salesman中的主键加入key标签
<one-to-many class="Carorder"/>
</set>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping package="com.it.onetomany">
<class name="Salesman" table="SALESMAN" schema="SCOTT">
<id name="sid" type="int">
<column name="SID" precision="22" scale="0" />
<generator class="assigned"></generator>
</id>
<property name="salesname" type="java.lang.String">
<column name="SALESNAME" length="20" />
</property>
<set name="carorder" table="carorder">
<key column="salesid"></key>
<one-to-many class="Carorder"/>
</set>
</class>
</hibernate-mapping>
Carorder.hbm.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.it.onetomany.Carorder" table="CARORDER" schema="SCOTT">
<id name="cid" type="int">
<column name="CID" precision="22" scale="0" />
<generator class="assigned" />
</id>
<property name="carname" type="java.lang.String">
<column name="CARNAME" length="20" />
</property>
</class>
</hibernate-mapping>
insert方法和query方法:实例化多个汽车订单,实例化一个销售人员,创建一个set集合,将汽车订单加入set集合,用setCarorder将多个订单分配给销售人员,最后将所有的实例化对象插入到内置对象中。这是插入方法的构成。
public static void inset(){
Session session=HibernateUtil.getSession();
Carorder order1=new Carorder();
order1.setCid(1002);
order1.setCarname("bsj");
Carorder order2=new Carorder();
order2.setCid(1003);
order2.setCarname("hm");
Salesman sales=new Salesman();
sales.setSid(102);
sales.setSalesname("zhangsan");
Set set=new HashSet();
set.add(order1);
set.add(order2);
sales.setCarorder(set);
session.save(order1);
session.save(order2);
session.save(sales);
// session.delete(sales);
session.beginTransaction().commit();
session.close();
}
public static void query(int salesId){
Session session=HibernateUtil.getSession();
Salesman salesman=(Salesman)session.get(Salesman.class, salesId);
Set<Carorder> set=salesman.getCarorder();
for (Carorder carorder : set) {
System.out.println(carorder.getCarname());
}
查询功能可以通过销售人员的id来查询他手下的汽车订单。
关联映射还分为多对多关联映射,多对一/一对多双向关联映射。
其步骤都大同小异,需要注意的是在many to many中的配置不同,需要写在单对象中的配置文件中,用来关联多对象。