008多对一 关联映射 --- many-to-one

  • 多对一 --- many-to-one
  • 一对多 --- one-to-many
  • 一对一 --- one-to-one
  • 多对多 --- many-to-many

场景:用户和组;从用户角度来,多个用户属于一个组(多对一 关联)

使用hibernate开发的思路:先建立对象模型(领域模型),把实体抽取出来。

目前两个实体:用户和组两个实体,多个用户属于一个组,那么一个用户都会对应于一个组,所以用户实体中应该有一个持有组的引用。

关联映射的本质:

将关联关系映射到数据库,所谓的关联关系是对象模型在内存中一个或多个引用。

User实体类:

public class User {

private int id;

private String name;

private Group group;

public Group getGroup() {

return group;

}

public void setGroup(Group group) {

this.group = group;

}

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;

}

}

Group实体类:

public class Group {

private int id;

private String name;

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;

}

}

实体类建立完后,开始创建映射文件,先建立简单的映射文件:

Group实体类的映射文件:

<hibernate-mapping>

<class name="com.wjt276.hibernate.Group" table="t_group">

<id name="id" column="id">

<generator class="native"/>

</id>

<property name="name"/>

</class>

</hibernate-mapping>

User实体类的映射文件:

<hibernate-mapping>

<class name="com.wjt276.hibernate.User" table="t_user">

<id name="id" column="id">

<generator class="native"/>

</id>

<property name="name"/>

<!--<many-to-one> 关联映射 多对一的关系

name:是维护的属性(User.group),这样表示在多的一端表里加入一个字段名称为group,

但group与SQL中的关键字重复,所以需要重新命名字段(column="groupid").

这样这个字段(groupid)会作为外键参照数据库中group表(t_group也叫一的一端),也就是就在多的一

端加入一个外键指向一的一端。

-->

<many-to-one name="group" column="groupid"/>

</class>

</hibernate-mapping>

※<many-to-one>标签※:

例如:<many-to-one name="group" column="groupid"/>

<many-to-one> 关联映射多对一的关系

name:是维护的属性(User.group),这样表示在多的一端表里加入一个字段名称为group,但group与SQL中的关键字重复,所以需要重新命名字段(column="groupid").这样这个字段(groupid)会作为外键参照数据库中group表(t_group也叫一的一端),也就是就在多的一端加入一个外键指向一的一端。

这样导出至数据库会生成下列语句:

alter table t_user drop foreign key FKCB63CCB695B3B5AC

drop table if exists t_group

drop table if exists t_user

create table t_group (id integer not null auto_increment, name varchar(255), primary key (id))

create table t_user (id integer not null auto_increment, name varchar(255), groupid integer, primary key (id))

alter table t_user add index FKCB63CCB695B3B5AC (groupid), add constraint FKCB63CCB695B3B5AC foreign key (groupid) references t_group (id)

多对一 存储(先存储group(对象持久化状态后,再保存user)):

session = HibernateUtils.getSession();

tx = session.beginTransaction();

Group group = new Group();

group.setName("wjt276");

session.save(group); //存储Group对象。

User user1 = new User();

user1.setName("菜10");

user1.setGroup(group);//设置用户所属的组

User user2 = new User();

user2.setName("容祖儿");

user2.setGroup(group);//设置用户所属的组

//开始存储

session.save(user1);//存储用户

session.save(user2);

tx.commit();//提交事务

执行后hibernate执行以下SQL语句:

Hibernate: insert into t_group (name) values (?)

Hibernate: insert into t_user (name, groupid) values (?, ?)

Hibernate: insert into t_user (name, groupid) values (?, ?)

注意:如果上面的session.save(group)不执行,则存储不存储不成功。则抛出TransientObjectException异常。

因为Group为Transient状,Object的id没有分配值。

结果:persistent状态的对象是不能引用Transient状态的对象

以上代码操作,必须首先保存group对象,再保存user对象。我们可以利用cascade(级联)方式,不需要先保存group对象。而是直接保存user对象,这样就可以在存储user之前先把group存储了。

利用cascade属性是解决TransientObjectException异常的一种手段。

重要属性-cascade(级联):

级联的意思是指定两个对象之间的操作联运关系,对一个 对象执行了操作之后,对其指定的级联对象也需要执行相同的操作,取值:all、none、save_update、delete

1、  all:代码在所有的情况下都执行级联操作

2、  none:在所有情况下都不执行级联操作

3、  save-update:在保存和更新的时候执行级联操作

4、  delete:在删除的时候执行级联操作。

例如:<many-to-one name="group" column="groupid" cascade="save-update"/>

多对一  加载数据

代码如下:

session = HibernateUtils.getSession();

tx = session.beginTransaction();

User user = (User)session.load(User.class, 3);

System.out.println("user.name=" + user.getName());

System.out.println("user.group.name=" + user.getGroup().getName());

//提交事务

tx.commit();

执行后向SQL发出以下语句:

Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_, user0_.groupid as groupid0_0_ from t_user user0_ where user0_.id=?

