只要你肯努力,没有什么事情是你不能搞砸的。



需求:一个汽车(Car)有一个引擎(Engine),它是一对一的映射关系。

对于一对一的映射,有两种实现方式:基于外键的映射和基于主键的映射。这两种方式学习的重点就是映射文件的配置,推荐使用第一种方式。

1、基于外键的映射

Car.java

package com.rk.hibernate.k_one2one;

public class Car
{
	private int carId;
	private String carName;
	private Engine engine;
	public int getCarId()
	{
		return carId;
	}
	public void setCarId(int carId)
	{
		this.carId = carId;
	}
	public String getCarName()
	{
		return carName;
	}
	public void setCarName(String carName)
	{
		this.carName = carName;
	}
	public Engine getEngine()
	{
		return engine;
	}
	public void setEngine(Engine engine)
	{
		this.engine = engine;
	}
	@Override
	public String toString()
	{
		return "Car [carId=" + carId + ", carName=" + carName + "]";
	}
	
}

Car.hbm.xml,注意many-to-one的映射

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.rk.hibernate.k_one2one" auto-import="true">
	<class name="Car" table="T_Car">
		<id name="carId" column="id">
			<generator class="native"></generator>
		</id>
		<property name="carName" column="name"></property>
		<!-- 
			一对一映射,有外键方
			unique="true"   给外键字段添加唯一约束
		 -->		
		<many-to-one name="engine" column="engineId" class="Engine" unique="true"></many-to-one>
	</class>
</hibernate-mapping>

Engine.java

package com.rk.hibernate.k_one2one;

public class Engine
{
	private int engineId;
	private String engineName;
	private Car car;
	public int getEngineId()
	{
		return engineId;
	}
	public void setEngineId(int engineId)
	{
		this.engineId = engineId;
	}
	public String getEngineName()
	{
		return engineName;
	}
	public void setEngineName(String engineName)
	{
		this.engineName = engineName;
	}
	public Car getCar()
	{
		return car;
	}
	public void setCar(Car car)
	{
		this.car = car;
	}
	@Override
	public String toString()
	{
		return "Engine [engineId=" + engineId + ", engineName=" + engineName + "]";
	}
	
}

Engine.hbm.xml,注意one-to-one映射

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.rk.hibernate.k_one2one" auto-import="true">
	<class name="Engine" table="T_Engine">
		<id name="engineId" column="id">
			<generator class="native"></generator>
		</id>
		<property name="engineName" column="name" type="string" length="20"/>
		<!-- 
			一对一映射: 没有外键方
		 -->
		<one-to-one name="car" class="Car"></one-to-one>
	</class>
</hibernate-mapping>

App.java

package com.rk.hibernate.k_one2one;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class App
{
	private static SessionFactory sf;
	static
	{
		sf = new Configuration()
						.configure()
						.addClass(Car.class)
						.addClass(Engine.class)
						.buildSessionFactory();
	}
	
	@Test
	public void testSave()
	{
		int i = 2;
		Session session = sf.openSession();
		session.beginTransaction();
		
		//引擎
		Engine engine = new Engine();
		engine.setEngineName("Super Engine" + i);
		//汽车
		Car car = new Car();
		car.setCarName("BMW" + i);
		car.setEngine(engine); //汽车和引擎的关系
		
		session.save(engine);
		session.save(car);
		
		session.getTransaction().commit();
		session.close();
	}
	
	@Test
	public void testGet()
	{
		Session session = sf.openSession();
		session.beginTransaction();
		
//		Car car = (Car)session.get(Car.class, 2);
//		System.out.println(car);
//		Engine engine = car.getEngine();
//		System.out.println(engine);
		
		Engine e2 = (Engine)session.get(Engine.class, 3);
		System.out.println(e2);
		Car c2 = e2.getCar();
		System.out.println(c2);
		
		session.getTransaction().commit();
		session.close();
	}
	
}



2、基于主键的映射

