分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

Hibernate映射

发布时间:2023-09-06 01:30责任编辑:白小东关键词:Hibernate

数据库表中存在的关系在hibernate为各实体之间的关系。

实体之间有三种关系:

  一对多:一个用户,生成多个订单,每一个订单只能属于一个用户

    建表原则:在多的一方创建一个字段,作为外键,指向一的一方的主键.

  多对多:一个学生可以选择多门课程,一个课程可以被多个学生选择.

    建表原则:创建第三张表,中间表至少有两个字段,分别作为外键指向多对多双方主键.

  一对一(特殊.最少):一个公司只能有一个注册地址,一个注册地址,只能被一个公司使用.(否则将两个表建到一个表.)

   建表原则:

    唯一外键:一对一的双方,假设一方是多的关系.需要在多的一方创建一个字段,作为外键.指向一的一方的主键.但是在外键添加一个unique.

    主键对应: 一对一的双方,通过主键进行关联.

Hibernate中一对多的配置:

第一步:创建两个实体:

客户实体:

 1 public class Customer { 2 ????private Integer cid; 3 ????private String cname; 4 ????// 一个客户有多个订单. 5 ????private Set<Order> orders = new HashSet<Order>(); 6 ????public Integer getCid() { 7 ????????return cid; 8 ????} 9 ????public void setCid(Integer cid) {10 ????????this.cid = cid;11 ????}12 ????public String getCname() {13 ????????return cname;14 ????}15 ????public void setCname(String cname) {16 ????????this.cname = cname;17 ????}18 ????public Set<Order> getOrders() {19 ????????return orders;20 ????}21 ????public void setOrders(Set<Order> orders) {22 ????????this.orders = orders;23 ????}24 ????25 }

订单实体:

 1 public class Order { 2 ????private Integer oid; 3 ????private String addr; 4 ????// 订单属于某一个客户.放置一个客户的对象. 5 ????private Customer customer; 6 ????public Integer getOid() { 7 ????????return oid; 8 ????} 9 ????public void setOid(Integer oid) {10 ????????this.oid = oid;11 ????}12 ????public String getAddr() {13 ????????return addr;14 ????}15 ????public void setAddr(String addr) {16 ????????this.addr = addr;17 ????}18 ????public Customer getCustomer() {19 ????????return customer;20 ????}21 ????public void setCustomer(Customer customer) {22 ????????this.customer = customer;23 ????}24 ????25 }

第二步:建立映射:

Customer.hbm.xml

 1 <hibernate-mapping> 2 ????<class name="cn.itcast.hibernate3.demo2.Customer" table="customer"> 3 ????????<!-- 配置唯一标识 --> 4 ????????<id name="cid" column="cid"> 5 ????????????<generator class="native"/> 6 ????????</id> 7 ????????<!-- 配置普通属性 --> 8 ????????<property name="cname" column="cname" length="20"/> 9 ????????10 ????????<!-- 建立映射 -->11 ????????<!-- 配置一个集合 <set>的name Customer对象中的关联对象的属性名称. -->12 ????????<set name="orders">13 ????????????<!-- <key>标签中column:用来描述一对多多的一方的外键的名称. -->14 ????????????<key column="cno"></key>15 ????????????<!-- 配置一个<one-to-many>标签中class属性:订单的类的全路径 -->16 ????????????<one-to-many class="cn.itcast.hibernate3.demo2.Order"/>17 ????????</set>18 ????</class>19 </hibernate-mapping>

Order.hbm.xml

 1 <hibernate-mapping> 2 ????<class name="cn.itcast.hibernate3.demo2.Order" table="orders"> 3 ????????<!-- 配置唯一标识 ?--> 4 ????????<id name="oid" column="oid"> 5 ????????????<generator class="native"/> 6 ????????</id> 7 ????????<!-- 配置普通属性 --> 8 ????????<property name="addr" column="addr" length="50"/> 9 ????????<!-- 配置映射 -->10 ????????<!-- 11 ????????<many-to-one>标签12 ????????????name ????:关联对象的属性的名称.13 ????????????column ???:表中的外键名称.14 ????????????class ???:关联对象类的全路径15 ????????-->16 ????????<many-to-one name="customer" column="cno" class="cn.itcast.hibernate3.demo2.Customer"/>17 ????</class>18 </hibernate-mapping>

第三步:将映射放到核心配置文件中,完成。

测试:

 1 @Test 2 // 向客户表插入一个客户,在订单表中插入两个订单. 3 public void demo1(){ 4 ????Session session = HibernateUtils.openSession(); 5 ????Transaction tx = session.beginTransaction(); 6 ?????7 ????// 定义一个客户: 8 ????Customer customer = new Customer(); 9 ????customer.setCname("老汤姆");10 ????11 ????// 定义两个订单:12 ????Order order1 = new Order();13 ????order1.setAddr("吉尼斯");14 ????15 ????Order order2 = new Order();16 ????order2.setAddr("西西里");17 ????18 ????// 建立关系:19 ????order1.setCustomer(customer);20 ????order2.setCustomer(customer);21 ????22 ????customer.getOrders().add(order1);23 ????customer.getOrders().add(order2);24 ????25 ????session.save(customer);26 ????session.save(order1);27 ????session.save(order2);28 ????29 ????tx.commit();30 ????session.close();

~成功

但是,这样保存数据太麻烦,在hibernate中存在级联保存:操作当前对象的时候,关联的对象也会被保存

只需在Customer.hbm.xml中set中加入<set name="orders" cascade="save-update">

 1 @Test 2 // 保存客户级联订单. 3 // <set>集合是客户的关联订单对象的集合.所以在<set>上配置一个属性:cascade="save-update" 4 public void demo3(){ 5 ????Session session = HibernateUtils.openSession(); 6 ????Transaction tx = session.beginTransaction(); 7 ?????8 ????// 定义客户: 9 ????Customer customer = new Customer();10 ????customer.setCname("老汤姆");11 ????12 ????// 定义订单:13 ????Order order = new Order();14 ????order.setAddr("吉尼斯");15 ????order.setCustomer(customer);16 ????17 ????customer.getOrders().add(order);18 ????19 ????// 保存的时候只保存一方:20 ????session.save(customer);21 ????22 ????tx.commit();23 ????session.close();24 }

当然,hibernate中不止一种级联

none:不使用级联dave-update:保存或更新的时候级联delete:删除的时候级联all:除了孤儿删除以外的所有级联.delete-orphan ???????:孤儿删除(孤子删除).* 仅限于一对多.只有一对多时候,才有父子存在.认为一的一方是父亲,多的一方是子方.* 当一个客户与某个订单解除了关系.将外键置为null.订单没有了所属客户,相当于一个孩子没有了父亲.将这种记录就删除了.all-delete-orphan:包含了孤儿删除的所有的级联.

另外,hibernate中多表之间由于外键存在双向维护,导致产生多余的sql语句,同样在Customer.hbm.xml中<set name="orders" cascade="save-update" inverse="true">

当inverse=true时,就是告诉Customer放弃对外键的维护权。

Hibernate中多对多的配置和一对多差不多,只是在各自的实体类中都存在对方的实体类集合,另外xml中如下:

Course.hbm.xml

 1 <hibernate-mapping> 2 ????<class name="cn.itcast.hibernate3.demo3.Course" table="course"> 3 ????????<!-- 配置唯一标识 --> 4 ????????<id name="cid" column="cid"> 5 ????????????<generator class="native"/> 6 ????????</id> 7 ????????<!-- 配置普通属性 --> 8 ????????<property name="cname" column="cname" length="20"/> 9 ????????<!-- 配置与学生关联映射 -->10 ????????<!-- <set>中name:对应当前类中的学生的集合的名称 ?table:中间表的名称-->11 ????????<set name="students" table="stu_cour" inverse="true">12 ????????????<!-- <key>中column:当前类在中间表中外键 -->13 ????????????<key column="cno"></key>14 ????????????<!-- <many-to-many>中class:另一方的类全路径. column:另一方在中间表中外键名称 -->15 ????????????<many-to-many class="cn.itcast.hibernate3.demo3.Student" column="sno"/>16 ????????</set>17 ????</class>18 </hibernate-mapping>

Student.hbm.xml

 1 <hibernate-mapping> 2 ????<class name="cn.itcast.hibernate3.demo3.Student" table="student"> 3 ????????<!-- 配置唯一标识 --> 4 ????????<id name="sid" column="sid"> 5 ????????????<generator class="native"/> 6 ????????</id> 7 ????????<!-- 配置普通属性 --> 8 ????????<property name="sname" column="sname" length="20"/> 9 ????????10 ????????<!-- 配置关联映射 -->11 ????????<!-- <set>标签 name:对应学生中的课程集合的名称 ??table:中间表名称. -->12 ????????<set name="courses" table="stu_cour" cascade="save-update,delete">13 ????????????<!-- <key>中column写 当前类在中间表的外键.-->14 ????????????<key column="sno"></key>15 ????????????<!-- <many-to-many>中class:另一方类的全路径. column:另一方在中间表中外键名称-->16 ????????????<many-to-many class="cn.itcast.hibernate3.demo3.Course" column="cno"/>17 ????????</set>18 ????</class>19 </hibernate-mapping>

另外,对应多对多中数据的删除,建议采用remove来删除数据

 1 @Test 2 // 多对多的学生退选. 3 public void demo4(){ 4 ????Session session = HibernateUtils.openSession(); 5 ????Transaction tx = session.beginTransaction(); 6 ?????7 ????// 查询一号学生 8 ????Student student = (Student) session.get(Student.class, 1); 9 ????Course course = (Course) session.get(Course.class, 2);10 ????student.getCourses().remove(course);11 ????12 ????tx.commit();13 ????session.close();14 }

Hibernate映射

原文地址:http://www.cnblogs.com/lesliehe/p/8021988.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved