javascript代码实例教程-Hibernate 表关系描述之OneToMany

发布时间:2019-03-28 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了javascript代码实例教程-Hibernate 表关系描述之OneToMany脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。

Hibernate 表关系描述之OneToMany
 上篇写了一对一,那么在这篇我们讲一对多,那么在表中的一对多,是使用外键关联,通过一张表的一个键另一个表的外键来建立一多关系;
 而在类中表示为一个类中有一个集合属性包含对方类的很多对象,而在另一个类中,只包含前类的一个对象,从而实现一对多关系的建立!
 而在Hibernate中采用的是Set类型集合,而使用<one-to-many>主<;many-to-one>来实现,好了,我们来看一下:
首先看看表结构!

customer表:

create table customers
(
    ID Bigint not null    Primary key auto_increment,
    userName vArchar(20)
);Order表: create table orders
(
    ID bigint not null PRimary key auto_increment,
    customers_ID bigint,    --应该为customers(ID)外键
    orderDescription VARchar(50)--订单描述
);

有了上面简单的客户表与订单表,来建立一个Project!~并且添加Hibernate~并由上面二张表生成Beans,主键都是native类型~自动递增!
我们将 自动生成的Customer.java    Bean添加一个SET属性,代码如下:


package fengyan.Hibernate;

import java.util.HashSet;
import java.util.Set;

/**
 *Authod:    fengyan
 *    date:    2006-12-30 01:02   
 */

public class Customers  implements java.io.Serializable {


    // Fields   

     private Long id;
     private String userName;

     //必须定义一个Set集合类型的属性以及它的get和set方法,
     //它持有一个Customers对象所发出的所有订单的引用
     private Set orders = new HashSet();

    // Constructors

    public Set getOrders() {
        return orders;
    }


    public void setOrders(Set orders) {
        this.orders = orders;
    }


    /** default constructor */
    public Customers() {
    }

   
    /** full constructor */
    public Customers(String userName) {
        this.userName = userName;
    }

  
    // Property accessors

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

    public String getUserName() {
        return this.userName;
    }
   
    public void setUserName(String userName) {
        this.userName = userName;
    }

}

 

为Order.java   Bean 去掉cid(CustomerID)并添加一个Customer属性,代码如下:


package fengyan.Hibernate;
/**
 *Authod:    fengyan
 *    date:    2006-12-30 01:02   
 */

public class Orders  implements java.io.Serializable {


    // Fields   

     private Long id;
  //   private Long customersId;
     private String orderDescription;

     //添加一个Customers属性,用来引用一个订单对象所属的客户对象
     private Customers customer;
    // Constructors

    public Customers getCustomer() {
        return customer;
    }


    public void setCustomer(Customers customer) {
        this.customer = customer;
    }


    /** default constructor */
    public Orders() {
    }

    public Orders(String description)
    {
        this.orderDescription = description;
    }
  
    // ProPErty accessors

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

  
    public String getOrderDescription() {
        return this.orderDescription;
    }
   
    public void setOrderDescription(String orderDescription) {
        this.orderDescription = orderDescription;
    }
}
 

 


修改Customer.hbm.XMl映射文件:

<?xML version="1.0" encoding="GBK"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="fengyan.Hibernate.Customers" table="customers" cataLOG="study">
        <id name="id" type="java.lang.Long">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="userName" type="java.lang.String">
            <column name="userName" length="20" />
        </property>
       
        <!-- name集合属性orders   
             table对应的表名   
             casCADe 级联关系,当保存或更新时会级联保存与这个Customers对象相关联的所有Orders对象
             inverse=true是将 控权抛出(给Orders) -->
        <set name="orders" table="orders" cascade="save-update" inverse="true">
            <key column="customers_ID"></key><!-- 表字段 -->       
            <one-to-many class="fengyan.Hibernate.Orders"/><!-- 关联的类 -->
        </set>
    </class>
</hibernate-mapping>

 

修改Order.hbm.xml,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="fengyan.Hibernate.Orders" table="orders" catalog="study">
        <id name="id" type="java.lang.Long">
            <column name="ID" />
            <generator class="native" />
        </id>
      
        <property name="orderDescription" type="java.lang.String">
            <column name="orderDescription" length="50" />
        </property>
       
        <!-- name属性名
             class对应的类
             column对应的表字段 -->
        <many-to-one name="customer" class="fengyan.Hibernate.Customers" column="customers_ID"></many-to-one>
    </class>
</hibernate-mapping>
然后我们建立一个CustomersDAO操作类

package fengyan.Hibernate;

import org.hibernate.Session;
import org.hibernate.Transaction;

public class CustomersDAO {
   
    public void save(Customers customer)
    {
        Session session = HibernateSessionFactory.getSession();//会话
        try
        {
            Transaction tx = session.beginTransaction();//事物
            session.save(customer);//保存
            tx.COMmIT();//提交事物
        }
        catch(Exception e)
        {
            System.out.println("DAO has Errors:"+e);
        }
        finally
        {
            session.close();//关闭会话
        }
    }

}
再来建立一个Servlet     MyServlet.java代码如下:

