当前位置:首页>开发>正文

hibernate继承映射 hibernate中继承关系映射

2023-04-09 00:18:53 互联网 未知 开发

hibernate继承映射 hibernate中继承关系映射

hibernate中继承关系映射

首先外键里主键的实体要自己手动的再后面初始化(new 主键实体())
配置里省事就在 ltmany-to-one gt和ltsetgt的属性里加上 fetch="join"
还有就是只有通过hibernate里主键查找hibernate才会自动给外键里的实体,主键里的集合赋值

hibernate关系映射和继承怎么实现?是怎么样的概念?

*1)父类和子类都有对应的表,使用定义继承关系,使用步骤如下 a.将父表和子表生成单表的基本映射 b.将子类添加extends父类 c.利用定义子类映射 从Hibernate3.0版本开始,可以将单独取出,放到一个hbm.xml中定义.格式如下 extends="父类类型" table="子类表"gt //property字段映射 *2)父类和子类使用同一张数据表 选择题: 编号,题目,难度,选项,选择答案 简答题: 编号,题目,难度,简答答案 数据表Question 编号,题目,难度,选项,选择答案,简答答案,题目类型 使用定义子类映射,具体步骤: a.修改实体类,定义成父类和子类的结构 b.在映射文件中定义映射 //定义父类中属性的映射 discriminator-value="区分值"gt //定义子类1中属性的映射 discriminator-value="区分值"gt //定义子类2中属性的映射 以上是两种继承关系映射,注意一点配置的映射,对应两张表,两张实体类,两表的id应该是一一对应的,即同一个id代表的是一个实物,还有一但定义该映射,用hibernate查询时候 即使是 from 父类,获得的结果实际也是子类的一个list集合

hibernate 实际项目中那种继承映射比较多一点呢?

哈哈,很遗憾的告诉你,
实际项目中如果使用hibernate的话 一般不使用表之间的级联关系!
一般只用单表查询,删除,修改等功能

级联关系难维护,出问题难排查,性能优化……
一般都是手动,或者逻辑控制外键,级联关系的,不要费心这个东西了。
自己写着玩是可以的。

hibernate有几种映射关系

Hibernate的关联关系映射大概有这么几种:

1、单向N-1

2、单向1-1

3、单向1-N

4、单向N-N

5、双向1-N

6、双向N-N

7、双向1-1

下面就对这七种关联关系映射进行一个简单的总结:

一、单向的多对一

看两个POJO

public class Person{

private int pid

private String name

private Address address

...//生成相应的getter、setter方法

}

----------------------------------------

public class Address{

private int id

private String detail

...//生成相应的getter、setter方法

}

这里我们需要维护的关系是多个Person可以对应同一个地址,使用单向的N-1映射我们只需要在多的一端加入一个外键指向一的一端即可

**看配置文件

ltclass name="Person"gt

ltid name="id"gt

ltgenerator class="native"/gt

lt/idgt

...//部分字段配置省略

ltmany-to-one name="address" column="addressId"/gt//关键配置

lt/classgt

这样配置以后hibernate就会帮我们在多的一端(Person)添加一个外键addressId指向一的一端

二、单向的1-1(外键关联)

可以采用ltmany-to-onegt标签,指定多的一端的unique=true,这样就限制了多的一端的多重性唯一

通过这种手段映射一对一唯一外键关联

配置文件只需要修改为:

ltmany-to-one name="address" column="addressId" unique="true"/gt

三、单向的1-N

**看代码,我们知道一个班级有多名学生,这就是一个典型的1-N关系

public class Classes {
private int id
private String name
private Set students

...//生成相应的getter、setter方法

}

---------------------------------------------------------------------------

public class Student {
private int id
private String name

..//生成相应是getter、setter方法

}

**映射原理:一对多关联映射,在多的一端添加一个外键指向一的一端,它维护的关系是一指向多

**配置文件:

