使用Hibernate操作一对多关系

Hibernate介绍:http://blog.csdn.net/ljheee/article/details/52475798

Hibernate操作一对一关系:http://blog.csdn.net/ljheee/article/details/52593662

Hibernate操作一对多关系:

        "一对多"是最普遍的映射关系,简单来讲就如产品和类别的关系。一个类别下可有多个产品,多个产品可同属一个类别。

本例---业务说明

        本实例涉及的表为CATEGORIES(类别表)和PRODUCTS(商品表)。

        规定每个类别下可有多个商品;每个商品被划分到某一个类别。

        产品表中的类别ID引用类别表中的外键。

下面进入主题:使用Hibernate操作一对多关系

创建一个Java工程。创建实体类Product,其类中需要有一个字段标识是哪一个类别。

public class Product {

      private StringproductNum;                   

      private StringproductName;  

      private StringcateogryName;//用一个String类型标识产品类别

}

      此处用一个String类型标识产品类别,也是可行的,不过通常不会这么做,因为在数据库存储“产品”一条条记录的时候,表中的这一列存在冗余。所以推荐下面一中方案:

public class Product {

      private String id;                   

      private String name;  

      private Categorycategory;//是一个自定义类

      // Getters &Setters ...

}

public class Category {//自定义类--类别

      private Long id;

      private stringcategoryName;

      // Getters & Setters ...

}

数据库表

<!– Product类映射文件 - ->

<class name="Product"table="PRODUCTS">

   <id name="id" column="PRODUCT_NUM">

       <generator class="native"></generator>

   </id>

   <property name="name"column="PRODUCT_NAME"></property>

   <many-to-one name="category"

                      column="CATEGORY_ID"

                             class="Category"

                             cascade="save-update">

   </many-to-one>

</class>

该映射文件中,前两个分别指定了PRODUCTS表中的主键列和产品名;<many-to-one name="category"指定产品类Product中category字段类型是class="Category"。

<!-- Category类映射文件 - ->

<class name="Category"table="CATEGORIES">

   <id name="id" column="CATEGORY_ID"type="java.lang.Long">

       <generator class="native"></generator>

   </id>

   <property name="path"column="CATEGORY_PATH"></property>

</class>

        这样就建立了产品和类别的单向一对多关联,即:从某个产品,单向可知该产品所属类别。

        但是可能会有这样的需求,我想查询“儿童玩具”这个类别下的成品有哪些,并按价格排序,这时候就需要建立产品和类别的双向一对多关联:由产品可知所属类别,由某个类别也可得该类别下的所有产品。

Category 类修改如下:

public class Category {

     private Long id;

     private stringcategoryName;

     private Set products;//所属该类别的产品集合

        // Getters & Setters ...

}

<!-- Category类映射文件 - ->

<class name="Category"table="CATEGORIES">

   <id name="id" column="CATEGORY_ID"type="java.lang.Long">

       <generator class="native"></generator>

   </id>

   <property name="path"column="CATEGORY_PATH"></property>

   <set name="products" cascade="save-update">

       <key column="CATEGORY_ID"></key>

       <one-to-many class="Product"/>

   </set>

</class>

该映射文件中<setname="products"指定products集合中,放的都是class="Product"类型。    

工程源代码

1、实体类Product

package com.ljheee.orm;
/**
 * 产品类
 * @author ljheee
 *
 */
public class Product {
private Long id;
private String name;
private int price;
private Category category;

public Product() {
}
public Product(String name, int price, Category category) {
      super();
      this.name = name;
      this.price = price;
      this.category = category;
}

public Long getId() {
      return id;
}

public void setId(Long id) {
      this.id = id;
}

public String getName() {
      return name;
}

public void setName(String name) {
      this.name = name;
}

public int getPrice() {
      return price;
}

public void setPrice(int price) {
      this.price = price;
}

public Category getCategory() {
      return category;
}

public void setCategory(Category category) {
      this.category = category;
}

@Override
public String toString() {
      return "Product [id=" + id + ", name=" + name + ", price=" + price + ", category=" + category + "]";
}
}

产品类Product的映射文件:Product.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 2016-9-3 9:30:29 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
    <class name="com.ljheee.orm.Product" table="PRODUCT">
        <id name="id" type="java.lang.Long">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="price" type="int">
            <column name="PRICE" />
        </property>
        
        <many-to-one name="category" class="com.ljheee.orm.Category" fetch="join">
            <column name="CATEGORY_ID" />
        </many-to-one>
    </class>
</hibernate-mapping>

2、[产品]类别Category

 package com.ljheee.orm;
