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

来源:互联网 发布:陈洁仪左右手 知乎 编辑:程序博客网 时间:2024/05/18 11:28

 

在项目中,原有的持久化操作时使用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>