Hibernate和JPA使用连接表处理多对一映射

2023-11-03 17:08

本文主要是介绍Hibernate和JPA使用连接表处理多对一映射,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

在项目中,原有的持久化操作时使用JPA进行的,通过注解多对一映射被映射成中间表和两个数据库表,其代码如下:

  1. import javax.persistence.Column;
  2. import javax.persistence.Entity;
  3. import javax.persistence.GeneratedValue;
  4. import javax.persistence.GenerationType;
  5. import javax.persistence.Id;
  6. import javax.persistence.NamedQueries;
  7. import javax.persistence.NamedQuery;
  8. import javax.persistence.Table;
  9. /**
  10.  * 产品实体类
  11.  * @author 李文锴
  12.  */
  13. @Entity
  14. @Table(name = "yunda_product")
  15. @NamedQueries({
  16.     @NamedQuery(name = "getProduct", query = "SELECT p FROM OrderProduct AS p"),
  17.     @NamedQuery(name = "getProductByName", query = "SELECT p FROM OrderProduct AS p WHERE p.name=:name")
  18. })
  19. public class OrderProduct implements java.io.Serializable {
  20.     private static final long serialVersionUID = 1L;
  21.     /**
  22.      * 货物id
  23.      */
  24.     @Id
  25.     @GeneratedValue(strategy = GenerationType.AUTO)
  26.     private Long id;
  27.     /**
  28.      * 货物名称
  29.      */
  30.     @Column(name = "p_name", length = 80, nullable = false)
  31.     private String name;
  32.     /**
  33.      * 货物类型
  34.      */
  35.     @Column(name = "p_type", length = 80, nullable = false)
  36.     private String type;
  37.     /**
  38.      * 货物数量
  39.      */
  40.     @Column(name = "p_quantity", nullable = false)
  41.     private int quantity;
  42.     public OrderProduct() {
  43.     }
  44.     public OrderProduct(String name, String type, int quantity) {
  45.         setName(name);
  46.         setType(type);
  47.         setQuantity(quantity);
  48.     }
  49.     public Long getId() {
  50.         return id;
  51.     }
  52.     public void setId(Long id) {
  53.         this.id = id;
  54.     }
  55.     public String getName() {
  56.         return name;
  57.     }
  58.     public void setName(String name) {
  59.         this.name = name;
  60.     }
  61.     public int getQuantity() {
  62.         return quantity;
  63.     }
  64.     public void setQuantity(int quantity) {
  65.         this.quantity = quantity;
  66.     }
  67.     public String getType() {
  68.         return type;
  69.     }
  70.     public void setType(String type) {
  71.         this.type = type;
  72.     }
  73.     @Override
  74.     public boolean equals(Object obj) {
  75.         if (obj == null) {
  76.             return false;
  77.         }
  78.         if (getClass() != obj.getClass()) {
  79.             return false;
  80.         }
  81.         final OrderProduct other = (OrderProduct) obj;
  82.         if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
  83.             return false;
  84.         }
  85.         if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) {
  86.             return false;
  87.         }
  88.         if (this.quantity != other.quantity) {
  89.             return false;
  90.         }
  91.         return true;
  92.     }
  93.     @Override
  94.     public int hashCode() {
  95.         int hash = 7;
  96.         hash = 61 * hash + (this.name != null ? this.name.hashCode() : 0);
  97.         hash = 61 * hash + (this.type != null ? this.type.hashCode() : 0);
  98.         hash = 61 * hash + this.quantity;
  99.         return hash;
  100.     }
  101. }

 

  1. import java.util.Date;
  2. import java.util.Set;
  3. import javax.persistence.CascadeType;
  4. import javax.persistence.Column;
  5. import javax.persistence.Entity;
  6. import javax.persistence.GeneratedValue;
  7. import javax.persistence.GenerationType;
  8. import javax.persistence.Id;
  9. import javax.persistence.JoinColumn;
  10. import javax.persistence.JoinTable;
  11. import javax.persistence.OneToMany;
  12. import javax.persistence.Table;
  13. import javax.persistence.Temporal;
  14. /**
  15.  * 存储订单实体类,其中和产品实体进行关联
  16.  * @author 李文锴
  17.  */
  18. @Entity
  19. @Table(name = "stock_order")
  20. public class StockOrder implements java.io.Serializable {
  21.     private static final long serialVersionUID = 1L;
  22.     /**
  23.      * 订单id
  24.      */
  25.     @Id
  26.     @GeneratedValue(strategy = GenerationType.AUTO)
  27.     private Long id;
  28.     /**
  29.      * 客户编号
  30.      */
  31.     @Column(name = "customer_no", length = 20, nullable = false)
  32.     private String customerNO;
  33.     /**
  34.      * 客户名称
  35.      */
  36.     @Column(name = "customer_name", length = 80, nullable = false)
  37.     private String customerName;
  38.     /**
  39.      * 产品
  40.      */
  41.     @OneToMany(cascade = CascadeType.ALL)
  42.     @JoinTable(name = "stock_order_product", joinColumns = {@JoinColumn(name = "stock_order_id")}, inverseJoinColumns = {@JoinColumn(name = "product_id")})
  43.     private Set<OrderProduct> prdoucts;
  44.     /**
  45.      * 到达日期
  46.      */
  47.     @Column(name = "arrival_date", nullable = false)
  48.     @Temporal(javax.persistence.TemporalType.DATE)
  49.     private Date arrivalDate;
  50.     public StockOrder() {
  51.     }
  52.     public StockOrder(String customerNO, String customerName, Set<OrderProduct> prdoucts, Date arrivalDate) {
  53.         setCustomerNO(customerNO);
  54.         setCustomerName(customerName);
  55.         setPrdoucts(prdoucts);
  56.         setArrivalDate(arrivalDate);
  57.     }
  58.     public Date getArrivalDate() {
  59.         return arrivalDate;
  60.     }
  61.     public void setArrivalDate(Date arrivalDate) {
  62.         this.arrivalDate = arrivalDate;
  63.     }
  64.     public String getCustomerNO() {
  65.         return customerNO;
  66.     }
  67.     public void setCustomerNO(String customerNO) {
  68.         this.customerNO = customerNO;
  69.     }
  70.     public Long getId() {
  71.         return id;
  72.     }
  73.     public void setId(Long id) {
  74.         this.id = id;
  75.     }
  76.     public Set<OrderProduct> getPrdoucts() {
  77.         return prdoucts;
  78.     }
  79.     public void setPrdoucts(Set<OrderProduct> prdoucts) {
  80.         this.prdoucts = prdoucts;
  81.     }
  82.     public String getCustomerName() {
  83.         return customerName;
  84.     }
  85.     public void setCustomerName(String customerName) {
  86.         this.customerName = customerName;
  87.     }
  88.     @Override
  89.     public boolean equals(Object obj) {
  90.         if (obj == null) {
  91.             return false;
  92.         }
  93.         if (getClass() != obj.getClass()) {
  94.             return false;
  95.         }
  96.         final StockOrder other = (StockOrder) obj;
  97.         if ((this.customerNO == null) ? (other.customerNO != null) : !this.customerNO.equals(other.customerNO)) {
  98.             return false;
  99.         }
  100.         if ((this.customerName == null) ? (other.customerName != null) : !this.customerName.equals(other.customerName)) {
  101.             return false;
  102.         }
  103.         if (this.prdoucts != other.prdoucts && (this.prdoucts == null || !this.prdoucts.equals(other.prdoucts))) {
  104.             return false;
  105.         }
  106.         if (this.arrivalDate != other.arrivalDate && (this.arrivalDate == null || !this.arrivalDate.equals(other.arrivalDate))) {
  107.             return false;
  108.         }
  109.         return true;
  110.     }
  111.     @Override
  112.     public int hashCode() {
  113.         int hash = 5;
  114.         hash = 59 * hash + (this.customerNO != null ? this.customerNO.hashCode() : 0);
  115.         hash = 59 * hash + (this.customerName != null ? this.customerName.hashCode() : 0);
  116.         hash = 59 * hash + (this.prdoucts != null ? this.prdoucts.hashCode() : 0);
  117.         hash = 59 * hash + (this.arrivalDate != null ? this.arrivalDate.hashCode() : 0);
  118.         return hash;
  119.     }
  120. }
  1. import java.util.Date;
  2. import java.util.Set;
  3. import javax.persistence.CascadeType;
  4. import javax.persistence.Column;
  5. import javax.persistence.Entity;
  6. import javax.persistence.GeneratedValue;
  7. import javax.persistence.GenerationType;
  8. import javax.persistence.Id;
  9. import javax.persistence.JoinColumn;
  10. import javax.persistence.JoinTable;
  11. import javax.persistence.OneToMany;
  12. import javax.persistence.Table;
  13. import javax.persistence.Temporal;
  14. /**
  15.  * 运输订单实体类,并于产品实体进行关联
  16.  * @author 李文锴
  17.  */
  18. @Entity
  19. @Table(name = "trans_order")
  20. public class TransOrder implements java.io.Serializable {
  21.     private static final long serialVersionUID = 1L;
  22.     /**
  23.      * 订单id
  24.      */
  25.     @Id
  26.     @GeneratedValue(strategy = GenerationType.AUTO)
  27.     private Long id;
  28.     /**
  29.      * 客户编号
  30.      */
  31.     @Column(name = "customer_no", length = 20, nullable = false)
  32.     private String customerNO;
  33.     /**
  34.      * 客户名称
  35.      */
  36.     @Column(name = "customer_name", length = 80, nullable = false)
  37.     private String customerName;
  38.     /**
  39.      * 产品
  40.      */
  41.     @OneToMany(cascade = CascadeType.ALL)
  42.     @JoinTable(name = "trans_order_product", joinColumns = {@JoinColumn(name = "trans_order_id")}, inverseJoinColumns = {@JoinColumn(name = "product_id")})
  43.     private Set<OrderProduct> prdoucts;
  44.     /**
  45.      * 其实地址
  46.      */
  47.     @Column(name = "start_address", length = 80, nullable = false)
  48.     private String startAddress;
  49.     /**
  50.      * 目的地址
  51.      */
  52.     @Column(name = "end_address", length = 80, nullable = false)
  53.     private String endAddress;
  54.     /**
  55.      * 运输日期
  56.      */
  57.     @Column(name = "trans_date", nullable = false)
  58.     @Temporal(javax.persistence.TemporalType.DATE)
  59.     private Date transportationDate;
  60.     public TransOrder() {
  61.     }
  62.     public TransOrder(String customerNO, String customerName, Set<OrderProduct> prdoucts, String startAddress, String endAddress, Date transportationDate) {
  63.         setCustomerNO(customerNO);
  64.         setCustomerName(customerName);
  65.         setPrdoucts(prdoucts);
  66.         setStartAddress(startAddress);
  67.         setEndAddress(endAddress);
  68.         setTransportationDate(transportationDate);
  69.     }
  70.     public Date getTransportationDate() {
  71.         return transportationDate;
  72.     }
  73.     public void setTransportationDate(Date transportationDate) {
  74.         this.transportationDate = transportationDate;
  75.     }
  76.     public String getCustomerNO() {
  77.         return customerNO;
  78.     }
  79.     public void setCustomerNO(String customerNO) {
  80.         this.customerNO = customerNO;
  81.     }
  82.     public Long getId() {
  83.         return id;
  84.     }
  85.     public void setId(Long id) {
  86.         this.id = id;
  87.     }
  88.     public Set<OrderProduct> getPrdoucts() {
  89.         return prdoucts;
  90.     }
  91.     public void setPrdoucts(Set<OrderProduct> prdoucts) {
  92.         this.prdoucts = prdoucts;
  93.     }
  94.     public String getCustomerName() {
  95.         return customerName;
  96.     }
  97.     public void setCustomerName(String customerName) {
  98.         this.customerName = customerName;
  99.     }
  100.     public String getEndAddress() {
  101.         return endAddress;
  102.     }
  103.     public void setEndAddress(String endAddress) {
  104.         this.endAddress = endAddress;
  105.     }
  106.     public String getStartAddress() {
  107.         return startAddress;
  108.     }
  109.     public void setStartAddress(String startAddress) {
  110.         this.startAddress = startAddress;
  111.     }
  112.     @Override
  113.     public boolean equals(Object obj) {
  114.         if (obj == null) {
  115.             return false;
  116.         }
  117.         if (getClass() != obj.getClass()) {
  118.             return false;
  119.         }
  120.         final TransOrder other = (TransOrder) obj;
  121.         if ((this.customerNO == null) ? (other.customerNO != null) : !this.customerNO.equals(other.customerNO)) {
  122.             return false;
  123.         }
  124.         if ((this.customerName == null) ? (other.customerName != null) : !this.customerName.equals(other.customerName)) {
  125.             return false;
  126.         }
  127.         if (this.prdoucts != other.prdoucts && (this.prdoucts == null || !this.prdoucts.equals(other.prdoucts))) {
  128.             return false;
  129.         }
  130.         if ((this.startAddress == null) ? (other.startAddress != null) : !this.startAddress.equals(other.startAddress)) {
  131.             return false;
  132.         }
  133.         if ((this.endAddress == null) ? (other.endAddress != null) : !this.endAddress.equals(other.endAddress)) {
  134.             return false;
  135.         }
  136.         if (this.transportationDate != other.transportationDate && (this.transportationDate == null || !this.transportationDate.equals(other.transportationDate))) {
  137.             return false;
  138.         }
  139.         return true;
  140.     }
  141.     @Override
  142.     public int hashCode() {
  143.         int hash = 3;
  144.         hash = 79 * hash + (this.customerNO != null ? this.customerNO.hashCode() : 0);
  145.         hash = 79 * hash + (this.customerName != null ? this.customerName.hashCode() : 0);
  146.         hash = 79 * hash + (this.prdoucts != null ? this.prdoucts.hashCode() : 0);
  147.         hash = 79 * hash + (this.startAddress != null ? this.startAddress.hashCode() : 0);
  148.         hash = 79 * hash + (this.endAddress != null ? this.endAddress.hashCode() : 0);
  149.         hash = 79 * hash + (this.transportationDate != null ? this.transportationDate.hashCode() : 0);
  150.         return hash;
  151.     }
  152. }

 