ltclass name="Classes" table="t_classes"gt
ltid name="id"gt
ltgenerator class="native"/gt
lt/idgt
ltproperty name="name"/gt
ltset name="students"gt
ltkey column="classesid"/gt//在一的一端添加的外键指向多的一端(默认情况下市主键匹配)
ltone-to-many class="xxx.Student"/gt//注意它维护的是一指向多的关系
lt/setgt
lt/classgt

四、双向1-N

上面提到了单向的1-N在一的一端添加的外键指向多的一端即可,对于双向的1-N则类似于N-N,集合元素中不使用ltone-to-manygt

元素映射关联属性,而使用ltmany-to-manygt元素,但是为了保证一的一端,因此需要增加unique="true"属性

**配置,简单修改单向1-N的配置文件

ltclass name="xxx.Classes" table="t_classes"gt
ltid name="id"gt
ltgenerator class="native"/gt
lt/idgt
ltproperty name="name"/gt
ltset name="students"gt
ltkey column="classesid"/gt

ltmany-to-many class="xxx.Student" unique="true"/gt
lt/setgt
lt/classgt

五、单向多对多

**先看两个POJO

public class User {
private int id
private String name
private Set roles

..//生成相应的getter、setter方法

}

---------------------------------------------------------------------------

public class Role {
private int id
private String name

..//生成相应的getter、setter方法

}

现在需要映射这样的N-N关系,一个User可以有多个Role,而一个Role有可以被多个User所拥有

这样我们就可以将一个N-N关系拆分为两个N-1的关系

**看配置文件

ltclass name="xxx.User" table="t_user"gt
ltid name="id"gt
ltgenerator class="native"/gt
lt/idgt
ltproperty name="name"/gt
ltset name="roles" table="t_user_role"gt
ltkey column="userid"/gt
ltmany-to-many class="xxx.Role" column="roleid"/gt
lt/setgt
lt/classgt

这样我们的关系的明确了

t_user t_user_role t_role

id name lt -------userid roleid ----- gt id name

六、双向的多对多关系

双向的多对多映射需要在两边都增加集合元素,用于映射集合属性

修改上面的单向N-N映射

在Role中添加集合属性

public class Role {
private int id
private String name

privarte Set user

..//生成相应的getter、setter方法

}

修改配置文件

ltclass name="xxx.User" table="t_user"gt
ltid name="id"gt
ltgenerator class="native"/gt
lt/idgt
ltproperty name="name"/gt
ltset name="roles" table="t_user_role"gt
ltkey column="userid"/gt
ltmany-to-many class="xxx.Role" column="roleid"/gt
lt/setgt
lt/classgt

------------------------------------------------------------------------------------------------

ltclass name="xxx.Role" table="t_role"gt
ltid name="id"gt
ltgenerator class="native"/gt
lt/idgt
ltproperty name="name"/gt
ltset name="users" table="t_user_role" order-by="userid"gt
ltkey column="roleid"/gt
ltmany-to-many class="xxx.User" column="userid"/gt
lt/setgt
lt/classgt

注意点:1、双向多对多关联两边都需要指定连接表的表名和外键列的列名

2、两个集合元素Set的table值必须指定,而且需要相同

七、双向的一对一关联

双向的1-1关联有两种形式:

1、基于外键的双向1-1关联

我们可以回想一下上面提到的单向1-1映射,它是有N-1的一个特例,只需要在ltmany-to-onegt标签多的一端添加unique="true"属性就可以形成单向的1-1映射关系,那么该怎么样将这种映射改为双向的呢?

下面我们再举个例子:一个User必须要有一个唯一的identityId

首先创建两个POJO类

public class Person {

private int id
private String name
private IdentityId identityId

..//生成相应的getter、setter方法

}

public class IdentityId {
private int id
private String cardNo
private Person person

..//生成相应的getter、setter方法

}

**看配置文件

ltclass name="xxx.Person" table="t_person"gt
ltid name="id"gt
ltgenerator class="native"/gt
lt/idgt
ltproperty name="name"/gt
ltmany-to-one name="identityId" class="xxx.IdentityId" unique="true"/gt
lt/classgt

-----------------------------------------------------------------------------------

