Hibernate学习笔记(七)

一、 多对一 ---- 单向

场景:用户和组;从用户角度来,多个用户属于一个组(多对一 关联)使用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;}
}

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

(三) xml方式:映射文件:

1、 Group实体类的映射文件:
<hibernate-mapping>
	<class name="csy.model.Group">
		<id name="id" column="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
	</class>
</hibernate-mapping>
2、 User实体类的映射文件:
<hibernate-mapping>
	<class name="csy.model.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>
3、 <many-to-one>标签:
	<many-to-one name="group" column="groupid"/>

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

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

(四) annotation

Group(一的一端)注解只需要正常的注解就可以了,因为在实体类中它是被引用的。

User(多的一端):@ManyToOne来注解多一对的关键,并且用@JoinColumn来指定外键的字段名

@Entity
public class User {
	private int id;
	private String name;
	private Group group;

	@ManyToOne
	@JoinColumn(name="groupId")
	public Group getGroup() {
		return group;
	}

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

Group group = new Group();
group.setName("csy");
session.save(group); //存储Group对象。
			
User user1 = new User();
user1.setName("zhangsan");
user1.setGroup(group);//设置用户所属的组
			
User user2 = new User();
user2.setName("lisi");
user2.setGroup(group);//设置用户所属的组
			
//开始存储
session.save(user1);//存储用户
session.save(user2);

执行后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异常因为GroupTransient状态,Objectid没有分配值。

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

以上代码操作,必须首先保存group对象,再保存user对象。我们可以利用cascade(级联)方式,不需要先保存group对象。而是直接保存user对象,这样就可以在存储user之前先把group存储了。利用cascade属性是解决TransientObjectException异常的一种手段。

(六) 重要属性-cascade(级联)

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

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

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

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

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

1、 xml
<many-to-one name="group" column="groupid" cascade="save-update"/>
2、 annotation

cascade属性:其值: CascadeType.ALL 所有

CascadeType.MERGE save + update

CascadeType.PERSIST

CascadeType.REFRESH

CascadeType.REMOVE

例如:

@ManyToMany(cascade={ CascadeType.ALL})

注意:cascade是一个数组,不要忘了花括号,并且cascade只是帮我们省了编程的麻烦而已,不要把它的作用看的太大








 



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值