先要使用Hibernate对其进行映射,由于产生了中间表,所以它的配置文件有些不同,如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  3. <hibernate-mapping>
  4.     <class name="com.yunda.dao.domain.Product" table="yunda_product">
  5.         <id name="id" type="long">
  6.             <generator class="native"/>
  7.         </id>
  8.         <property name="name" column="p_name" type="string" length="80" not-null="true"/>
  9.         <property name="type" column="p_type" type="string" length="80" not-null="true"/>
  10.         <property name="quantity" column="p_quantity" type="integer" length="80" not-null="true"/>
  11.         <!-- 使用join来配置多对一的连接,以table属性来表示连接表的多对一,连接表为stock_order_id -->
  12.         <!-- optional属性表示这是一个外连接,inverse属性可以出现在一端和多端,这里选择出现在多端,效果相同 -->
  13.         <join table="stock_order_product" optional="true" inverse="true">
  14.             <!-- 该key的字段为连接表中的字段,作为外键 -->
  15.             <key column="product_id" />
  16.             <!-- 连接表中配置多对一,对应的字段为stock_order_id -->
  17.             <many-to-one name="stockOrder" column="stock_order_id" not-null="true" />
  18.         </join>
  19.         <!-- 使用join来配置多对一的连接,以table属性来表示连接表的多对一,连接表为trans_order_id -->
  20.         <!-- optional属性表示这是一个外连接,inverse属性可以出现在一端和多端,这里选择出现在多端,效果相同 -->
  21.         <join table="trans_order_product" optional="true" inverse="true">
  22.             <!-- 该key的字段为连接表中的字段,作为外键 -->
  23.             <key column="product_id" />
  24.             <!-- 连接表中配置多对一,对应的字段为trans_order_id -->
  25.             <many-to-one name="transOrder" column="trans_order_id" not-null="true" />
  26.         </join>
  27.     </class>
  28. </hibernate-mapping>

 

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  3. <hibernate-mapping>
  4.     <class name="com.yunda.dao.domain.StockOrder" table="stock_order">
  5.         <id name="id" type="long">
  6.             <generator class="native"/>
  7.         </id>
  8.         <property name="customerNO" column="customer_no" type="string" length="20" not-null="true"/>
  9.         <property name="customerName" column="customer_name" type="string" length="80" not-null="true"/>
  10.         <property name="arrivalDate" column="arrival_date" type="date" not-null="true"/>
  11.         <!-- 通过连接表的一端,因此需要table属性为stock_order_product -->
  12.         <set name="prdoucts" cascade="all" table="stock_order_product" lazy="false">
  13.             <!-- 该key的字段为连接表中的字段,作为外键 -->
  14.             <key column="stock_order_id" />
  15.             <!-- 配置多对多 -->
  16.             <!-- 但是unique属性为true,表示product_id字段为不可重复,保证一对多关系 -->
  17.             <many-to-many class="com.yunda.dao.domain.Product" column="product_id" unique="true" />
  18.         </set>
  19.     </class>
  20. </hibernate-mapping>

 

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  3. <hibernate-mapping>
  4.     <class name="com.yunda.dao.domain.TransOrder" table="trans_order">
  5.         <id name="id" type="long">
  6.             <generator class="native"/>
  7.         </id>
  8.         <property name="customerNO" column="customer_no" type="string" length="20" not-null="true"/>
  9.         <property name="customerName" column="customer_name" type="string" length="80" not-null="true"/>
  10.         <property name="startAddress" column="start_address" type="string" length="80" not-null="true"/>
  11.         <property name="endAddress" column="end_address" type="string" length="80" not-null="true"/>
  12.         <property name="transportationDate" column="trans_date" type="date" not-null="true"/>
  13.         <!-- 通过连接表的一端,因此需要table属性为stock_order_product -->
  14.         <set name="prdoucts" cascade="all" table="trans_order_product" lazy="false">
  15.             <!-- 该key的字段为连接表中的字段,作为外键 -->
  16.             <key column="trans_order_id" />
  17.             <!-- 配置多对多 -->
  18.             <!-- 但是unique属性为true,表示product_id字段为不可重复,保证一对多关系 -->
  19.             <many-to-many class="com.yunda.dao.domain.Product" column="product_id" unique="true" />
  20.         </set>
  21.     </class>
  22. </hibernate-mapping>

 