ltclass name="xxx.IdentityId" table="t_identity"gt
ltid name="id"gt
ltgenerator class="native"/gt
lt/idgt
ltproperty name="cardNo"/gt
ltone-to-one name="person" class="xxx.Person" property-ref="identityId"/gt
lt/classgt

注意:这里的property-ref属性为identity表明建立了从identity对象到person对象的关联.

因此只要调用identity持久化对象的getIdentityId()方法就可以导航到Person对象 由此可见:

Person对象和IdentityId对象之间为双向的关联关系person.getIdentityId().getPerson()

2、基于主键的1-1双向关联

上面的POJO类不需要有任何变化,我们只需要修改配置文件

ltclass name="xxx.Person" table="t_person"gt
ltid name="id" column="ID"gt
ltgenerator class="foreign"gt
ltparam name="property"gtidentityIdlt/paramgt
lt/generatorgt
lt/idgt
ltproperty name="name"/gt
ltone-to-one name="identity" clsss="xxx.IdentityId" constrained="true"/gt
lt/classgt

注意:这里的constrained="true"表明Person表的主键ID同时作为外键参考IdentityId表

--------------------------------------------------------------------------------------

ltclass name="xxx.Identity" table="t_identity"gt
ltid name="id"gt
ltgenerator class="native"/gt
lt/idgt
ltproperty name="cardNo"/gt
ltone-to-one name="person" class="xxx.Person"/gt
lt/classgt

注意:这里Person表中ID既是主键同时还作为外键参照表IdentityId,因为使用了foreign标识符生成策略Hibernate就保证了Person

对象与关联的IdentityId对象共享一个主键

综上所述,hibernate的实体映射方式很灵活,如果我们使用hibernate映射得当将可以大大简化持久层数据的访问!

Hibernate中实现继承有几种解决方法

借助于Hibernate强大的O/R Mapping能力,我们能够通过discriminator轻易地将一颗继续树映射到一个表中,通过discriminator确定具体映射的子类。

在设置@hibernate.discriminator column="type" type="integer"后,启动Hibernate报错:

Could not format discriminator value to SQL string

搜索Hibernate官方文档后发现问题,原来Hibernate默认的discriminator的type是String,当设置discriminator的type为integer后,需要为父类也设置@hibernate.class table="TABLE_NAME" discriminator-value="not null",否则,Hibernate默认的discriminator-value是完整的类名,在转换String到int时造成NumberFormatException。

最后运行XDoclet,生成hbm文件:

<?XML version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.crackj2ee.example.AbstractClass" table="TABLE_NAME" discriminator-value="not null">
<id name="id" column="id" type="Java.lang.Long" unsaved-value="null">
<generator class="increment"/>
</id>
<discriminator column="type" not-null="true" type="integer"/>
<subclass name="com.crackj2ee.example.SubClass1" discriminator-value="1">
<subclass name="com.crackj2ee.example.SubClass2" discriminator-value="2">
</class>
</hibernate-mapping>

hibernate多层继承注释

注解方式给你写个吧,xml配置方式应该也差不多。hibernate jpa。 这个分2中情况:
1. 父子类对应一张表
在父类实体的@Entity注解下添加如下的注解:
@Inheritance(Strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name=”辨别字段列名”)
@DiscriminatorValue(父类实体辨别字段列值)
在子类实体的@Entity注解下添加如下的注解:
@DiscriminatorValue(子类实体辨别字段列值)nbsp
2.父类实体和子类实体分别对应数据库中不同的表
父类@Inheritance(Strategy=InheritanceType.JOINED)
子类@PrimaryKeyJoinColumn nbsp指定跟父类关联的主键名
参考http://zhuchengzzcc.iteye.com/blog/1679496

hibernate关系映射

你没有主外键的关联怎么建立对象之间的关系呢?比如说一对多映射Person与Address,采用many-to-one来映射,当你需要通过Person找到address的时候,hibernate会通过many-to-one来加载address,即发相应的sql语句。即通过many-to-one维护对象之间的关系。

最新文章