package fengyan.Hibernate;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //声明一个用户
        Customers customer = new Customers("fengyan");
       
        //声明二订单
        Orders order1 = new Orders("描述1");
        Orders order2 = new Orders("描述2");
       
        //订单关联用户
        order1.setCustomer(customer);
        order2.setCustomer(customer);
       
        //用户关联订单
        customer.getOrders().add(order1);
        customer.getOrders().add(order2);
       
        //save
        CustomersDAO cd = new CustomersDAO();
        cd.save(customer);//我们仅仅保存了Customers!
       
    }
}
最后一个JSP测试页面:

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<html>
  <head>     
    <title>My JSP &#39;index.jsp' starting page</title> 
  </head> 
  <body>
   <br>
   <a href="servlet/MyServlet">add</a>
  </body>
</html>
 

运行效果如下:
Hibernate 表关系描述之OneToMany
我们可以看到,在doGet()方法中,我产仅仅save(customer),并没有save(order)但却执行了三条SQL,由显示的SQL语句我们可以知道,将用户fengyan添加到Customers表中的同时也将 order1及order2添加到Orders表中!
为什么Hibernate会自动帮我们将订单也添加到表中呢,就是我们在Customers.hbm.xml映射配置中,set节点的cascade=save-update,就是当我们保存或更新Customers的时候也会自动保存相应的Orders对象!

当我们现在将 doGet()方法内  订单关联用户的代码注释掉,看一下效果:
Hibernate 表关系描述之OneToMany
从显示的SQL语句看,我们似乎看不出什么区别,但这时如果打开MySQL,会发现:Hibernate 表关系描述之OneToMany

我们发现现在Hiberante帮自动插入的Customers_ID字段为空,为什么会这样的呢,我们不是在下面用


//用户关联订单
  customer.getOrders().add(order1);
  customer.getOrders().add(order2);

不是已经由用户关联了订单吗?这是因为我们在Customers.hbm.xml的set节点中加了属性inverse=true,这句话的意思是将主控制权交出去,具体是什么意思呢?就是在一对多关系中将 主动权交出,具体也就是交给了Orders,也就是用户与订单之间从属关系主要是由Orders对象来确定,也即订单自己来决定它属于哪个对象,所以在这里,我们将    订单关联用户的代码注释掉后,虽然后面 用户关联了订单,但因为用户已经将主动权交出,所以Hibernate在帮我们save订单的时候并不知道订单是属于哪个用户,也自然就在Customers_ID字段填空值了!
那么如果此时我们将Customers.hbm.xml中的 inverse=true去掉是不是就行了呢?带着这样的猜想,我来尝试一下,结果如下图:

 

Hibernate 表关系描述之OneToMany

我们首先查寻数据库发现Hibernate已经正确的将Orders对象持久化到表中了,
Hibernate 表关系描述之OneToMany
 

同时我们看控制台监视的SQL语句,这时我们发现有五条语句,前三条分别是添加一个用户和二条订单,四五条是修改订单的,具体修改什么,我们发现是修改了customers_ID字段,原来这种情况,Hibernate是先将 订单持久化到表中,因为我们注释了订单关联用户的代码,所以Hibernate还是先插入空值,然后再根据我们的 用户关联订单 再来更新Orders表将 Customers_ID字段修改为正确的值!
这个时候我们发现,虽然这样可以,但还是会有一些问题,因为当数据量很大的时候,这样的操作是很占资的,会影响性能,同时如果我们的数据库customers_ID字段定义为not null,非空,那么可想而知这种方式是不可行的!
那么可不可以将inverse=true加上,Customers将主动权交出后,我们仅仅用订单关联用户,而用户关联订单的注释掉呢?我们式式!
运行结果我们发现仅仅是将 用户添加到表中去了,而订单却丢失,这为什么,不是用户将主动权交出,而我们也用订单关联了用户,为何没有加入订单呢,首先要知道,关联是仅仅减缓到订单属于哪个用户,也就是关联订单的customers_ID字段!但用户类里,属性 Set orders = new HashSet();初始是为空的,这样虽然订单关联了用户,但用户对象内的orders属性还是为空,订单还没产生呢,这样Hibernate自然在保存用户的时候,判断集合为空,自然不会去添加订单!这个有点像什么呢,就好比腾讯的QQ宠物里面的所谓“超值大礼包”,每一种礼包我们可以认为是一个订单,而这样的“礼包”一产生也的属于对象,当然就是属于所有拥有QQ宠物的QQ号了!这可以认为上 订单关联了对象,但至于在操作对象的时候,订单有没有,这个其实还是由QQ号码决定的,看它要不要,它如果要了,就有订单,不要呢,当然就没订单了,虽然腾讯希望订单是属于他的!我个人觉得这个比如很恰当!

 

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦! js脚本,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的javascript代码实例教程-Hibernate 表关系描述之OneToMany全部内容,希望文章能够帮你解决javascript代码实例教程-Hibernate 表关系描述之OneToMany所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。