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是如何协同工作的,以及如何在实际项目中利用它们来实现高效的数据访问。这些示例通常包括配置文件、实体类、DAO(Data Access Object...
在提供的压缩包“JPA JAR”中,可能包含了实现JPA的Hibernate库,如hibernate-entitymanager.jar,这个jar包包含了执行JPA操作所需的类和接口。在实际项目中,将这个jar包加入到项目的类路径中,就可以使用Hibernate...
Hibernate不仅实现了JPA规范,还额外提供了一些特性,如二级缓存、更灵活的查询选项和性能优化工具。 **JPA核心概念:** 1. **实体(Entity)**:在JPA中,实体是映射到数据库表的Java类。通过在类上添加`@Entity`...
在 JPA 中,实体之间的关联关系非常重要,因为它们描述了实体如何相互作用以及如何存储这些关系。本文将深入探讨 JPA 中的一对一 (One-to-One)、一对多 (One-to-Many)、多对一 (Many-to-One) 和多对多 (Many-to-Many...
在本项目中,我们主要探讨的是如何将Spring3、JPA2(Hibernate4)整合到一个Dynamic Web Project中,以实现高效、灵活的企业级数据库管理。这是一个基础的Java Web应用程序开发教程,旨在帮助开发者理解如何在...
标题 "Spring2.5 + JPA(Hibernate)实现" 涉及到的是在Java开发环境中,使用Spring框架的2.5版本与Java Persistence API (JPA) 的一种集成方式,其中Hibernate作为JPA的提供商。这篇博文可能是指导开发者如何在项目中...
在`jpa_hibernate_jar`这个压缩包中,包含的jar文件很可能是项目开发所需的各种依赖库,这些库可能包含了JPA和Hibernate的核心实现,以及其他辅助功能如连接池、日志系统等。 **JPA核心概念**: 1. **实体(Entity...
- `@Entity`:标记一个Java类作为JPA实体。 - `@Table`:指定实体对应的数据库表名。 - `@Id`:标记一个字段作为主键。 - `@GeneratedValue`:用于自动生成主键值,支持多种策略如IDENTITY、SEQUENCE、TABLE等。 - `...
标题"Hibernate's JPA.rar"表明这是一个关于使用Hibernate实现Java Persistence API (JPA)的压缩文件,可能包含示例代码、配置文件或者必要的库文件。Hibernate是一个流行的对象关系映射(ORM)框架,它使得Java...
Hibernate JPA,全称为Hibernate Java Persistence API,是Hibernate组织提供的一种基于Java平台的企业级对象关系映射(ORM)解决方案,它实现了Java Persistence API(JPA),使得Java开发者能够方便地在关系数据库...
4. **懒加载和级联操作**:JPA支持实体之间的关联关系,并能处理关联对象的懒加载和级联操作。 5. **实体状态管理**:JPA管理实体对象的状态,包括 managed、transient、persistent 和 detached 状态,帮助开发者更...
Hibernate作为JPA的一个实现,极大地简化了数据库操作,使得开发者能够以面向对象的方式处理数据,而无需关注底层SQL的复杂性。本篇文章将深入探讨Hibernate JPA的核心概念、主要功能及使用方法。 一、Hibernate ...
在JPA中,关联关系是实现对象与数据库表之间映射的关键部分,它允许我们将数据库中的表与Java类之间的关系映射出来。本文将深入探讨JPA中的四种主要关联关系:一对一(OneToOne)、一对多(OneToMany)、多对一...
Hibernate是JPA的一种实现,广泛应用于Java项目中,用于提供持久层服务。本文将详细介绍JPA与Hibernate中常用的注解及其使用场景。 #### 二、主要注解详解 ##### 1. @Entity - **定义**:`@Entity` 注解用来标记...
4. **创建实体类**:实体类是与数据库表映射的Java类,通过注解(@Entity)声明为JPA实体,并可以用@Table指定对应数据库表名,用@Id标记主键。 5. **定义关系映射**:使用JPA的注解(如@ManyToOne、@OneToMany、@...
以上就是关于Hibernate中实现多对一单向关联关系的基本知识,包括如何在实体类中定义关联、如何进行数据库操作以及如何查询关联对象。这个源代码示例应该提供了更具体的实现细节,你可以通过查看和运行它来深入理解...
- **实体类**: 使用@Entity注解标记Java类为JPA实体,并通过@Id注解指定主键字段。 - **持久化操作**: 通过EntityManager的persist()方法将新实体持久化,merge()方法更新已存在的实体,remove()方法删除实体,find...
在Hibernate中,这些关系通常通过XML配置文件来定义,而在JPA中,关联映射可以通过注解直接在实体类上完成,实现了所谓的“零配置”。 在给定的需求场景中,设计了一个简单的用户权限管理系统,其中包含三个核心...
Spring JPA通过使用Hibernate或EclipseLink等JPA实现,进一步增强了其功能。 1. **Spring JPA操作数据库:** Spring JPA允许我们使用注解来定义实体类,这些类对应于数据库中的表。例如,`@Entity`表示这是一个...