一、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();
}
}
}