Hibernate: select group0_.id as id1_0_, group0_.name as name1_0_ from t_group group0_ where group0_.id=?

可以加载Group信息:因为采用了<many-to-one>这个标签,这个标签会在多的一端(User)加一个外键,指向一的一端(Group),也就是它维护了从多到一的这种关系,多指向一的关系。当你加载多一端的数据时,它就能把一的这一端数据加载上来。当加载User对象后hibernate会根据User对象中的groupid再来加载Group信息给User对象中的group属性

时间: 2024-08-27 06:39:51

008多对一 关联映射 --- many-to-one的相关文章

一口一口吃掉Hibernate(六)——多对多关联映射

今天来说说hibernate中的多对多关联映射,多对多关联映射涉及到单向映射和双向映射2种. 首先举个多对多关联例子:用户User和角色Role,一个用户可以属于多个角色,一个角色可以有多个用户.这就是典型的多对多关联的例子.而单向关联映射则是只能由A端去操作B端,B端不能操作A端的数据.而双向关联映射则是A,B两端都可以操作另一端的数据. 先说单向关联映射,实体类如下: <span style="font-size:18px">/** * 学生类 * @author Lo

Hibernate ManyToOne Mappings 多对一关联映射

Hibernate框架的使用步骤: 1.创建Hibernate的配置文件(hibernate.cfg.xml) 2.创建持久化类,即其实例需要保存到数据库中的类(Employee.java) 3.创建对象-关系映射文件(Employee.hbm.xml) 4.通过Hibernate API编写访问数据库的代码 例子:多个员工对应一个地址. 一.创建hibernate.cfg.xml 配置文件: 注意数据库名.用户名.密码是否填写正确. <?xml version="1.0" en

【SSH系列】Hibernate映射 -- 多对多关联映射

     映射原理 在数据库学习阶段,我们知道,如果实体和实体之间的关系是多对多,那么我们就抽出来第三张表,第一张表和第二张表的主键作为第三表的联合主键,结合我们的hibernate,多对多关联,无论是单向关联还是双向关联都是通过第三张表,将两个表中的主键放到第三张表中做一个关联,用第三张表来解决可能造成的数据冗余问题.今天这篇博文小编来简单的介绍一下hibernate中的多对多关联映射. 在某些系统中,一个用户可以有多个角色,一个角色也可以有多个用户,so,她们之间的关系就是多对多,多对多关联

【SSH进阶之路】Hibernate映射——多对多关联映射(八)

上篇博文[SSH进阶之路]Hibernate映射--一对多关联映射(七),我们介绍了一对多关联映射,它是多对多关联映射的基础. 多对多映射是现实生活中最常见的映射,也是最容易理解的映射.废话少说,直接开始. 映射原理 不论是单向关联还是双向关联都是通过第三张表,将两个表中的主键放到第三张做一个关联.用第三张表来解决可能会造成数据冗余的问题. 举例 一个用户(User)对多个角色(Role),一个角色对多个用户. 分类 单向的多对多关联映射(单向User--->Role) 对象模型 关系模型 实例

hibernate多对一关联映射

hibernate多对一关联映射: 实体类 (POJO) public class Student{ private int stuId; private String stuNum; private String stuName; private ClassRoom cr; } public class ClassRoom{ private int claId; private String claName; } 映射文件 <class name=" Student" tabl

hibernate之关于使用连接表实现多对一关联映射

[Hibernate]之关于使用连接表实现多对一关联映射 在我们项目使用中采用中间表最多的一般就是多对一,或者是多对多,当然一对一使用中间表也是可以的,但是这种几率通常少之又少!所以这里重点介绍多对一和一对多的采用中间表进行关联映射! 依然采用Group和Person来描述这个逻辑! Annotations配置 @Entity @Table(name="t_group") publicclass Group {     private Integer id;     private S

016 多对多关联映射 单向(many-to-many)

一般的设计中,多对多关联映射,需要一个中间表 Hibernate会自动生成中间表 Hibernate使用many-to-many标签来表示多对多的关联 多对多的关联映射,在实体类中,跟一对多一样,也是用集合来表示的. 实例场景: 用户与他的角色(一个用户拥有多个角色,一个角色还可以属于多个用户) Role实体类: public class Role { private int id; private String name; public int getId() { return id; } p

017 多对多关联映射 双向(many-to-many)

多对多关联映射 双向 两方都持有对象引用,修改对象模型,但数据的存储没有变化. 再修改映射文件: public class Role { private int id; private String name; private Set users;//users对象的集合 public int getUsers() { return users; } public void setUsers(int users) { this.users= users; } public int getId()

8.Hibernate的多对多关联映射

1.创建如下数据库脚本 1 --2.项目表 2 -- Create table 3 create table PROJECT 4 ( 5 PROID NUMBER(6) not null, 6 PRONAME VARCHAR2(50) 7 ) 8 tablespace USERS 9 pctfree 10 10 initrans 1 11 maxtrans 255 12 storage 13 ( 14 initial 64 15 minextents 1 16 maxextents unlimi