Hibernate:组件属性和关联映射的区别

Hibernate中我们经常用到组件属性,以及关联属性(比如N-1关联),但是他们有什么区别?首先我们了解一下基本概念:

一:组件属性

组件属性的意思是:持久化类的属性并不是基本数据类型,也不是字符串、日期等标量类型的变量,而是一个复合类型的对象,在持久化过程中,它仅仅被当做值类型,而并非引用另一个持久化实体。组件属性的类型可以是任何自定义类,下面我们举个例子:

我们有个Person类,有idnameage、还有个组件属性Address address(这个类型是我们定义的)

Person.java

import javax.persistence.*;

@Entity
@Table(name="embeddable_inf")
public class Person {
	@Id
	@Column(name="person_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;
	private String name;
	private String age;
	//组件属性 Address为我们定义的类
	private Address address;
	public Person(String name, String age) {
		super();
		this.name = name;
		this.age = age;
	}
	//省略所有set、get方法


Hibernate中,Address并不是一个持久化类,它也不是Java中的8大基本数据类型,它仅仅是一个我们自定义的类然后被当做address组件属性的类型,那既然不是一个持久化类,那么Address这个类中的属性就不会单独存储在一张数据表中,而是和Person这个类一同储存在一张表中。

我们在看看我们定义的组件属性类型Addess

Address.java

import javax.persistence.*;

import org.hibernate.annotations.Parent;
//标明该类作为持久化类的组件类使用
@Embeddable
public class Address {
	@Column(name="address_order")
	private String id;
	@Column(name="address_detail")
	private String addressDetail;
	//指定含有该组件的持久化类
	@Parent
	private Person owner;
	//无参构造函数
	public Address() {
		super();
	}
	public Address(String id, String addressDetail) {
		super();
		this.id = id;
		this.addressDetail = addressDetail;
	}
	//省略所有set、get方法


    我们通过@Embeddable注解指定该类为持久化类的组件类使用,并且通过@Parent注解指定使用该组件的持久化类,可以发现,我们并没有通过@EntityAddress类指定为持久化类。

看我们的测试类 

Test.java

import org.hibernate.*;

import com.mao.n_1.HibernateUtil;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Session session=HibernateUtil.currentSession();
		Transaction tx=session.beginTransaction();
		Person person=new Person("VipMao","23");
		Address address=new Address("01","山东青岛");
		person.setAddress(address);
		session.save(person);
		tx.commit();
		HibernateUtil.closeSession();
		HibernateUtil.sessionFactory.close();
	}

}
这里的Session和Transaction都是通过HibernateUtil工具类创建的

数据库结果:

 

可以看出,组件类中的列也和持久化中的类中的列保存在同一张表中。

二:关联映射

我们再拿同一个例子来看看Hibernate中的关联映射

Person-Address 单向N-1关联来讲,多个Person关联一个Address

于是我们这样定义Person类:同样有id、name、age属性,以及和Address形成N-1关联关系

Person.java

import javax.persistence.*;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;


@Entity
@Table(name="person_inf")
public class Person {
	@Id
	@Column(name="person_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;
	private String name;
	private String age;
	@ManyToOne(targetEntity=Address.class)
	//指定外键
	@JoinColumn(name="address_id",nullable=false)
	//级联操作
	@Cascade(CascadeType.ALL)
	private Address address;
	
	public Person(String name, String age) {
		super();
		this.name = name;
		this.age = age;
	}
	//省略所有set、get方法


我们通过@ManyToOne指定Address属性,完成N-1的映射,我们再来看看,Address类的定义:

Address.java

import javax.persistence.*;

@Entity
@Table(name="address_inf")
public class Address {
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="address_id")
	private int addressId;
	@Column(name="address_detail")
	private String addressDetail;
	public Address(String addressDetail) {
		super();
		this.addressDetail = addressDetail;
	}
	//省略所有set、get方法


可以看出,PersonAddress两个类我们都通过@Entity完成了持久化,这就要求两个类的属性都保存在不同的数据表中,这是和组件属性不同的,关联操作就是一个持久化类和另一个持久化类存在某种关联关系,而组件属性则是一个类是另一个持久化类的组件属性,

我们的测试类

Test.java

import org.hibernate.*;

public class Test {
	public static void main(String[] args) {
		Session session=HibernateUtil.currentSession();
		Transaction tx=session.beginTransaction();
		Address a1=new Address("山东曲阜");
		Address a2=new Address("江西南昌");
		session.save(a1);
		session.save(a2);
		session.flush();
		Person person=new Person("VipMao","23");
		person.setAddress(a1);
		Person person2=new Person("马洪昌","23");
		person2.setAddress(a1);
		session.save(person);
		session.save(person2);
		tx.commit();
		HibernateUtil.closeSession();
		HibernateUtil.sessionFactory.close();
		
		
	
	}
}


数据库结果:

 


可以看出PersonAddress的数据分别被保存在了不同的数据表中。

总结:

Hibernate中组件属性只是持久化类引用另一个复合类型的对象(可以是我们自定义的类,像上面的Address类),组件类并不是持久化类,组件类通过@Embeddable注解,并通过@Parent注解引用该组件的持久化类,组件类数据与持久化类数据保存在同一张表中。而映射关系则是某持久化类和另一个持久化类存在某种映射关系(比如N-11-N),两个都为持久化类,数据分别保存在不同的数据表中。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值