import java.util.HashSet;
import java.util.Set;
/**
 * [产品]类别
 * @author ljheee
 *
 */
public class Category {
private Long id;
private String title;//类别名
private String desc;//类别描述

//不加此行是单向连接,由产品可知是属于哪个类别。
/**
* 产品集合
* 即该类别下,所属的所有产品
*/
private Set<Product> products = new HashSet<>();//集合没有序号

public void addProduct(Product p){
      products.add(p);
}
public Set<Product> getProducts() {
      return products;
}

public void setProducts(Set<Product> products) {
      this.products = products;
}

public Category() {
}
//对象状态
//1 瞬时状态
//2 持久化状态
//3 托管状态
public Category(String title, String desc) {
      super();
      this.title = title;
      this.desc = desc;
}

public Long getId() {
      return id;
}

public void setId(Long id) {
      this.id = id;
}

public String getTitle() {
      return title;
}

public void setTitle(String title) {
      this.title = title;
}

public String getDesc() {
      return desc;
}

public void setDesc(String desc) {
      this.desc = desc;
}

@Override
public String toString() {
      return "Category [id=" + id + ", title=" + title + ", desc=" + desc + "]";
}
}

Category的映射文件:Category.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 2016-9-3 9:30:29 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<!-- 左边类名,映射右边指定的关系表 -->
    <class name="com.ljheee.orm.Category" table="CATEGORY">
    
    <!--类的id属性,作数据库ID字段列,generator生成类别class="increment"字段增长-->
        <id name="id" type="java.lang.Long">
            <column name="ID" />
            <generator class="native" />
        </id>
        
        <property name="title" type="java.lang.String">
            <column name="TITLE" />
        </property>
        <property name="desc" type="java.lang.String">
            <column name="summary" />
        </property>
        
        <!-- Set<Product>建立双向关联 -->
        <set name="products" cascade="save-update" fetch="join" lazy="true">
        <key> 
        <!--CATEGORY_ID是表Product的外键  -->
        <column name="CATEGORY_ID"></column>
        </key>
        <one-to-many class="com.ljheee.orm.Product"/>
        </set>
        
    </class>
</hibernate-mapping>

3、工程配置文件: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>
<!-- 这个cfg配置文件里,可有多个会话工.厂;如果就默认的一个,则不指定name -->
 <session-factory >
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.password">abc</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mypersons</property>
    <property name="hibernate.connection.username">abc</property>
    <property name="hibernate.default_schema">mypersons</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  
    <!-- 第一次运行,根据配置文件,自动创建表  -->
    <!-- <property name="hbm2ddl.auto">create</property> -->
  
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.format_sql">true</property>
  
    <mapping resource="com/ljheee/orm/Category.hbm.xml"/>
    <mapping resource="com/ljheee/orm/Product.hbm.xml"/>
  
 </session-factory>
</hibernate-configuration>

        这些完成后,创建一个测试类,在main方法中获得会话Session,即可对增删改查数据记录了。

如:添加一个商品"lenovoN220",并且将其划到"笔记本"类别下

//相互绑定关系,在数据库表中体现为主外键

pro.setCategory(ctg);

ctg.getProducts().add(pro);

并且这里用session只save了产品pro,并没有save类别ctg,这是因为做了级联。

 

Hibernate配置文件3个重要属性

1、cascade(级联)

        1.       级联的意思是指定两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作

        2.       总共可以取值为:all、none、save-update、delete

        3.       all-代表在所有的情况下都执行级联操作

        4.       none-在所有情况下都不执行级联操作

        5.       save-update-在保存和更新的时候执行级联操作

        6.       delete-在删除的时候执行级联操作

2、lazy – 延迟加载(懒加载)

      lazy – 延迟加载(懒加载),一般用于集合的抓取策略,也就是说只在需要用到的情况下,再发出select语句,将其相关的对象查询出来

      set 默认lazy属性的值是true,即hibernate会自动使用懒加载策略,以提高性能

      举例说明

 <set name="students“ lazy=“false”>

                <keycolumn="classesid" ></key>

                <one-to-manyclass="com.bjsxt.hibernate.Student" />

 </set>

3、inverse属性

      inverse – 标记由哪一方来维护关联关系(双向关联中会用到)

      1.  inverse默认值为false

      2.  如果inverse设置为true,表示将由对方维护两者之间的关联关系

      举例说明

 <set name="students“ lazy=“false”inverse=“true”>

                 <keycolumn="classesid" ></key>

                 <one-to-manyclass="com.bjsxt.hibernate.Student" />

 </set>

 


完整工程:https://github.com/ljheee/ProductORM

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值