场景: 当一个实体跟另一个实体存在一对一关系时,就可以用hibernate的one-to-one mapping来处理啦。
本教程将会讲解如何用hibernate来解决两个存在1对1关联关系的表之间的级联save问题。
本教程用到的开发工具和技术:
1. Hibernate 3.6.3.Final
2. Oracle 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
3. Apache Maven 3.3.3
4. Eclipse Mars Release (4.5.0)
项目结构:
[img]http://dl2.iteye.com/upload/attachment/0122/8580/8cab1eab-9f6a-36b6-8f46-d7b0b5afaa4d.png[/img]
项目依赖:
pom.xml 文件
1. “One-to-one” 表关联
一对一关系的表设计是指,一个STOCK表中有且仅有一条STOCK_DETAIL记录与其对应, 两个表中都有同样的STOCK_ID作为主健,在STOCK_DETAIL表中STOCK_ID既是主健,同时也作为外键关联到STOCK表的STOCK_ID字段。这就是常见的一对一的表结构设计。
[img]http://dl2.iteye.com/upload/attachment/0122/8584/0395e241-3b62-33d5-b83e-a3f02132bd7c.png[/img]
建表语句:
2. Hibernate的model类
创建两个entity类来对应上面的两张表,分别是Stock.java 和StockDetail.java.
Stock.java 文件:
StockDetail.java
3. Hibernate的mapping文件
创建两个对应的hbm文件,Stock.hbm.xml和StockDetail.hbm.xml
Stock.hbm.xml文件:
StockDetail.hbm.xml 文件:
PS:由于STOCK_DETAIL的的主键和STOCK表示一样的,所以在StockDetail.hbm.xml文件中通过指定generator=foreign来实现表明Stock_detail的主键的由来,并通过指定constrained="true"来限制Stock表的主健一定要存在。
4. Hibernate 的配置文件
将Stock.hbm.xml和StockDetail.hbm.xml配置到Hibernate.cfg.xml文件中。
Hibernate.cfg.xml 文件:
5. 运行
输出结果:
[quote]
Maven + Hibernate One-to-One example + Oracle
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Hibernate: select max(STOCK_ID) from RMMDBA.STOCK
Hibernate: insert into RMMDBA.STOCK (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)
Hibernate: insert into RMMDBA.STOCK_DETAIL (COMP_NAME, COMP_DESC, REMARK, LISTED_DATE, STOCK_ID) values (?, ?, ?, ?, ?)
Done
[/quote]
项目下载链接:
http://dl.iteye.com/topics/download/f244e58d-a147-36c5-a23f-4a0cd32c79b0
本教程将会讲解如何用hibernate来解决两个存在1对1关联关系的表之间的级联save问题。
本教程用到的开发工具和技术:
1. Hibernate 3.6.3.Final
2. Oracle 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
3. Apache Maven 3.3.3
4. Eclipse Mars Release (4.5.0)
项目结构:
[img]http://dl2.iteye.com/upload/attachment/0122/8580/8cab1eab-9f6a-36b6-8f46-d7b0b5afaa4d.png[/img]
项目依赖:
pom.xml 文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.luchenghao.common</groupId>
<artifactId>HibernateExamples</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>HibernateExamples</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.3.Final</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0</version>
</dependency>
</dependencies>
</project>
1. “One-to-one” 表关联
一对一关系的表设计是指,一个STOCK表中有且仅有一条STOCK_DETAIL记录与其对应, 两个表中都有同样的STOCK_ID作为主健,在STOCK_DETAIL表中STOCK_ID既是主健,同时也作为外键关联到STOCK表的STOCK_ID字段。这就是常见的一对一的表结构设计。
[img]http://dl2.iteye.com/upload/attachment/0122/8584/0395e241-3b62-33d5-b83e-a3f02132bd7c.png[/img]
建表语句:
CREATE TABLE "CLUDBA"."STOCK" (
"STOCK_ID" NUMBER NOT NULL ENABLE,
"STOCK_CODE" VARCHAR2(10 BYTE) NOT NULL ENABLE,
"STOCK_NAME" VARCHAR2(20 BYTE ) NOT NULL ENABLE,
CONSTRAINT "STOCK_PK" PRIMARY KEY ("STOCK_ID")
);
--
-- Definition of table "stock_detail"
--
CREATE TABLE "CLUDBA"."STOCK_DETAIL" (
"STOCK_ID" NUMBER(10) NOT NULL ,
"COMP_NAME" VARCHAR2(100) NOT NULL,
"COMP_DESC" VARCHAR2(255) DEFAULT NULL,
"REMARK" VARCHAR2(255) DEFAULT NULL,
"LISTED_DATE" date NOT NULL,
PRIMARY KEY ("STOCK_ID"),
CONSTRAINT "FK_STOCK_ID" FOREIGN KEY ("STOCK_ID") REFERENCES "STOCK" ("STOCK_ID")
);
2. Hibernate的model类
创建两个entity类来对应上面的两张表,分别是Stock.java 和StockDetail.java.
Stock.java 文件:
public class Stock {
private Integer stockId;
private String stockCode;
private String stockName;
private StockDetail stockDetail;
//getter和setter
}
StockDetail.java
public class StockDetail {
private Integer stockId;
private Stock stock;
private String compName;
private String compDesc;
private String remark;
private Date listedDate;
//getter和setter
}
3. Hibernate的mapping文件
创建两个对应的hbm文件,Stock.hbm.xml和StockDetail.hbm.xml
Stock.hbm.xml文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 25 April 2011 7:52:33 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.luchenghao.domain.Stock" table="STOCK">
<id name="stockId" type="java.lang.Integer">
<column name="STOCK_ID" />
<generator class="increment" />
</id>
<property name="stockCode" type="string">
<column name="STOCK_CODE" length="10" not-null="true" unique="true" />
</property>
<property name="stockName" type="string">
<column name="STOCK_NAME" length="20" not-null="true" unique="true" />
</property>
<one-to-one name="stockDetail" class="com.luchenghao.domain.StockDetail"
cascade="save-update"></one-to-one>
</class>
</hibernate-mapping>
StockDetail.hbm.xml 文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 25 April 2011 7:52:33 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.luchenghao.domain.StockDetail" table="STOCK_DETAIL">
<id name="stockId" type="java.lang.Integer">
<column name="STOCK_ID" />
<generator class="foreign">
<param name="property">stock</param>
</generator>
</id>
<one-to-one name="stock" class="com.luchenghao.domain.Stock"
constrained="true"></one-to-one>
<property name="compName" type="string">
<column name="COMP_NAME" length="100" not-null="true" />
</property>
<property name="compDesc" type="string">
<column name="COMP_DESC" not-null="true" />
</property>
<property name="remark" type="string">
<column name="REMARK" not-null="true" />
</property>
<property name="listedDate" type="date">
<column name="LISTED_DATE" length="10" not-null="true" />
</property>
</class>
</hibernate-mapping>
PS:由于STOCK_DETAIL的的主键和STOCK表示一样的,所以在StockDetail.hbm.xml文件中通过指定generator=foreign来实现表明Stock_detail的主键的由来,并通过指定constrained="true"来限制Stock表的主健一定要存在。
4. Hibernate 的配置文件
将Stock.hbm.xml和StockDetail.hbm.xml配置到Hibernate.cfg.xml文件中。
Hibernate.cfg.xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- a SessionFactory instance listed as /jndi/name -->
<session-factory>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:@hz2dw3207:1521:O07CAB</property>
<property name="hibernate.connection.username">RMMDBA</property>
<property name="hibernate.connection.password">RMMDBA</property>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="hibernate.default_schema">RMMDBA</property>
<property name="show_sql">true</property>
<mapping resource="com/luchenghao/domain/Stock.hbm.xml"></mapping>
<mapping resource="com/luchenghao/domain/StockDetail.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
5. 运行
package com.luchenghao.common;
import java.util.Date;
import org.hibernate.Session;
import com.luchenghao.domain.Stock;
import com.luchenghao.domain.StockDetail;
import com.luchenghao.util.HibernateUtil;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println("Maven + Hibernate One-to-One example + Oracle");
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Stock stock = new Stock();
stock.setStockCode("4715");
stock.setStockName("GENM");
StockDetail stockDetail = new StockDetail();
stockDetail.setCompName("GENTING Malaysia");
stockDetail.setCompDesc("Best resort in the world");
stockDetail.setRemark("Nothing Special");
stockDetail.setListedDate(new Date());
stock.setStockDetail(stockDetail);
stockDetail.setStock(stock);
session.save(stock);
session.getTransaction().commit();
System.out.println("Done");
}
}
输出结果:
[quote]
Maven + Hibernate One-to-One example + Oracle
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Hibernate: select max(STOCK_ID) from RMMDBA.STOCK
Hibernate: insert into RMMDBA.STOCK (STOCK_CODE, STOCK_NAME, STOCK_ID) values (?, ?, ?)
Hibernate: insert into RMMDBA.STOCK_DETAIL (COMP_NAME, COMP_DESC, REMARK, LISTED_DATE, STOCK_ID) values (?, ?, ?, ?, ?)
Done
[/quote]
项目下载链接:
http://dl.iteye.com/topics/download/f244e58d-a147-36c5-a23f-4a0cd32c79b0