1. 无连接表的N-1关联

对于无连接的N-1关联而言,程序只要在N的一端增加一列外键,让外键记录对象指所属的实体即可,Hibernate可使用@JoinColumn来修饰代表关联实体的属性,@JoinColumn用于映射底层的外键列。下面定义一个Person的类,Person与Address的关系就是N-1。

@Entity
@Table(name="person_inf")
public class Person
{// 标识属性@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定义该Person实体关联的Address实体@ManyToOne(targetEntity=Address.class)// 映射外键列,指定外键列的列名为address_id、不允许为空@JoinColumn(name="address_id" , nullable=false)@Cascade(CascadeType.ALL)private Address address;// id的setter和getter方法public void setId(Integer id){this.id = id;}public Integer getId(){return this.id;}// name的setter和getter方法public void setName(String name){this.name = name;}public String getName(){return this.name;}// age的setter和getter方法public void setAge(int age){this.age = age;}public int getAge(){return this.age;}// address的setter和getter方法public void setAddress(Address address){this.address = address;}public Address getAddress(){return this.address;}
}

程序无须从Address访问Person,所以Address无须增加Person属性。代码如下。

@Entity
@Table(name="address_inf")
public class Address
{// 标识属性@Id @Column(name="address_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private int addressId;// 定义地址详细信息的成员变量private String addressDetail;// 无参数的构造器public Address(){}// 初始化全部成员变量的构造器public Address(String addressDetail){this.addressDetail = addressDetail;}// addressId的setter和getter方法public void setAddressId(int addressId){this.addressId = addressId;}public int getAddressId(){return this.addressId;}// addressDetail的setter和getter方法public void setAddressDetail(String addressDetail){this.addressDetail = addressDetail;}public String getAddressDetail(){return this.addressDetail;}
}

用如下的代码来保存Person和Address实体。

private void testCascase()
{Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();// 创建一个Person对象Person p = new Person();// 创建一个瞬态的Address对象Address a = new Address("广州天河");          // ①// 设置Person的name为owen.org字符串p.setName("owen.org");p.setAge(21);// 设置Person和Address之间的关联关系p.setAddress(a);// 持久化Person对象session.persist(p);// 创建一个瞬态的Address对象Address a2 = new Address("上海虹口");         // ②// 修改持久化状态的Person对象p.setAddress(a2);                             // ③tx.commit();HibernateUtil.closeSession();
}

上面的实体类中使用了@Cascade(CascadeType.ALL)修饰代表关联实体的属性,这意味着系统先自动级联插入主表记录,也就是先持久化Address对象,再持久化Person对象。也就是说,Hibernate先执行一条insert into address…,再执行一条insert into person….语句。而对于p.setAddress(a2),系统先执行insert into address…,后执行update person….。如果没有@Cascade(CascadeType.ALL),则会报TransientObjectException异常。如下是执行结果图。

2. 有连接表的N-1关联

在有连接的情况下会生成一张中间表,这个时候我们只要修Person的实体就行了,修饰如下。

@Entity
@Table(name="person_inf")
public class Person
{// 标识属性@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定义该Person实体关联的Address实体@ManyToOne(targetEntity=Address.class)// 显式使用@JoinTable映射连接表@JoinTable(name="person_address", // 指定连接表的表名为person_address// 指定连接表中person_id外键列,参照到当前实体对应表的主键列joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id", unique=true),// 指定连接表中address_id外键列,参照到当前实体的关联实体对应表的主键列inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id"))private Address address;// id的setter和getter方法public void setId(Integer id){this.id = id;}public Integer getId(){return this.id;}// name的setter和getter方法public void setName(String name){this.name = name;}public String getName(){return this.name;}// age的setter和getter方法public void setAge(int age){this.age = age;}public int getAge(){return this.age;}// address的setter和getter方法public void setAddress(Address address){this.address = address;}public Address getAddress(){return this.address;}
}

其它的实体及执行的类如下。

 public class PersonManager
{public static void main(String[] args){PersonManager mgr = new PersonManager();mgr.testPerson();HibernateUtil.sessionFactory.close();}private void testPerson(){Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();// 创建一个Person对象Person p = new Person();// 设置Person的name为owen字符串p.setName("owen");p.setAge(21);// 创建一个瞬态的Address对象Address a = new Address("广州天河");// 设置Person和Address之间的关联关系p.setAddress(a);// 再持久化Address对象session.persist(a);// 创建一个瞬态的Address对象Address a2 = new Address("上海虹口");// 设置Person和Address之间的关联关系p.setAddress(a2);// 由于采用了连接表来维护N-1关联关系,因此不存在主从表关系,// 程序可以随意控制先持久化哪个实体。// 持久化Address对象session.persist(a2);// 持久化Person对象session.save(p);// 持久化Address对象session.save(a);tx.commit();HibernateUtil.closeSession();}
}

执行结果如下。

Hibernate的单向N-1关联(一)相关推荐

