EJB学习日记(13)

2007年10月10日 07:01:00
实体BEAN的七种关系之---------多对多双向
Many-to-Many Bidirectional Relationship

一般来说,多对多的双向发生在双方都持有对方的很多引用,A可能持有很多个B,B也可能持有很多个A,并且A和B之间还要求能够互相查询.在现实中,我们可以用如下的例子来说明这种关系:

人和航班,一个人可以订很多次航班,可以是订了今天的,也可以订明天的,因为他工作繁忙,同样的,一个航班不可能只为一个人而开,也可以接受很多个人的预 订.并且这种查询是双向的,一个人他可以查询他订了多少个航班,一个航班也可以查询它被多少人订了,这样才好根据订的情况进行安排.

先看看代码吧.

还是老样子,Person类的代码
/*
* Person.java
*
* Created on 2007-9-15, 0:11:58
*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package lbf.entitybean.test1;

import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

/**
*
*
@author Admin
*/
@Entity
public class Person implements Serializable {

private static final long serialVersionUID = 1L ;
private Long id;
private String name;
private String sex;
private int age;
private Address address;
private List > Phone < phones;
private IDCard idCard;
private Country country;
private List > Car < cars;
private List > Flight < flights;

@ManyToMany(cascade
= CascadeType.ALL)
@JoinTable(name
= " PersonANDFlight " , joinColumns = {@JoinColumn(name = " personID " )}, inverseJoinColumns = {@JoinColumn(name = " flightID " )})
public List > Flight < getFlights() {
return flights;
}

public void setFlights(List > Flight < flights) {
this .flights = flights;
}

@OneToMany(cascade
= CascadeType.ALL, mappedBy = " person " )
public List > Car < getCars() {
return cars;
}

public void setCars(List > Car < cars) {
this .cars = cars;
}

@ManyToOne(cascade
= CascadeType.ALL)
@JoinColumn(name
= " countryID " )
public Country getCountry() {
return country;
}

public void setCountry(Country country) {
this .country = country;
}

@OneToOne(cascade
= CascadeType.ALL)
public IDCard getIdCard() {
return idCard;
}

public void setIdCard(IDCard idCard) {
this .idCard = idCard;
}

@OneToMany(cascade
= CascadeType.ALL)
@JoinColumn(name
= " personID " )
public List > Phone < getPhones() {
return phones;
}

public void setPhones(List > Phone < phones) {
this .phones = phones;
}

@OneToOne(cascade
= {CascadeType.ALL})
public Address getAddress() {
return address;
}

public void setAddress(Address address) {
this .address = address;
}

public int getAge() {
return age;
}

public void setAge( int age) {
this .age = age;
}

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;
}

public void setId(Long id) {
this .id = id;
}

@Id
@GeneratedValue(strategy
= GenerationType.AUTO)
public Long getId() {
return id;
}
}

代表航班的Flight类的代码:
/*
* Flight.java
*
* Created on 2007-9-24, 14:35:45
*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package lbf.entitybean.test1;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Temporal;

/**
*
*
@author hadeslee
*/
@Entity
public class Flight implements Serializable {
private static final long serialVersionUID = 1L ;
private Long id;

@Temporal(javax.persistence.TemporalType.TIME)
public Date getArriveTime() {
return arriveTime;
}

public void setArriveTime(Date arriveTime) {
this .arriveTime = arriveTime;
}

public String getFlightNumber() {
return flightNumber;
}

public void setFlightNumber(String flightNumber) {
this .flightNumber = flightNumber;
}

public String getFromCity() {
return fromCity;
}

public void setFromCity(String fromCity) {
this .fromCity = fromCity;
}

@Temporal(javax.persistence.TemporalType.TIME)
public Date getLeaveTime() {
return leaveTime;
}

public void setLeaveTime(Date leaveTime) {
this .leaveTime = leaveTime;
}
@ManyToMany(mappedBy
= " flights " )
public List > Person < getPersons() {
return persons;
}

public void setPersons(List > Person < persons) {
this .persons = persons;
}

public String getToCity() {
return toCity;
}

public void setToCity(String toCity) {
this .toCity = toCity;
}
private String flightNumber;
private String fromCity,toCity;
private Date leaveTime,arriveTime;
private List > Person < persons;

public void setId(Long id) {
this .id = id;
}

@Id
@GeneratedValue(strategy
= GenerationType.AUTO)
public Long getId() {
return id;
}

}

