Hibernate 一对一关系(基于XML)

场景: 当一个实体跟另一个实体存在一对一关系时,就可以用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)

项目结构:



项目依赖:
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字段。这就是常见的一对一的表结构设计。



建表语句:
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");
    }
}




输出结果:

引用

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



项目下载链接:
http://dl.iteye.com/topics/download/f244e58d-a147-36c5-a23f-4a0cd32c79b0

猜你喜欢

转载自xfxlch.iteye.com/blog/2355299