Hibernate中的映射关系(一对多)
在数据库中表和表之间的关系有几种,下面就详细说一下在Hibernate中怎样映射一对多的关系
Hibernate映射一对多的关系,其实就是持久类之间的映射,那如何把持久类关联起来呢??那就用到.hbm.xml文件的<many-to-one>标签了
具体做法如下:
新建一个customer类:
package com.jeremy.hibernate.app.example; public class Customer { private Integer customerId; private String customerName; public Integer getCustomerId() { return customerId; } public void setCustomerId(Integer customerId) { this.customerId = customerId; } public String getCustomerName() { return customerName; } public void setCustomerName(String customerName) { this.customerName = customerName; } }
再新建一个订单表order表
package com.jeremy.hibernate.app.example; public class Order { private Integer orderId; private String orderName; private Customer customer; public Integer getOrderId() { return orderId; } public void setOrderId(Integer orderId) { this.orderId = orderId; } public String getOrderName() { return orderName; } public void setOrderName(String orderName) { this.orderName = orderName; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } }
那这个两个类怎样关联起来呢??
那就需要通过那就用到.hbm.xml文件的<many-to-one>标签了
在order.hbm.xml文件中配置:就是”多“那段添加一个外键
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.atguigu.hibernate.entities.n21"> <class name="Order" table="ORDERS"> <id name="orderId" type="java.lang.Integer"> <column name="ORDER_ID" /> <generator class="native" /> </id> <property name="orderName" type="java.lang.String"> <column name="ORDER_NAME" /> </property> <!-- 映射多对一的关联关系。 使用 many-to-one 来映射多对一的关联关系 name: 多这一端关联的一那一端的属性的名字 class: 一那一端的属性对应的类名 column: 一那一端在多的一端对应的数据表中的外键的名字 --> <many-to-one name="customer" class="Customer" column="CUSTOMER_ID"></many-to-one> </class> </hibernate-mapping>
customer.hbm.xml文件像普通的那样配置即可
example:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.atguigu.hibernate.entities.n21.Customer" table="CUSTOMERS"> <id name="customerId" type="java.lang.Integer"> <column name="CUSTOMER_ID" /> <generator class="native" /> </id> <property name="customerName" type="java.lang.String"> <column name="CUSTOMER_NAME" /> </property> </class> </hibernate-mapping>
这样就可以把表的一对多关系建立起来了,
建立起来后最重要的是访问,也就是我们怎么在Hibernate中进行多表增删改操作呢??这又是一个关键的问题
增:
@Test public void testMany2OneSave(){ Customer customer = new Customer(); customer.setCustomerName("BB"); Order order1 = new Order(); order1.setOrderName("ORDER-3"); Order order2 = new Order(); order2.setOrderName("ORDER-4"); //设定关联关系,比平常的要多一个设定关联关系的语句,因为外键必须得根据外键的,多以在插入的order表时要么新增一个customer要 么就查询一个customer,这个步骤尤为重要 order1.setCustomer(customer); order2.setCustomer(customer); //执行 save 操作: 先插入 Customer, 再插入 Order, 3 条 INSERT //先插入 1 的一端, 再插入 n 的一端, 只有 INSERT 语句.(推荐使用注释的) // session.save(customer); // // session.save(order1); // session.save(order2); //先插入 Order, 再插入 Customer. 3 条 INSERT, 2 条 UPDATE //先插入 n 的一端, 再插入 1 的一端, 会多出 UPDATE 语句! //因为在插入多的一端时, 无法确定 1 的一端的外键值. 所以只能等 1 的一端插入后, 再额外发送 UPDATE 语句. //所以推荐先插入 1 的一端, 后插入 n 的一端(也就是注释的那部分) session.save(order1); session.save(order2); session.save(customer); }
删delete:
@Test public void testDelete(){ //在不设定级联关系的情况下, 且 1 这一端的对象有 n 的对象在引用, 不能直接删除 1 这一端的对象 Customer customer = (Customer) session.get(Customer.class, 1); session.delete(customer); }
改update:
@Test public void testUpdate(){ Order order = (Order) session.get(Order.class, 1); order.getCustomer().setCustomerName("AAA"); }
查select:
@Test public void testSelect(){ //1. 若查询多的一端的一个对象, 则默认情况下, 只查询了多的一端的对象. 而没有查询关联的1 的那一端的对象! Order order = (Order) session.get(Order.class, 1); System.out.println(order.getOrderName()); System.out.println(order.getCustomer().getClass().getName()); session.close(); //2. 在需要使用到关联的对象时, 才发送对应的 SQL 语句. Customer customer = order.getCustomer(); System.out.println(customer.getCustomerName()); //3. 在查询 Customer 对象时, 由多的一端导航到 1 的一端时, //若此时 session 已被关闭, 则默认情况下 //会发生 LazyInitializationException 异常 //4. 获取 Order 对象时, 默认情况下, 其关联的 Customer 对象是一个代理对象! }
因为持久化对象的set()方法时可以触发Hibernate发送update语句,get()方法可以触发Hibernate发送select语句,我们可以通过外键表的get()和set()的方法对外键表进行更改和查询
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。