场景
数据表已经创建没有指定主外键,逻辑上存在主外键关系,需要查询两张有关系的表数据
案列
这两个表未指定主外键,其中user表的depId为dep的主键,现在需要将姓名和部门展示。
sql实现:
select user.*,dep.* from user,dep where user.depId=dep.id;
解决办法:
创建响应的实体类,创建相应的hbm.xml文件,
public class User {
private Long id ;
private String depId;
private String name ;
private Dep dep;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDepId() {
return depId;
}
public void setDepId(String depId) {
this.depId = depId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dep getDep() {
return dep;
}
public void setDep(Dep dep) {
this.dep = dep;
}
}
package com;
public class Dep {
private Long Id;
private String name;
public Long getId() {
return Id;
}
public void setId(Long id) {
Id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在user类中,定义了Dep dep,配置hbm.xml文件可以使用hibernate tool工具自动生成
修改hbm.xml文件,主要是加入
many-to-one
关系,可以保持dep的hbm文件不变,只修改user的hbm文件
<many-to-one name="dep" class="com.Dep"
column="depId" insert="false" update="false" fetch="select" lazy="false"
not-found="ignore"></many-to-one>
即可产生关联,可观察后台,生成的sql语句
结果来看先查询了user表,然后按user表中的depI的作为条件查询了Dep表
上述常用属性介绍
name为被关联的表的实体变量名称,class为关联的全限定名的类,column为需要关联的列,即为user表的depId,
这个时候就有个疑问了,表dep没有指定哪一个字段和depId相关联,为何达到了关联的相关呢?
按照生成的sql来看,被关联的dep表的id为相关列,在hbm文件中指定为主键,这时,被找到自动关联了。
以下为网上收集来的属性,以供参考
通过many-to-one
元素,可以定义一种常见的与另一个持久化类的关联。 这种关系模型是多对一关联(实际上是一个对象引用-译注):这个表的一个外键引用目标表的 主键字段。
<many-to-one name="propertyName" column="column_name" class="ClassName" cascade="cascade_style" fetch="join|select" update="true|false" insert="true|false" property-ref="propertyNameFromAssociatedClass" access="field|property|ClassName" unique="true|false" not-null="true|false" optimistic-lock="true|false" lazy="proxy|no-proxy|false" not-found="ignore|exception" entity-name="EntityName" formula="arbitrary SQL expression" node="element-name|@attribute-name|element/@attribute|." embed-xml="true|false" index="index_name" unique_key="unique_key_id" foreign-key="foreign_key_name" />
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
cascade
属性设置为除了none
以外任何有意义的值, 它将把特定的操作传递到关联对象中。这个值就代表着Hibernate基本操作的名称, persist, merge, delete, save-update, evict, replicate, lock, refresh
, 以及特别的值delete-orphan
和all
,并且可以用逗号分隔符 来组合这些操作,例如,cascade="persist,merge,evict"
或 cascade="all,delete-orphan"
。更全面的解释请参考第 10.11 节 “传播性持久化(transitive persistence)”. 注意,单值关联 (many-to-one 和 one-to-one 关联) 不支持删除孤儿(orphan delete,删除不再被引用的值).
一个典型的简单many-to-one
定义例子:
<many-to-one name="product" class="Product" column="PRODUCT_ID"/>
property-ref
属性只应该用来对付遗留下来的数据库系统, 可能有外键指向对方关联表的是个非主键字段(但是应该是一个惟一关键字)的情况下。 这是一种十分丑陋的关系模型。比如说,假设Product
类有一个惟一的序列号, 它并不是主键。(unique
属性控制Hibernate通过SchemaExport工具进行的DDL生成。)
<property name="serialNumber" unique="true" type="string" column="SERIAL_NUMBER"/>
那么关于OrderItem
的映射可能是:
<many-to-one name="product" property-ref="serialNumber" column="PRODUCT_SERIAL_NUMBER"/>
当然,我们决不鼓励这种用法。
如果被引用的唯一主键由关联实体的多个属性组成,你应该在名称为<properties>
的元素 里面映射所有关联的属性。
假若被引用的唯一主键是组件的属性,你可以指定属性路径:
<many-to-one name="owner" property-ref="identity.ssn" column="OWNER_SSN"/>
欢迎转载,如有不当之处,敬请提出