`
H.Z
  • 浏览: 16742 次
  • 来自: 长沙
社区版块
存档分类
最新评论

JPA实体关联(hibernate实现)

    博客分类:
  • JPA
 
阅读更多

1.一对一(OneToOne)

一对一关系映射分为单向一对一和多向一对一。在配置关系时必须确立控制方和被控制方。单向和双向的区别为看主控方和被控方两边是否都配置了@OneToOne,如果都有为双向一对一,反之为单向。

 

双向一对一关联有两条规则:
@JoinColumn必须配置在关系维护方即主控方上面;
mappedBy属性配置在被维护方的@OneToOne中,并且只能指向主控方,名称定义为主控方中包含的被控方引用名称。

 

/**
 * person属于关系维护方
 *
 */
@Entity
@Table(name="t_one_person")
public class Person {

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Integer id;
	
	@Column(length=10,nullable=false)
	private String name;
	
	/*
	 * 双向关系一对一
	 * @JoinColumn在JPA中成为连接列,目的是在Person实体表中生成一个IDCard实体
	 * 的外键关系.外键列明可以用name指定,如果不指定,默认为目标实体对象名和_ID组合.
	 * 拥有@JoinColumn的是关系维护方.
	 */
	@OneToOne(cascade=CascadeType.ALL,optional=false)
	@JoinColumn(name="idCard_id")
	private IDCard idCard;
	//省略get/set方法...
}
	

 

 

 

/**
 * 为关系被维持方
 *
 */
@Entity
@Table(name="t_one_idcard")
public class IDCard {

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Integer id;
	
	@Column(length=18,nullable=false)
	private String cadno;
	
	/*
	 * 双向关联:一对一
	 * mappedBy:反转.出现该属性的是关系被维护方,所指向的则是关系维护方.
	 */
	@OneToOne(cascade={CascadeType.PERSIST,CascadeType.REFRESH,CascadeType.MERGE},mappedBy="idCard",optional=false,fetch=FetchType.EAGER)
	private Person person;
       //省略get/set方法...
}

 

 

Junit测试:

 

public class TestJPA {

	EntityManagerFactory emf = null;

	@Before
	public void before() {
		emf = Persistence.createEntityManagerFactory("myJPA");
	}

	@Test
	public void add() {
		Person person = new Person();
		IDCard idCard = new IDCard();
		person.setName("老李");
		idCard.setCadno("111111111111111111");
		idCard.setPerson(person);
		person.setIdCard(idCard);

		EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();

		em.persist(person);
		em.getTransaction().commit();
		em.close();
	}

	/**
	 * 关闭EntityManagerFactory
	 */
	@After
	public void after() {
		if (null != emf) {
			emf.close();
		}
	}
}

 

 

2.一对多(OneToMany)

在JPA规范中:
1<--->m 多的一方位关系维护端,关系维护端负责外键记录的更新.关系被维护端是没有权利更新外键字段的.

 

/**
 *关系被维护方
 */
@Entity
@Table(name="t_order")
public class Order {

	@Id
	@Column(length=55)
	private String orderId;
	
	//总价钱
	@Column(nullable=false)
	private Float amount=0f;
	
	/*订单项.一对多
	 * CascadeType.MERGE :级联更新
	 * CascadeType.PERSIST:级联保存
	 * CascadeType.REFRESH: 级联刷新 refresh(),才会触发
	 * CascadeType.REMOVE:级联删除
	 * CascadeType.ALL:以上所有
	 * 
	 * FetchType.EAGER:立即加载 @OneToOne: 默认.
	 * FetchType.LAZY:懒加载. @OneToMany :默认.
	 * 
	 * mappedBy:关系反转.此处有orderItem关系维护端.
	 */
	@OneToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY,mappedBy="order")
	private Set<OrderItem> items=new HashSet<OrderItem>();
	//省略get/set方法...
}

 

/**
 * 
 *关系维护方
 *在JPA规范中:
 *  1<--->m 多的一方位关系维护端,关系维护端负责外键记录的更新.关系被维护端是没有权利更新外键字段的.
 */


@Entity
@Table(name="t_orderItem")
public class OrderItem {

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Integer id;
	
	@Column(length=40,nullable=false)
	private String productName;
	
	//销售价
	@Column(nullable=false)
	private Float sellPrice=0f;
	
	/*
	 * 订单.多对一
	 * optional=true :可选,对应数据库可以为null.
	 * @JoinColumn: 维护外键
	 */
	
	@ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},fetch=FetchType.EAGER,optional=false)
	@JoinColumn(name="order_id")
	private Order order;
	//省略get/set方法..
}

 

 

Junit测试:

 

public class TestJPA {

	EntityManagerFactory emf = null;

	@Before
	public void before() {
		emf = Persistence.createEntityManagerFactory("myJPA");
	}
	
	@Test
	public void add(){
		OrderItem orderItem = new OrderItem();
		orderItem.setProductName("电脑");
		orderItem.setSellPrice(5000f);
		
		
		OrderItem orderItem1 = new OrderItem();
		orderItem1.setProductName("手机");
		orderItem1.setSellPrice(3000f);
		
		
		Order order=new Order();
		//订单项关联订单
		orderItem.setOrder(order);
		orderItem1.setOrder(order);
		
		
		order.setAmount(25.0f);
		order.setOrderId(UUID.randomUUID().toString());
		
		//订单关联订单项
		order.getItems().add(orderItem);
		order.getItems().add(orderItem1);
		
		
		EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();
		em.persist(order);
		em.getTransaction().commit();
		em.close();
	}
	
	/**
	 * 关闭EntityManagerFactory
	 */
	@After
	public void after() {
		if (null != emf) {
			emf.close();
		}
	}
}

 

 

3.多对多(ManyToMany)

使用之间表,分为两个一对多

@Entity
@Table(name="t_many_student")
public class Student {

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Integer id;
	
	@Column(name="name",length=10,nullable=false)
	private String name;
	
	/* @JoinTable:中间表
	 * inverseJoinColumns:指定被维护端的外键定义,这里指向的是Teacher
	 * joinColumns:指定关系维护端的外键定义,这里指向的是student
	 */
	@ManyToMany(cascade=CascadeType.REFRESH)
	@JoinTable(name="student_teacher",inverseJoinColumns=@JoinColumn(name="teacher_ids"),joinColumns=@JoinColumn(name="student_ids"))
	private Set<Teacher> teachers=new HashSet<Teacher>();
	
	/**
	 * </pre>
	 * 添加老师和学生的关系
	 * </pre>
	 */
	public void addTeacher(Teacher teacher){
		this.teachers.add(teacher);
	}
	
	/**
	 * </pre>
	 * 解除老师和学生的关系
	 * </pre>
	 */
	public void removeTeacher(Teacher teacher){
		if(this.teachers.contains(teacher)){
			this.teachers.remove(teacher);
		}
	}
	//省略get/set方法...
}
@Entity
@Table(name="t_many_teacher")
public class Teacher {

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Integer id;
	
	@Column(name="name",length=10,nullable=false)
	private String name;
	
	@ManyToMany(cascade={CascadeType.REFRESH},fetch=FetchType.LAZY,mappedBy="teachers")
	private Set<Student> students=new HashSet<Student>();
        //省略get/set方法...

}

  Junit测试:

public class TestJPA {

	EntityManagerFactory emf = null;

	@Before
	public void before() {
		emf = Persistence.createEntityManagerFactory("myJPA");
	}
	
	/**
	 * </pre>
	 * 添加老师和学生
	 * </pre>
	 */
	
	@Test
	public void add(){
		Student student = new Student("学生");
		Teacher teacher=new Teacher("老师");
		EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();
		em.persist(teacher);
		em.persist(student);
		em.getTransaction().commit();
		em.close();
	}
	
	/**
	 * </pre>
	 * 建立老师和学生的关系
	 * </pre>
	 */
	
	@Test
	public void buildTS(){
		EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();
		Student student = em.find(Student.class, 1);
		student.addTeacher(em.getReference(Teacher.class, 1));
		em.persist(student);
		em.getTransaction().commit();
		em.close();
	}
	
	/**
	 * </pre>
	 * 解除老师和学生的关系
	 * </pre>
	 */
	
	@Test
	public void deleteTS(){
		EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();
		Student student = em.find(Student.class, 1);
		student.removeTeacher(em.getReference(Teacher.class, 1));
		em.persist(student);
		em.getTransaction().commit();
		em.close();
	}
	
	/**
	 * </pre>
	 *删除老师
	 * </pre>
	 */
	
	@Test
	public void deleteTeacher(){
		EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();
		Student student = em.find(Student.class, 1);
		Teacher teacher = em.getReference(Teacher.class, 1);
		//先解除老师和学生的关系
		student.removeTeacher(teacher);
		//然后在删除老师
		em.remove(teacher);
		em.getTransaction().commit();
		em.close();
	}
	
	/**
	 * </pre>
	 *删除学生
	 * </pre>
	 */
	
	@Test
	public void deleteStudent(){
		EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();
		Student student = em.find(Student.class, 1);
		em.remove(student);//因为student是关系维护端,有权进行中间表进行修改,不需要解除关系.
		em.getTransaction().commit();
		em.close();
	}
	
	
	/**
	 * 关闭EntityManagerFactory
	 */
	@After
	public void after() {
		if (null != emf) {
			emf.close();
		}
	}
}

 

4.复合主键

/**
 * 复合主键必须要实现Serializable,无参构造,必须重写hashCode,equals.
 * @author HH
 *
 */
@Embeddable//用于实体里面的时候,告诉JPA实现产品只使用这个复合主键类的属性
public class AirLinePK implements Serializable{

	@Column(length=3)
	private String startCity;
	
	@Column(length=3)
	private String endCity;
	
        //省略get/set方法...
        //....
       //省略重写的hashCode和equals方法...
}

 

@Entity
public class AirLine {

	@EmbeddedId//专门用于复合主键类
	private AirLinePK id;
	
	@Column(length=20)
	private String name;

        //省略get/set方法..
}

 Junit测试:

public class TestJPA {

	EntityManagerFactory emf = null;

	@Before
	public void before() {
		emf = Persistence.createEntityManagerFactory("myJPA");
	}
	
	@Test
	public void add(){
		EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();
		em.persist(new AirLine(new AirLinePK("PEK","SHA"),"北京飞上海"));
		em.getTransaction().commit();
		em.close();
	}

	/**
	 * 关闭EntityManagerFactory
	 */
	@After
	public void after() {
		if (null != emf) {
			emf.close();
		}
	}
}

 

分享到:
评论

相关推荐

    jpa之使用hibernate示例代码

    通过分析"jpa-hibernate"这个压缩包中的示例代码,你可以深入理解JPA和Hibernate是如何协同工作的,以及如何在实际项目中利用它们来实现高效的数据访问。这些示例通常包括配置文件、实体类、DAO(Data Access Object...

    JPA jar包(基于JPA的Hibernate实现)

    在提供的压缩包“JPA JAR”中,可能包含了实现JPA的Hibernate库,如hibernate-entitymanager.jar,这个jar包包含了执行JPA操作所需的类和接口。在实际项目中,将这个jar包加入到项目的类路径中,就可以使用Hibernate...

    JPA-Hibernate包

    Hibernate不仅实现了JPA规范,还额外提供了一些特性,如二级缓存、更灵活的查询选项和性能优化工具。 **JPA核心概念:** 1. **实体(Entity)**:在JPA中,实体是映射到数据库表的Java类。通过在类上添加`@Entity`...

    jpa 关联映射jpa 关联映射jpa 关联映射

    在 JPA 中,实体之间的关联关系非常重要,因为它们描述了实体如何相互作用以及如何存储这些关系。本文将深入探讨 JPA 中的一对一 (One-to-One)、一对多 (One-to-Many)、多对一 (Many-to-One) 和多对多 (Many-to-Many...

    Spring3, JPA2( Hibernate4)整合开发DWP

    在本项目中,我们主要探讨的是如何将Spring3、JPA2(Hibernate4)整合到一个Dynamic Web Project中,以实现高效、灵活的企业级数据库管理。这是一个基础的Java Web应用程序开发教程,旨在帮助开发者理解如何在...

    Spring2.5 + JPA(Hibernate)实现

    标题 "Spring2.5 + JPA(Hibernate)实现" 涉及到的是在Java开发环境中,使用Spring框架的2.5版本与Java Persistence API (JPA) 的一种集成方式,其中Hibernate作为JPA的提供商。这篇博文可能是指导开发者如何在项目中...

    jpa_hibernate项目 所有jar包

    在`jpa_hibernate_jar`这个压缩包中,包含的jar文件很可能是项目开发所需的各种依赖库,这些库可能包含了JPA和Hibernate的核心实现,以及其他辅助功能如连接池、日志系统等。 **JPA核心概念**: 1. **实体(Entity...

    JPA教程,包括TOPLink JPA,Hibernate JPA,Open Jpa,jpa批注

    - `@Entity`:标记一个Java类作为JPA实体。 - `@Table`:指定实体对应的数据库表名。 - `@Id`:标记一个字段作为主键。 - `@GeneratedValue`:用于自动生成主键值,支持多种策略如IDENTITY、SEQUENCE、TABLE等。 - `...

    Hibernate's JPA.rar

    标题"Hibernate's JPA.rar"表明这是一个关于使用Hibernate实现Java Persistence API (JPA)的压缩文件,可能包含示例代码、配置文件或者必要的库文件。Hibernate是一个流行的对象关系映射(ORM)框架,它使得Java...

    hibernate-jpa.jar

    Hibernate JPA,全称为Hibernate Java Persistence API,是Hibernate组织提供的一种基于Java平台的企业级对象关系映射(ORM)解决方案,它实现了Java Persistence API(JPA),使得Java开发者能够方便地在关系数据库...

    5.Hibernate 05 Hibernate结合JPA1

    4. **懒加载和级联操作**:JPA支持实体之间的关联关系,并能处理关联对象的懒加载和级联操作。 5. **实体状态管理**:JPA管理实体对象的状态,包括 managed、transient、persistent 和 detached 状态,帮助开发者更...

    hibernate_ jpa.jar

    Hibernate作为JPA的一个实现,极大地简化了数据库操作,使得开发者能够以面向对象的方式处理数据,而无需关注底层SQL的复杂性。本篇文章将深入探讨Hibernate JPA的核心概念、主要功能及使用方法。 一、Hibernate ...

    JPA关联关系

    在JPA中,关联关系是实现对象与数据库表之间映射的关键部分,它允许我们将数据库中的表与Java类之间的关系映射出来。本文将深入探讨JPA中的四种主要关联关系:一对一(OneToOne)、一对多(OneToMany)、多对一...

    JPA -amp Hibernate 注解

    Hibernate是JPA的一种实现,广泛应用于Java项目中,用于提供持久层服务。本文将详细介绍JPA与Hibernate中常用的注解及其使用场景。 #### 二、主要注解详解 ##### 1. @Entity - **定义**:`@Entity` 注解用来标记...

    JPA 与hibernate所需jar包

    4. **创建实体类**:实体类是与数据库表映射的Java类,通过注解(@Entity)声明为JPA实体,并可以用@Table指定对应数据库表名,用@Id标记主键。 5. **定义关系映射**:使用JPA的注解(如@ManyToOne、@OneToMany、@...

    hibernate多对一单向关联关系实现源码

    以上就是关于Hibernate中实现多对一单向关联关系的基本知识,包括如何在实体类中定义关联、如何进行数据库操作以及如何查询关联对象。这个源代码示例应该提供了更具体的实现细节,你可以通过查看和运行它来深入理解...

    hibernate-jpa-2.1-api-1.0.0.final.jar.zip

    - **实体类**: 使用@Entity注解标记Java类为JPA实体,并通过@Id注解指定主键字段。 - **持久化操作**: 通过EntityManager的persist()方法将新实体持久化,merge()方法更新已存在的实体,remove()方法删除实体,find...

    JPA学习笔记-EJB-04JPA关联映射总结

    在Hibernate中,这些关系通常通过XML配置文件来定义,而在JPA中,关联映射可以通过注解直接在实体类上完成,实现了所谓的“零配置”。 在给定的需求场景中,设计了一个简单的用户权限管理系统,其中包含三个核心...

    spring jpa操作数据库 级联数据 hibernate

    Spring JPA通过使用Hibernate或EclipseLink等JPA实现,进一步增强了其功能。 1. **Spring JPA操作数据库:** Spring JPA允许我们使用注解来定义实体类,这些类对应于数据库中的表。例如,`@Entity`表示这是一个...

Global site tag (gtag.js) - Google Analytics