四、Hibernate多对一关联有关系(单向关联)

来源:互联网 发布:dc电视剧 知乎 编辑:程序博客网 时间:2024/05/21 21:43

一、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

 

(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;// 生产商名称

    public Factory() {
    }

    //省略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>
     </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>

 

代码导读

<many-to-one>元素:定义一个持久化类与另一个持久化类的关联,这种关联是数据库表间的多对一关联,需要此持久化类映射表的外键引用另一个持久化类映射表的主键,也就是映射的字段,其中,“name”属性的值是持久化类中的属性,“class”属性就关联的目标持久化类。

 

(4)、测试

public void testSave1(){
        Session session = null;
        try{
            session = HibernateInitialize.getSession();
            session.beginTransaction();
            Factory factory = new Factory();
            factory.setFactoryName("富士康");
           
            Product product = new Product();
            product1.setName("手机");
            product1.setPrice(200.0);
            product1.setFactory(factory);
           
            Product product2 = new Product();
            product2.setName("电脑");
            product2.setPrice(2000.0);
            product2.setFactory(factory);
           
            //不能成功保存,抛出TransientObjectException异常
            //因为Factory为Tran    sient状态,oid没有分配值
            //persistent状态的对象是不能引用transient状态的对象的
            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();
            Product1 product = (Product1) session.get(Product1.class, new Integer(8));
            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();
        }
    }

 

说明:

hibernate多对一关联映射

关联映射的本质:
    * 将关联关系映射到数据库,所谓的关联关系是对象模型在内存中的一个或多个引用

<many-to-one>会在多的一端加入一个外键,指向一的一端,这个外键是由<many-to-one>
中的column属性定义的,如果忽略了这个属性那么默认的外键与实体的属性一致

<many-to-one>标签的定义示例:
     * <many-to-one name="factory" column="factoryid"/>


     *   <many-to-one name="factory" class="com.keli.pojo.Factory">
            <!-- 映射的字段 -->
             <column name="factoryid"/>

          </many-to-one>
理解级联的含义?
    * 是对象的连锁操作     
        

原创粉丝点击