我们再来看一看ManyToMany的声明
public @ interface ManyToMany
{
Class targetEntity( )
default void . class ;
CascadeType[] cascade( )
default {};
FetchType fetch( )
default LAZY;
String mappedBy( )
default "" ;
}

从代码可以看出,注释都差不多,只不过多对多的时候,仅仅从两张用外键相连是不够的,必须生成一张用于连接的中间表.也就如下代码所声明的地方:
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "PersonANDFlight", joinColumns = {@JoinColumn(name = "personID")}, inverseJoinColumns = {@JoinColumn(name = "flightID")})
public List>Flight< getFlights() {
return flights;
}

我们声明了一张用来连接的表,并且声明了主控端的列名和反转端的列名,其实这个声明不是必要的,当我们不用@JoinTable来声明的时候,JBOSS也会为我们自动生成一个连接用的表,表名默认是主控端的表名加上下划线"_"再加上反转端的表名.

从上面的注释我们可以看出,此关系的主控端在Person这一方,因为我们可以在Flight那一方看到如下注释:
@ManyToMany(mappedBy="flights")
public List>Person< getPersons() {
return persons;
}

正是因为双向关系的存在,也由于Person是主控端, 所以Person要取消某次预定只要remove相应的Flight就可以了,而Flight由于是反转端,所以虽然它也可以得到它的所有预定的人,但是 它却无法改变这种关系,即使它remove掉了某个Person,但是这种关系并不会在数据库里面表现出来,因为毕竟航班是不能随便取消一个人的登机资格 的.

其实按我的理解来说,多对多的双向有点类似于一对多的单向,只不过双方都是一对多,我们这个例子完全可以用一对多来实现,但是一对多实现的话,就会 有很多重复的数据存在,因为每个关系都可能会有重复的元素,比如我们这个例子,如果一对多的话,每个航班都会对应几百人,哪怕这几百人下次还坐你的航班, 你还要重新定义一下.因为上次的几百人的外键已经指向你了.还要再指向另一个你,必须要重新生成几百个元素,所以在这种情况下,多对多就可以很好的重用数 据库里面的表了,在Person和Flight表中,都不会有重复的元素存在了.并且关系也明朗了许多.

来自: 千里冰封

Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=1817688


基于粒子群优化算法的p-Hub选址优化(Matlab代码实现)内容概要:本文介绍了基于粒子群优化算法(PSO)的p-Hub选址优化问题的研究与实现,重点利用Matlab进行算法编程和仿真。p-Hub选址是物流与交通网络中的关键问题,旨在通过确定最优的枢纽节点位置和非枢纽节点的分配方式,最小化网络总成本。文章详细阐述了粒子群算法的基本原理及其在解决组合优化问题中的适应性改进,结合p-Hub中转网络的特点构建数学模型,并通过Matlab代码实现算法流程,包括初始化、适应度计算、粒子更新与收敛判断等环节。同时可能涉及对算法参数设置、收敛性能及不同规模案例的仿真结果分析,以验证方法的有效性和鲁棒性。; 适合人群:具备一定Matlab编程基础和优化算法理论知识的高校研究生、科研人员及从事物流网络规划、交通系统设计等相关领域的工程技术人员。; 使用场景及目标:①解决物流、航空、通信等网络中的枢纽选址与路径优化问题;②学习并掌握粒子群算法在复杂组合优化问题中的建模与实现方法;③为相关科研项目或实际工程应用提供算法支持与代码参考。; 阅读建议:建议读者结合Matlab代码逐段理解算法实现逻辑,重点关注目标函数建模、粒子编码方式及约束处理策略,并尝试调整参数或拓展模型以加深对算法性能的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值