一、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>
理解级联的含义?
* 是对象的连锁操作