这篇关于Hibernate和JPA使用连接表处理多对一映射的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/339650

相关文章

Java使用SLF4J记录不同级别日志的示例详解

《Java使用SLF4J记录不同级别日志的示例详解》SLF4J是一个简单的日志门面,它允许在运行时选择不同的日志实现,这篇文章主要为大家详细介绍了如何使用SLF4J记录不同级别日志,感兴趣的可以了解下... 目录一、SLF4J简介二、添加依赖三、配置Logback四、记录不同级别的日志五、总结一、SLF4J

使用Python实现一个优雅的异步定时器

《使用Python实现一个优雅的异步定时器》在Python中实现定时器功能是一个常见需求,尤其是在需要周期性执行任务的场景下,本文给大家介绍了基于asyncio和threading模块,可扩展的异步定... 目录需求背景代码1. 单例事件循环的实现2. 事件循环的运行与关闭3. 定时器核心逻辑4. 启动与停

如何使用Nginx配置将80端口重定向到443端口

《如何使用Nginx配置将80端口重定向到443端口》这篇文章主要为大家详细介绍了如何将Nginx配置为将HTTP(80端口)请求重定向到HTTPS(443端口),文中的示例代码讲解详细,有需要的小伙... 目录1. 创建或编辑Nginx配置文件2. 配置HTTP重定向到HTTPS3. 配置HTTPS服务器

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

使用Python构建一个Hexo博客发布工具

《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的