一、单向多对一关联映射:以产品和生产商关系为例
单向关联:在实体类中,将一的一方(如生产商)定义为多的一方的一个属性,在多的一方映射文件中使用many-to-one
在Product映射的表中建立外键factoryId外键关联类Factory的映射表的主键factoryId
1.Product.hbm.xml文件配置(实体类添加属性: private Factory factory;)
<hibernate-mapping> <class name="com.cong.domain.Product" table="tb_product"> <id name="id" column="id" type="int"> //id <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.cong.domain.Factory"> //多对一关联映射 <column name="factoryId"></column> //映射字段 </many-to-one> </class> </hibernate-mapping>
<many-to-one>元素:定义一个持久化类与另一个持久化类的关联,是数据表间的多对一关联
需要此持久化类映射表的外键引用另一个持久化类映射表的主键,即关联字段
name属性的值是持久化类中的属性,class属性就是关联的目标持久化类
2.Factory.hbm.xml文件配置
<hibernate-mapping> <class name="com.cong.domain.Factory" table="tb_factory"> <id name="factoryId" column="factoryId" type="int"> //id <generator class="native"/> //主键生成策略 </id> <property name="factoryName" type="string" length="45"> //生产商名称 <column name="factoryName"/> </property> </class> </hibernate-mapping>
注:单向多对一关联,只能通过主控方对被控方进行级联更新;
例如:想要获取某件商品的生产商信息(被控),需要先加载该产品的持久化对象(主控)
通过产品持久化对象访问生产商的属性,反过来无法获取
测试方法代码段:
public void Test(){ Session session = null; Transaction tx=null; try { session = HibernateUtil.getSessionFactory().getCurrentSession(); //通过HibernateUtil工具类获得当前session tx=session.beginTransaction(); Product product = (Product) session.get(Product.class, new Integer("1")); //使用get方法主键查询数据 System.out.println("产品名称:"+product.getName()); System.out.println("产品价格:"+product.getPrice()+"元"); System.out.println("生产商:"+product.getFactory().getFactoryName()); tx.commit(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); tx.rollback(); }finally { if(tx != null){ tx=null; } } }
二、多对一双向关联
双向关联:在实体类中,将一的一方(如生产商)定义为多的一方(如产品)的一个属性,同时
在一的一方定义一个集合类型(Set类型)的属性。多的一方使用<many-to-one>元素,在一的一方使用
<set>元素及其子元素<one-to-many>.
1.Factory.hbm.xml文件配置(实体类添加:private Set<Product> products;)
<hibernate-mapping> <class name="com.cong.domain.Factory" table="tb_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"> //设置Set集合属性inverse指定关联关系的控制方向,默认由one方来维护关联关系,为true表示由多方进行关联关系维护 <key column="factoryId"/> //外键字段名称 <one-to-many class="com.cong.domain.Product"/> </set> </class> </hibernate-mapping>
2.Product.hbm.xml文件配置与单向多对一的配置一样(上方已经配置)
注:双向多对一的关联,既可以通过主控方实体加载被控方实体,同时也可以通过被控方加载主控方实体
测试方法代码段:
public void Test2(){ Session session = null; Transaction tx=null; try { session = HibernateUtil.getSessionFactory().getCurrentSession(); //通过HIbernateUtil工具类获取当前session tx=session.beginTransaction(); //开启事务 Product product = (Product) session.get(Product.class, new Integer("1")); //主键查询记录 // Factory factory = (Factory) session.get(Factory.class, new Integer("1")); // // System.out.println("生产商:"+factory.getFactoryName()); // // Set<Product> products = factory.getProducts(); // for (Iterator<Product> iterator2 = products.iterator(); iterator2.hasNext();) { // Product product2 = (Product) iterator2.next(); // System.out.println("产品名称:"+product2.getName()); // System.out.println("产品价格:"+product2.getPrice()+"元"); // } System.out.println("产品名称:"+product.getName()); System.out.println("产品价格:"+product.getPrice()+"元"); System.out.println("生产商:"+product.getFactory().getFactoryName()); tx.commit(); } catch (Exception e) { e.printStackTrace(); tx.rollback(); }finally { if(tx != null){ tx=null; } } }