数据库创建表时没有指定主外键,hibernate 如何 may to one的解决办法,按主键关联也是one to one的一种

场景

数据表已经创建没有指定主外键,逻辑上存在主外键关系,需要查询两张有关系的表数据

案列


这两个表未指定主外键,其中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文件

扫描二维码关注公众号,回复: 1122515 查看本文章
<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"
        
/>

 

 

name: 属性名。

 

column (可选): 外间字段名。它也可以通过嵌套的 <column>元素指定。

 

class (可选 - 默认是通过反射得到属性类型): 关联的类的名字。

 

cascade(级联) (可选): 指明哪些操作会从父对象级联到关联的对象。

 

fetch (可选 - 默认为 select): 在外连接抓取(outer-join fetching)和序列选择抓取(sequential select fetching)两者中选择其一。

 

update, insert (可选 - 默认为 true) 指定对应的字段是否包含在用于UPDATE 和/或 INSERT 的SQL语句中。如果二者都是false,则这是一个纯粹的 “外源性(derived)”关联,它的值是通过映射到同一个(或多个)字段的某些其他属性得到 或者通过trigger(触发器)、或其他程序生成。

 

property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。 如果没有指定,会使用对方关联类的主键。

 

access (可选 - 默认是 property): Hibernate用来访问属性的策略。

 

unique (可选): 使用DDL为外键字段生成一个唯一约束。此外, 这也可以用作property-ref的目标属性。这使关联同时具有 一对一的效果。

 

not-null (可选): 使用DDL为外键字段生成一个非空约束。

 

optimistic-lock (可选 - 默认为 true): 指定这个属性在做更新时是否需要获得乐观锁定(optimistic lock)。 换句话说,它决定这个属性发生脏数据时版本(version)的值是否增长。

 

lazy (可选 - 默认为 proxy): 默认情况下,单点关联是经过代理的。lazy="no-proxy"指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。 lazy="false"指定此关联总是被预先抓取。

 

not-found (可选 - 默认为 exception): 指定外键引用的数据不存在时如何处理: ignore会将行数据不存在视为一个空(null)关联。

 

entity-name (可选): 被关联的类的实体名。

 

formula (可选): SQL表达式,用于定义computed(计算出的)外键值。

cascade属性设置为除了none以外任何有意义的值, 它将把特定的操作传递到关联对象中。这个值就代表着Hibernate基本操作的名称, persist, merge, delete, save-update, evict, replicate, lock, refresh, 以及特别的值delete-orphanall,并且可以用逗号分隔符 来组合这些操作,例如,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"/>


欢迎转载,如有不当之处,敬请提出


猜你喜欢

转载自blog.csdn.net/jiangyunlovec/article/details/79668958