分享web开发知识

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

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

学习笔记之Hibernate_映射关系之一对多映射关系

发布时间:2023-09-06 01:28责任编辑:胡小海关键词:Hibernate

一、单向一对多映射关系

实体类的创建

1.本例子的 多的一方是Order,一的一方是Customer,一个Customer 可以有很多个Order, 而一个Order只能属于一个Customer。

    实体类Customer

package hibernates.entities.n21;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; ???} ???public Customer(String customerName) { ???????super(); ???????this.customerName = customerName; ???} ???public Customer() { ???????super(); ???????// TODO Auto-generated constructor stub ???} ???@Override ???public String toString() { ???????return "Customer [customerId=" + customerId + ", customerName=" + customerName + "]"; ???}}

    实体类Order

package hibernates.entities.n21;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; ???} ???public Order(String orderName, Customer customer) { ???????super(); ???????this.orderName = orderName; ???????this.customer = customer; ???} ???public Order() { ???????super(); ???????// TODO Auto-generated constructor stub ???} ???@Override ???public String toString() { ???????return "Order [orderId=" + orderId + ", orderName=" + orderName + ", customer=" + customer + "]"; ???}}

编写基础映射文件

Order.hbm.xml的编写:主要是编写<many-to-one>标签

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Generated 2017-11-27 21:13:51 by Hibernate Tools 3.5.0.Final --><hibernate-mapping> ???<class name="hibernates.entities.n21.Order" table="ORDERS"> ???????????<id name="orderId" type="java.lang.Integer"> ???????????<column name="ORDERID" /> ???????????<generator class="native" /> ???????</id> ???????????????<property name="orderName" type="java.lang.String"> ???????????<column name="ORDERNAME" /> ???????</property> ???????????????<!-- ????????????映射多对一的关联关系。 使用 many-to-one 来映射多对一的关联关系 ????????????name: 多这一端关联的一那一端的属性的名字 ???????????class: 一那一端的属性对应的类名 ???????????column: 一那一端在多的一端对应的数据表中的外键的名字 ???????--> ???????<many-to-one name="customer" class="hibernates.entities.n21.Customer" > ???????????<column name="CUSTOMER_ID" /> ???????</many-to-one> ???????????</class> ???</hibernate-mapping>

Customer.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"><!-- Generated 2017-11-27 21:13:51 by Hibernate Tools 3.5.0.Final --><hibernate-mapping> ???<class name="hibernates.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="CUSTOME_RNAME" /> ???????</property> ???????????</class> ???</hibernate-mapping>

核心配置文件hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC ???????"-//Hibernate/Hibernate Configuration DTD 3.0//EN" ???????"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration> ???<session-factory> ???????????<!-- 配置连接数据库的基本信息 --> ???????<property name="connection.username">root</property> ???????<property name="connection.password">123456</property> ???????<property name="connection.driver_class">com.mysql.jdbc.Driver</property> ???????<property name="connection.url">jdbc:mysql:///hibernate</property> ???????????????<!-- 配置 hibernate 的基本信息 --> ???????<!-- hibernate 所使用的数据库方言 ????????<property name="dialect">org.hibernate.dialect.MySQLMyISAMDialect</property> ???????????????<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> ???????????????<property name="dialect">org.hibernate.dialect.MySQLDialect</property> ???????--> ???????????????<!-- 执行操作时是否在控制台打印 SQL --> ???????<property name="show_sql">true</property> ???????????<!-- 是否对 SQL 进行格式化 --> ???????<property name="format_sql">true</property> ???????????<!-- 指定自动生成数据表的策略 --> ???????<property name="hbm2ddl.auto">update</property> ???????????????<!-- 设置 Hibernate 的事务隔离级别 --> ???????<property name="connection.isolation">2</property> ???????????????<!-- 删除对象后, 使其 OID 置为 null --> ???????<property name="use_identifier_rollback">true</property> ???????????????<!-- 配置 C3P0 数据源 --> ???????<property name="hibernate.c3p0.max_size">10</property> ???????<property name="hibernate.c3p0.min_size">5</property> ???????<property name="c3p0.acquire_increment">2</property> ???????????????<property name="c3p0.idle_test_period">2000</property> ???????<property name="c3p0.timeout">2000</property> ???????????????<property name="c3p0.max_statements">10</property> ???????????????<!-- 指定关联的 .hbm.xml 文件 --> ???????<mapping resource="hibernates/entities/n21/Customer.hbm.xml"/> ???????<mapping resource="hibernates/entities/n21/Order.hbm.xml"/> ???????</session-factory></hibernate-configuration>

对Order和Customer的增删改查的测试

package hibernates.entities.n21;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.boot.MetadataSources;import org.hibernate.boot.registry.StandardServiceRegistryBuilder;import org.hibernate.service.ServiceRegistry;import org.junit.After;import org.junit.Before;import org.junit.Test;public class HibernateTest { ???????????Session session; ???SessionFactory sessionFactory; ???Transaction transaction; ???????@Before ???public void init() { ???????ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build(); ???????sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory(); ???????session = sessionFactory.openSession(); ???????transaction = session.beginTransaction(); ???} ???????@After ???public void destroy() { ???????transaction.commit(); ???????session.close(); ???????sessionFactory.close(); ???} ???????@Test ???public void testMany2OneSave() { ???????Customer customer = new Customer(); ???????customer.setCustomerName("小明"); ???????Order order1 = new Order(); ???????order1.setOrderName("AA"); ???????Order order2 = new Order(); ???????order2.setOrderName("BB"); ???????????????//设定关联关系 ???????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); ???????????} ???????@Test ???public void testMany2OneGet() { ???????//1. 若查询多的一端的一个对象, 则默认情况下, 只查询了多的一端的对象. 而没有查询关联的 ???????//1 的那一端的对象! ???????Order order = session.get(Order.class, 1); ???????System.out.println(order); ???????System.out.println(order.getCustomer().getClass().getName()); ???????????????session.close(); ???????????????//2. 在需要使用到关联的对象时, 才发送对应的 SQL 语句. ????????Customer customer = order.getCustomer(); ???????System.out.println(customer); ???????????????//3. 在查询 Customer 对象时, 由多的一端导航到 1 的一端时, ????????//若此时 session 已被关闭, 则默认情况下 ???????//会发生 LazyInitializationException 异常 ???????????????//4. 获取 Order 对象时, 默认情况下, 其关联的 Customer 对象是一个代理对象! ???????????} ???????@Test ???public void testUpdate() { ???????Order order = session.get(Order.class, 1); ???????order.getCustomer().setCustomerName("555"); ???} ???????????@Test ???public void testDelete() { ???????//在不设定级联关系的情况下, 且 1 这一端的对象有 n 的对象在引用, 不能直接删除 1 这一端的对象 ???????Customer customer = session.get(Customer.class, 1); ???????session.delete(customer); ???}}

二、双向一对多映射关系

 实体类的创建(与一中的一样)

编写基础映射文件

Order.hbm.xml的编写:主要是编写<many-to-one>标签

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Generated 2017-12-1 19:54:01 by Hibernate Tools 3.5.0.Final --><hibernate-mapping> ???<class name="hibernates.entities.n21.both.Order" table="BOTHORDERS"> ???????<id name="orderId" type="java.lang.Integer"> ???????????<column name="ORDERID" /> ???????????<generator class="native" /> ???????</id> ???????<property name="orderName" type="java.lang.String"> ???????????<column name="ORDERNAME" /> ???????</property> ???????<many-to-one name="customer" class="hibernates.entities.n21.both.Customer" fetch="join" ???????????????cascade="delete"> ???????????<column name="CUSTOMERID" /> ???????</many-to-one> ???</class></hibernate-mapping>

Customer.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"><!-- Generated 2017-12-1 19:54:01 by Hibernate Tools 3.5.0.Final --><hibernate-mapping> ???<class name="hibernates.entities.n21.both.Customer" table="BOTHCUSTOMERS"> ???????<id name="customerId" type="java.lang.Integer"> ???????????<column name="CUSTOMERID" /> ???????????<generator class="native" /> ???????</id> ???????<property name="customerName" type="java.lang.String"> ???????????<column name="CUSTOMERNAME" /> ???????</property> ???????<set name="orders" table="BOTHORDERS" inverse="true" cascade="delete" order-by="CUSTOMERID DESC"> ???????????<key> ???????????????<column name="CUSTOMERID" /> ???????????</key> ???????????<one-to-many class="hibernates.entities.n21.both.Order" />
???????</set> ???</class></hibernate-mapping>

核心配置文件hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC ???????"-//Hibernate/Hibernate Configuration DTD 3.0//EN" ???????"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration> ???<session-factory> ???????????<!-- 配置连接数据库的基本信息 --> ???????<property name="connection.username">root</property> ???????<property name="connection.password">123456</property> ???????<property name="connection.driver_class">com.mysql.jdbc.Driver</property> ???????<property name="connection.url">jdbc:mysql:///hibernate</property> ???????????????<!-- 配置 hibernate 的基本信息 --> ???????<!-- hibernate 所使用的数据库方言 ????????<property name="dialect">org.hibernate.dialect.MySQLMyISAMDialect</property> ???????????????<property name="dialect">org.hibernate.dialect.MySQLDialect</property> ???--> ???????????????<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> ???????????????????<!-- 执行操作时是否在控制台打印 SQL --> ???????<property name="show_sql">true</property> ???????????<!-- 是否对 SQL 进行格式化 --> ???????<property name="format_sql">true</property> ???????????<!-- 指定自动生成数据表的策略 --> ???????<property name="hbm2ddl.auto">update</property> ???????????????<!-- 设置 Hibernate 的事务隔离级别 --> ???????<property name="connection.isolation">2</property> ???????????????<!-- 删除对象后, 使其 OID 置为 null --> ???????<property name="use_identifier_rollback">true</property> ???????????????<!-- 配置 C3P0 数据源 --> ???????<property name="hibernate.c3p0.max_size">10</property> ???????<property name="hibernate.c3p0.min_size">5</property> ???????<property name="c3p0.acquire_increment">2</property> ???????????????<property name="c3p0.idle_test_period">2000</property> ???????<property name="c3p0.timeout">2000</property> ???????????????<property name="c3p0.max_statements">10</property> ???????????????<!-- 指定关联的 .hbm.xml 文件 --> ???????<!-- ????????<mapping resource="hibernates/entities/n21/Customer.hbm.xml"/> ???????<mapping resource="hibernates/entities/n21/Order.hbm.xml"/>--> ???????<mapping resource="hibernates/entities/n21/both/Order.hbm.xml"/> ????????<mapping resource="hibernates/entities/n21/both/Customer.hbm.xml"/> ????????</session-factory></hibernate-configuration>

Set标签中的三个属性:inverse、 cascade、 order-by

inverse属性:在hibernate中通过对 inverse 属性的来决定是由双向关联的哪一方来维护表和表之间的关系. inverse = false 的为主动方,inverse = true 的为被动方, 由主动方负责维护关联关系
在没有设置 inverse=true 的情况下,父子两边都维护父子关系,在一对多的关系中一般是把一的一端设置为true,这样可以让hibernate减少很多的update语句。

cascade属性:在对象 – 关系映射文件中, 用于映射持久化类之间关联关系的元素, <set>, <many-to-one> 和 <one-to-one> 都有一个 cascade 属性, 它用于指定如何操纵与当前对象关联的其他对象.
       all: 所有情况下均进行关联操作,即save-update和delete。
       none: 所有情况下均不进行关联操作。这是默认值。
       save-update: 在执行save/update/saveOrUpdate时进行关联操作。
       delete: 在执行delete 时进行关联操作。
       all-delete-orphan: 当一个节点在对象图中成为孤儿节点时,删除该节点

order-by属性:<set> 元素有一个 order-by 属性, 如果设置了该属性, 当 Hibernate 通过 select 语句到数据库中检索集合对象时, 利用 order by 子句进行排序,order-by 属性中还可以加入 SQL 函数。
下面是对于这几个属性打的一些相关代码,以及一些发现:

package hibernates.entities.n21.both;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.boot.MetadataSources;import org.hibernate.boot.registry.StandardServiceRegistryBuilder;import org.hibernate.service.ServiceRegistry;import org.junit.After;import org.junit.Before;import org.junit.Test;public class HibernateTest { ???????????????????Session session; ???SessionFactory sessionFactory; ???Transaction transaction; ???????@Before ???public void init() { ???????ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build(); ???????sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory(); ???????session = sessionFactory.openSession(); ???????transaction = session.beginTransaction(); ???????Customer customer1 = new Customer(); ???????customer1.setCustomerName("AA"); ???????Customer customer2 = new Customer(); ???????customer2.setCustomerName("BB"); ???????Order order1 = new Order(); ???????Order order2 = new Order(); ???????customer1.getOrders().add(order1); ???????customer1.getOrders().add(order2); ???????customer2.getOrders().add(order1); ???????customer2.getOrders().add(order2); ???????order1.setCustomer(customer1); ???????order2.setCustomer(customer1); ???????order1.setCustomer(customer2); ???????order2.setCustomer(customer2); ???????session.save(customer1); ???????session.save(customer2); ???????session.save(order1); ???????session.save(order2); ???} ???????@After ???public void destroy() { ???????transaction.commit(); ???????session.close(); ???????sessionFactory.close(); ???} ???????@Test ???public void testInverse() { ???????//1.可以在 1 的一端的 set 节点指定 inverse=true, 来使 1 的一端放弃维护关联关系! ???????//2.通过多的一端改变来改变表中的数据: ???????Order order3 = session.get(Order.class, 1); ???????order3.setOrderName("HH"); ???????order3.getCustomer().setCustomerName("BB"); ???????//3.通过一的一端来修改表中的数据: ???????Customer customer3 = session.get(Customer.class, 1); ???????customer3.setCustomerName("DD"); ???????customer3.getOrders().iterator().next().setCustomer(customer3); ???????System.out.println(customer3.getOrders()); ???????????} ???????@Test ???public void testCascade() { ???????//当<set> 中的 cascade的属性值为delete时一的一端的数据被删除时,它所关联的多的一端也被删除,<many-to-one>中的 ???????//cascade也具有同样的功能 ???????Customer customer3 = session.get(Customer.class, 1); ???????session.delete(customer3); ???????Order order3 = session.get(Order.class, 1); ???????session.delete(order3); ???} ???????@Test ???public void testOrderBy() { ???????//下面两句输出语句都会使Hibernate查询customer关联的order表,然后按照order-by的设定排序查询 ???????Customer customer3 = session.get(Customer.class, 1); ???????System.out.println(customer3.getOrders()); ???????System.out.println(customer3.getCustomerName()); ???} ???}

学习笔记之Hibernate_映射关系之一对多映射关系

原文地址:http://www.cnblogs.com/hahahahehehe/p/7932341.html

知识推荐

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