  1. hibernate单向一对多关联

    2019独角兽企业重金招聘Python工程师标准>>> 有这样一个应用场景,有一张用户表(APM_USER),一张部门表(APM_DEPT).用户和部门之间的关系是多对一(many ...

  2. jpa单向一对多关联映射

    如果在一的@OneToMany有@manyToOne则是双向一对多关联,如果在多的那面没有@manyToOne关联则是单向一对多关联 class和student是一对多的关系 表结构 student ...

  3. Hibernate 之单向多对一映射及其衍生问题

    由于在数据表之间可以通过外键进行关联,在使用Hibernate操作映射到存在关联关系的数据表的对象时,需要将对象的关联关系与数据表的外键关联进行映射. 首先建立hibernate.cfg.xml和会话 ...

  4. 06-hibernate注解-一对多单向外键关联

    一对多单向外键 1,一方持有多方的集合,一个班级有多个学生(一对多). 2,@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY ) / ...

  5. hibernate 一对多(one-to-many)双向关联

    一对多(one-to-many)双向关联实例(Department- Employee) 这里的一对多双向关联是在域模型(实体对象模型)上的概念,在关系数据库中,只存在外键参照关系,而且总是由&quo ...

  6. Hibernate学习之一对多关联

    注意事项: 1.单向一对多  只需在"一"放进行配置 2.双向一对多   需要在关联双方都加以配置,而且需要在一的一方设置inverse=true 首先是实体类: TAddress ...

  7. hibernate映射-单向n-n关联关系

    (学习记录,错误不足之处,请您耐心指正^_^) hibernate映射-多对多关联关系 n-n关联必须使用连接表才能完成, 一.代码示例: {类文件↓} Category.class 1 packag ...

  8. hibernate的一对多双向关联映射----客户和订单关系

    客户和订单关系:客户是一的一方,订单是多的一方. customer表: CREATE TABLE `customer` ( `ID` int(4) NOT NULL AUTO_INCREMENT , ...

  9. hibernate one2one 唯一外键关联(双向关联)

    hibernate的一对一唯一外键关联映射(双向关联 Person <------->IdCard) 一对一唯一外键关联采用<one - to -one>标签映射,必须指定标签 ...

  10. hibernate映射(单向双向的一对多、多对一以及一对一、多对一(转)

    多对一关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是多指向一 一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多 也就是说一对多和多对一的映射策略是一样的,只是站 ...

最新文章

  1. ROC曲线与癌症分类
  2. 计算机和打印机的耗材管理,打印设备耗材余量知多少?多种途径实时掌握
  3. CNCF宣布containerd毕业
  4. 使用Spring AOP中MethodInterceptor记录日志
  5. 【Nutch2.2.1基础教程之1】nutch相关异常
  6. linux远程连接交换机,思科:路由器、交换机 ssh远程连接
  7. Java 开源Wiki:XWiki
  8. Echarts数据可视化event图表事件的相关操作,开发全解+完美注释
  9. python下文件以及文件的常用操作-1
  10. curl语句导入到Postman
  11. java海贼王秘宝传说下载,《梦想海贼王》全套源码
  12. C#加密Excel文件
  13. 大前端学习笔记--持续随缘更新
  14. 洛谷P1010 [NOIP1998 普及组] 幂次方 C语言/C++
  15. BAT批处理批量修改文件后缀名
  16. (Android版)AR 现实增强 高通 Vuforia QCAR SDK学习笔记(一)
  17. 笔记本 android,震惊:这个秘籍可以让笔记本同时拥有(mac/win/Android)系统
  18. JAVA架构师面试分享—链家网
  19. iOS 屏幕实时共享功能实践(内附详细代码)
  20. 广州联通用户开通GPRS上网流量包月如意通上网王本地王

热门文章

  1. 3.20计算机组成原理课堂笔记
  2. 深度优先搜索与广度优先搜索———模板
  3. No orientation specified, and the default is
  4. 爬虫笔记(四)------关于BeautifulSoup4解析器与编码
  5. 3dmax9中文版注册机
  6. LINQ的ORM功能中对使用sp_executesql语句的存储过程的支持
  7. MPC模型预测控制器——数学推导
  8. 使用Python来调用电脑音响
  9. python3.8+mysql+pymysql安装
  10. NYOJ-88-汉诺塔(一)