Car.java

package com.rk.hibernate.l_one2one_primarykey;

public class Car
{
	private int carId;
	private String carName;
	private Engine engine;
	public int getCarId()
	{
		return carId;
	}
	public void setCarId(int carId)
	{
		this.carId = carId;
	}
	public String getCarName()
	{
		return carName;
	}
	public void setCarName(String carName)
	{
		this.carName = carName;
	}
	public Engine getEngine()
	{
		return engine;
	}
	public void setEngine(Engine engine)
	{
		this.engine = engine;
	}
	@Override
	public String toString()
	{
		return "Car [carId=" + carId + ", carName=" + carName + "]";
	}
	
}

Car.hbm.xml,注意one-to-one配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.rk.hibernate.l_one2one_primarykey" auto-import="true">
	<class name="Car" table="T_Car2">
		<id name="carId" column="id">
			<generator class="native"></generator>
		</id>
		<property name="carName" column="name"></property>
		<!-- 
			一对一映射
		 -->
		<one-to-one name="engine" class="Engine"></one-to-one>
	</class>
</hibernate-mapping>

Engine.java,注意当前类的carId属性是T_Engine2表的主键,也是T_Car2的外键。

package com.rk.hibernate.l_one2one_primarykey;

public class Engine
{
	private int carId;
	private String engineName;
	private Car car;
	public int getCarId()
	{
		return carId;
	}
	public void setCarId(int carId)
	{
		this.carId = carId;
	}
	public String getEngineName()
	{
		return engineName;
	}
	public void setEngineName(String engineName)
	{
		this.engineName = engineName;
	}
	public Car getCar()
	{
		return car;
	}
	public void setCar(Car car)
	{
		this.car = car;
	}
	@Override
	public String toString()
	{
		return "Engine [carId=" + carId + ", engineName=" + engineName + "]";
	}
}

Engine.hbm.xml,注意id和one-to-one的配置。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.rk.hibernate.l_one2one_primarykey" auto-import="true">
	<class name="Engine" table="T_Engine2">
		<id name="carId" column="car_id">
			<!-- 
				id 节点指定的是主键映射, 即car_id是主键
				主键生成方式: foreign  即把别的表的主键作为当前表的主键;
						property (关键字,不能修改)指定引用的对象
			 -->
			<generator class="foreign">
				<param name="property">car</param>
			</generator>
		</id>
		<property name="engineName" column="name" type="string" length="20"/>
		<!-- 
			一对一映射,有外键方
			(基于主键的映射)
			 constrained="true"  指定在主键上添加外键约束
		 -->		
		<one-to-one name="car" class="Car" constrained="true"></one-to-one>
	</class>
</hibernate-mapping>

App.java

package com.rk.hibernate.l_one2one_primarykey;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class App
{
	private static SessionFactory sf;
	static
	{
		sf = new Configuration()
						.configure()
						.addClass(Car.class)
						.addClass(Engine.class)
						.buildSessionFactory();
	}
	
	@Test
	public void testSave()
	{
		int i = 0;
		Session session = sf.openSession();
		session.beginTransaction();
		
		//汽车
		Car car = new Car();
		car.setCarName("BMW" + i);
		//引擎
		Engine engine = new Engine();
		engine.setEngineName("Super Engine" + i);
		engine.setCar(car);
		
		session.save(car);
		session.save(engine);
		
		session.getTransaction().commit();
		session.close();
	}
	
	@Test
	public void testGet()
	{
		Session session = sf.openSession();
		session.beginTransaction();
		
		Car car = (Car)session.get(Car.class, 1);
		System.out.println(car);
		Engine engine = car.getEngine();
		System.out.println(engine);
		
//		Engine e2 = (Engine)session.get(Engine.class, 1);
//		System.out.println(e2);
//		Car c2 = e2.getCar();
//		System.out.println(c2);
		
		session.getTransaction().commit();
		session.close();
	}
	
}