多对一关系在系统实现中很常见。典型的例子就是我们国家领导人胡锦涛要认识全国人和困难,但是我们全国人民认识他却很容易。所以我们有的时候用多对一这种关联关系是很简单的。下面我们分步来解析但向关联:
第一步:建立两个实体类分别为Department与Employee两个代码如下:
package cn.csdn.hibernater.domain;
import java.util.Set;
public class Department {
private int id;
private String name;
private Set<Employee> emps;
public Department() {
super();
}
public Set<Employee> getEmps() {
return emps;
}
public void setEmps(Set<Employee> emps) {
this.emps = emps;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "Department [id=" + id + ",name=" + name + "]";
}
}
Employee:
packagecn.csdn.hibernater.domain;
public class Employee {
private int id;
private String name;
private Department depart;
public Employee() {
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Department getDepart() {
return depart;
}
public String toString() {
return "Employee [id=" + id + ",name=" + name + ", depart=" + depart
+ "]";
}
public void setDepart(Department depart) {
this.depart = depart;
}
}
第二步:配置映射文件Department.hbm.xml与Employee.hbm.xml
代码:<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.csdn.hibernater.domain">
<class name="Department" table="department">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="emps">
<key column="depart_id"/>
<one-to-many class="Employee"/>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.csdn.hibernater.domain">
<class name="Department" table="department">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="emps">
<key column="depart_id"/>
<one-to-many class="Employee"/>
</set>
</class>
</hibernate-mapping>
对于many-to-one关联关系,我们可以采用java.util.Set(或者net.sf.hibernate.collenction.Bag)类型的Collection,表现xml映射文件中也就是<set>…</set>(或<bag>…</bag>)节点。关于Hibernate的Collection实现的,请参见Hibernate Reference。
many-to-one 节点有以下属性:
属性
描述
类型
必须
name
映射属性
Text
Y
colum
关联字段
Text
Y
Class
类名
默认为映射属性所属类型
Text
N
Insert
是否对关联字段进行insert操作
默认:true
Bool
N
cascade
操作级联(cascade)关系。可选值:
all:所有情况下均可进行级联操作。
none:所有情况下都不进行级联操作。
Save-update:在执行save-update时进行级联操作。
Delete:在执行delete时进行级联操作。
Text
N
Update
是否对关联字段进行update操作
Text
N
access
属性值的读取方式。可选项
Field、Property(默认)、ClassName
Text
N
<many-to-one>元素的属性:
<many-to-one
name="propertyName" (1)
column="column_name" (2)
class="ClassName" (3)
cascade="cascade_style" (4)
fetch="join|select" (5)
update="true|false" (6)
insert="true|false" (6)
property-ref="propertyNameFromAssociatedClass" (7)
access="field|property|ClassName" (8)
unique="true|false" (9)
not-null="true|false" (10)
optimistic-lock="true|false" (11)
lazy="proxy|no-proxy|false" (12)
not-found="ignore|exception" (13)
entity-name="EntityName" (14)
formula="arbitrary SQL expression" (15)
node="element-name|@attribute-name|element/@attribute|."
embed-xml="true|false"
index="index_name"
unique_key="unique_key_id"
foreign-key="foreign_key_name"
/>
(1)
name: 属性名。
(2)
column (可选): 外间字段名。它也可以通过嵌套的 <column>元素指定。
(3)
class (可选 - 默认是通过反射得到属性类型): 关联的类的名字。
(4)
cascade(级联) (可选): 指明哪些操作会从父对象级联到关联的对象。
(5)
fetch (可选 - 默认为 select): 在外连接抓取(outer-join fetching)和序列选择抓取(sequential select fetching)两者中选择其一。
(6)
update, insert (可选 - 默认为 true) 指定对应的字段是否包含在用于UPDATE 和/或 INSERT 的SQL语句中。如果二者都是false,则这是一个纯粹的 “外源性(derived)”关联,它的值是通过映射到同一个(或多个)字段的某些其他属性得到 或者通过trigger(触发器)、或其他程序生成。
(6)
property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。 如果没有指定,会使用对方关联类的主键。
(7)
access (可选 - 默认是 property): Hibernate用来访问属性的策略。
(8)
unique (可选): 使用DDL为外键字段生成一个唯一约束。此外, 这也可以用作property-ref的目标属性。这使关联同时具有 一对一的效果。
(9)
not-null (可选): 使用DDL为外键字段生成一个非空约束。
(10)
optimistic-lock (可选 - 默认为 true): 指定这个属性在做更新时是否需要获得乐观锁定(optimistic lock)。 换句话说,它决定这个属性发生脏数据时版本(version)的值是否增长。
(11)
lazy (可选 - 默认为 proxy): 默认情况下,单点关联是经过代理的。lazy="no-proxy"指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。 lazy="false"指定此关联总是被预先抓取。
(12)
not-found (可选 - 默认为 exception): 指定外键引用的数据不存在时如何处理: ignore会将行数据不存在视为一个空(null)关联。
(13)
entity-name (可选): 被关联的类的实体名。
(14)
formula (可选): SQL表达式,用于定义computed(计算出的)外键值。
第三步:编写代码向映射的数据库中添加并查询数据。
package cn.csdn.hibernate.test;
importorg.hibernate.Session;
importorg.hibernate.Transaction;
importcn.csdn.hibernate.utils.HibernateUtil;
importcn.csdn.hibernater.domain.Department;
importcn.csdn.hibernater.domain.Employee;
publicclass Many2one {
public static void main(String[] args) {
// TODO Auto-generated method stub
add();
query(1);
}
staticDepartment add() {
Session s = null;
Transaction tx = null;
try {
s = HibernateUtil.getSession();
tx = s.beginTransaction();
// 增加
Department dep = new Department();
dep.setName("depart one");
Employee e1 = new Employee();
e1.setName("Tom");
e1.setDepart(dep);// 对象模型:对象建立关联关系
s.save(dep);
s.save(e1);
tx.commit();
return dep;
} finally {
if (s != null)
s.close();
}
}
static Employee query(int empId) {
Session s = null;
Transaction tx = null;
try {
s = HibernateUtil.getSession();
tx = s.beginTransaction();
// 查询
Employee e = (Employee)s.get(Employee.class, empId);
System.out.println(e.getName() +e.getDepart().getName());
tx.commit();
return e;
} finally {
if (s != null)
s.close();
}
}
}