五、hibernate多对一(双向关联)

一、Hibernate多对一单向关联关系

(1)实体类与表间的关系

Product              Factory                 tab_product         tab_factory

-id:int              -factoryId:int           id                 factoryid

-name:string         -factoryName:string      name               name

-price:double                                 price

-factory:Factory                              factoryid

-Set<Product>:products

 

(2)、创建表语句

CREATE TABLE `tab_factory` (
  `factoryid` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `factoryname` varchar(45) NOT NULL COMMENT '生产商名称',
  PRIMARY KEY (`factoryid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

INSERT INTO `tab_factory` (`factoryid`,`factoryname`) VALUES
 (1,'明日科技'),
 (2,'明日*****');

CREATE TABLE `tab_product` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL COMMENT '产品名称',
  `price` double NOT NULL COMMENT '产品价格',
  `factoryid` int(10) unsigned NOT NULL COMMENT '关联的产品信息id',
  PRIMARY KEY (`id`),
  KEY `FK_tab_product` (`factoryid`),
  CONSTRAINT `FK_tab_product` FOREIGN KEY (`factoryid`) REFERENCES `tab_factory` (`factoryid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

INSERT INTO `tab_product` (`id`,`name`,`price`,`factoryid`) VALUES
 (1,'Java Web编程宝典',79,1),
 (2,'Java编程宝典',79,1),
 (3,'测试数据',88,1),
 (4,'编程词典',368,2);

 

(3)、创建实体类与映射文件

Factory.java

public class Factory {
   
    private Integer factoryId;//生产商的id

    private String factoryName;//生产商名称

    private Set<Product2> products;//Set集合,一个厂商所对应的所有图书
   
    public void Product2(){
       
    }

   //省略set、get方法

}

Product.java

public class Product {
    private Integer id;//唯一性标识
    private String name;//产品名称
    private Double price;//产品价格
    private Factory factory;//关联的生产商
    public Product() {
    }

    //省略set、get方法

}

Factory.hbm.xml
 <hibernate-mapping>
     <class name="com.keli.pojo.Factory" table="tab_factory">
         <id name="factoryId" column="factoryid" type="int">
            <generator class="native"/>
        </id>
        <property name="factoryName" type="string" length="45">
            <column name="factoryname"/>
        </property>

         <!-- 定义一对多映射 -->
        <set name="products"
             inverse="true">
            <key column="factoryid"/>
            <one-to-many class="com.keli.pojo.Product2"/>
        </set>    

     </class>
 </hibernate-mapping>

Product.hbm.xml

 <hibernate-mapping>
     <class name="com.keli.pojo.Product" table="tab_product">
         <id name="id" column="id" type="int">
            <generator class="native"/>
        </id>
        <property name="name" type="string" length="45">
            <column name="name"/>
        </property>
        <property name="price" type="double">
            <column name="price"/>
        </property>
        <!-- 多对一关联映射 -->
        <many-to-one name="factory" class="com.keli.pojo.Factory">
            <!-- 映射的字段 -->
            <column name="factoryid"/>

        </many-to-one>
     </class>
 </hibernate-mapping>

 

代码导读:

  控制方向反转:将“inverse”属性设置为“true”,表示Factory对象不再是主控方,而将关联关系的维护交给对象类的Product来维护,在Product对象持久化的时候会主动获取关联的类Factory 的id。

  关联的id:这时设置的关联id指的是Product对象中所关联的Factory对象的id,并不是Product对象自己的id。

 

五、测试

//多对一双向关联

public class TestMany2one2 extends TestCase {
    public void testSave1(){
        Session session = null;
        try{
            session = HibernateInitialize.getSession();
            session.beginTransaction();
            Factory factory = new Factory();
            factory.setFactoryName("神舟数码");
          
            Product product1 = new Product();
            product1.setName("手机");
            product1.setPrice(200.0);
            product1.setFactory(factory);
          
            Product product2 = new Product();
            product2.setName("电脑");
            product2.setPrice(2000.0);
            product2.setFactory(factory);
          
            //不能保存Column 'factoryid' cannot be null
            session.save(product1);
            session.save(product2);
            session.getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateInitialize.closeSession();
        }
    }
  
    public void testSave2(){
        Session session = null;
        try{
            session = HibernateInitialize.getSession();
            session.beginTransaction();
            Factory factory = new Factory();
            factory.setFactoryName("华为");
            session.save(factory);
          
            Product product1 = new Product();
            product1.setName("手机");
            product1.setPrice(200.0);
            product1.setFactory(factory);
          
            Product product2 = new Product();
            product2.setName("电脑");
            product2.setPrice(2000.0);
            product2.setFactory(factory);
            //可以正确存储
            session.save(product1);
            session.save(product2);
            session.getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateInitialize.closeSession();
        }
    }

    public void testSave3(){
        Session session = null;
        try{
            session = HibernateInitialize.getSession();
            session.beginTransaction();
            Factory factory = new Factory();
            factory.setFactoryName("富士康");
          
            Product product1 = new Product();
            product1.setName("手机");
            product1.setPrice(200.0);
            product1.setFactory(factory);
          
            Product product2 = new Product();
            product2.setName("电脑");
            product2.setPrice(2000.0);
            product2.setFactory(factory);
          
            //不会抛出异常,因为采用了cascade属性,所以它会先保存Factory
            //采用cascade属性是解决TransientObjectException异常的一种手段
            //<many-to-one name="factory" class="com.keli.pojo.Factory1" cascade="all">
            session.save(product1);
            session.save(product2);
            session.getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateInitialize.closeSession();
        }
    }

  
    public void testLoad1() {
        Session session = null;
        try{
            session = HibernateInitialize.getSession();
            session.beginTransaction();
            Product product = (Product2) session.get(Product.class, new Integer(24));
            System.out.println("产品名称:"+product.getName());
            System.out.println("产品价格:"+product.getPrice()+"元");
            System.out.println("生产商:"+product.getFactory().getFactoryName());
            session.getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateInitialize.closeSession();
        }
    }
   
    public void testLoad2() {
        Session session = null;
        try{
            session = HibernateInitialize.getSession();
            session.beginTransaction();
            Factory factory = (Factory) session.get(Factory.class, new Integer(12));
           
            System.out.println("生产商:"+factory.getFactoryName());
           
            for(Iterator<Product> iter =factory.getProducts().iterator();iter.hasNext();){
                Product product = (Product) iter.next();
                System.out.println("产品名称:"+product.getName());
                System.out.println("产品价格:"+product.getPrice()+"元");
            }
            session.getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateInitialize.closeSession();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值