主键映射和Hibernate映射

组件映射

类组合关系的映射,也叫做组件映射!

  注意:组件类和被包含的组件类,共同映射到一张表!

  需求: 如汽车与车轮

代码示例:

1、JavaBean

Wheel.java

package com.gqx.component;
/**
 * 车轮
 * @author 郭庆兴
 *
 */
public class Wheel {
	private int count;
	private int size;
	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
	}
	public int getSize() {
		return size;
	}
	public void setSize(int size) {
		this.size = size;
	}

}

Car.java

package com.gqx.component;

public class Car {
	private int id;
	private String brand;
	//车轮
	private Wheel wheel;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getBrand() {
		return brand;
	}
	public void setBrand(String brand) {
		this.brand = brand;
	}
	public Wheel getWheel() {
		return wheel;
	}
	public void setWheel(Wheel wheel) {
		this.wheel = wheel;
	}

}

2、映射文件

<?xml version="1.0"?>
<!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.gqx.component">

	<class name="Car" table="t_car" >
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="brand" length="20"></property>

		<!-- 组件映射 -->
		<component name="wheel">
			<property name="count"></property>
			<property name="size"></property>
		</component>
	</class>
</hibernate-mapping>

3、测试程序

package com.gqx.component;

import static org.junit.Assert.*;

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

import com.gqx.collection.User;

public class App {
	private static SessionFactory sf;
	static{
		sf=new Configuration().configure()
				.addClass(Car.class)
				.buildSessionFactory();
	}
	@Test
	public void test() {
		Session session=sf.openSession();
		session.beginTransaction();

		//轮子
		Wheel wheel=new Wheel();
		wheel.setCount(4);
		wheel.setSize(40);
		//汽车
		Car car=new Car();
		car.setBrand("BMW");
		car.setWheel(wheel);
		//保存
		session.save(car);
		session.getTransaction().commit();
		session.close();
	}

}

继承映射

  如:父类——动物

      子类:猫,猴子

1、JavaBean文件

Animal.java

package com.gqx.extends1;
/**
 * 动物类
 * @author 郭庆兴
 *
 */
public abstract class Animal {
	private int id;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

Cat.java

package com.gqx.extends1;

public class Cat extends Animal {
	//抓老鼠
	private String catchMouse;

	public String getCatchMouse() {
		return catchMouse;
	}

	public void setCatchMouse(String catchMouse) {
		this.catchMouse = catchMouse;
	}

}

Monkey.java

package com.gqx.extends2;

public class Monkey extends Animal{
	//吃香蕉
	private String eatBanana;

	public String getEatBanana() {
		return eatBanana;
	}

	public void setEatBanana(String eatBanana) {
		this.eatBanana = eatBanana;
	}

}

2、映射文件

简单继承映射

<?xml version="1.0"?>
<!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.gqx.extends1">

	<class name="Cat" table="t_cat" >
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="catchMouse" length="20"></property>
		<property name="name" length="20"></property>
	</class>
</hibernate-mapping>

3、测试文件

package com.gqx.extends1;

import static org.junit.Assert.*;

import java.util.List;

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

import com.gqx.collection.User;

public class App {
	private static SessionFactory sf;
	static{
		sf=new Configuration().configure()
				.addClass(Cat.class)
				.buildSessionFactory();
	}
	@Test
	public void test() {
		Session session=sf.openSession();
		session.beginTransaction();

		Cat cat=new Cat();
		cat.setName("龙猫");
		cat.setCatchMouse("抓小老鼠");

		session.save(cat);

		session.getTransaction().commit();
		session.close();
	}

	@Test
	public void testGet() {
		Session session=sf.openSession();
		session.beginTransaction();

//		Query q=session.createQuery("from Cat");
//		List<Cat> list=q.list();
//		如果通过父类查询,需要说明包
		Query q=session.createQuery("from com.gqx.extends1.Cat");
		List<Animal> list=q.list();
		System.out.println(list);

		session.getTransaction().commit();
		session.close();
	}

}

映射文件也可以分为三种类型去实现

一、所有子类映射到一张表 (1张表)

什么情况用?

子类教多,且子类较为简单,即只有个别属性!

好处:因为使用一个映射文件, 减少了映射文件的个数。

缺点:(不符合数据库设计原则)

  一个映射文件: Animal.hbm.xml

<?xml version="1.0"?>
<!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.gqx.extends2">

	<class name="Animal" table="t_animal" >
		<id name="id">
			<generator class="native"></generator>
		</id>
		<!-- 指定鉴别器字段(区分不同的子类) -->
		<discriminator column="type_"></discriminator>
		<property name="name" length="20"></property>

		<!-- 每个子类都用subclass映射
			 注意:一定要指定鉴别器字段,否则报错!
			 鉴别器字段:作用是在数据库中区别每一个子类信息,就是一个列的信息
		 -->
		<!-- 子类:猫
			 discriminator-value:
			 指定鉴别器字段,即type_字段的值
			 如果不指定,默认为当前子类的全名
		-->
		<subclass name="Cat" discriminator-value="cat_">
			<property name="catchMouse"></property>
		</subclass>
		<!-- 子类:狗 -->
		<subclass name="Monkey" discriminator-value="monkey_">
			<property name="eatBanana"></property>
		</subclass>
	</class>
</hibernate-mapping>

结果如图:

总结:

写法较为简单:所有子类用一个映射文件,且映射到一张表!

但数据库设计不合理!

二、每个类映射一张表(3张表)

数据库

T_anmal (存储父类信息)

T_cat (引用父类的主键)

T_monkey(引用父类的主键)

映射文件

<?xml version="1.0"?>
<!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.gqx.extends3">

	<class name="Animal" table="t_animal" >
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name" length="20"></property>

		<!--
			子类:猫 t_cat
			key:指定cat表的外键字段
		 -->
		 <joined-subclass name="Cat" table="t_cat">
		 	<key column="t_animal_id"></key>
		 	<property name="catchMouse"></property>
		 </joined-subclass>

		 <!--
			子类:猴子 t_monkey
		 -->
		 <joined-subclass name="Monkey" table="t_monkey">
		 	<key column="t_animal_id"></key>
		 	<property name="eatBanana"></property>
		 </joined-subclass>
	</class>
</hibernate-mapping>

总结:

一个映射文件,存储所有的子类; 子类父类都对应表;

缺点:表结构比较负责,插入一条子类信息,需要用2条sql: 往父类插入、往子类插入!

三、(推荐)每个子类映射一张表, 父类不对应表(2张表)

这个时候要把Animal类的id改一下

private String id;

映射文件

<?xml version="1.0"?>
<!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.gqx.extends4">
	<!--
		abstract="true" 指定实体对象不对应表,即在数据库端不生成表
	 -->
	<class name="Animal" abstract="true">
		<!-- 如果用union-subclass节点,主键生成策略不能为自增长 -->
		<id name="id">
			<generator class="uuid"></generator>
		</id>
		<property name="name" length="20"></property>

		<!--
			union-subclass
			table	指定为表名,表的主键即为id列
		 -->
		<!-- 子类:猫 t_cat-->
		 <union-subclass name="Cat" table="t_cat">
		 	<property name="catchMouse"></property>
		 </union-subclass>
		 <!-- 子类:猴子 t_monkey-->
		 <union-subclass name="Monkey" table="t_monkey">
		 	<property name="eatBanana"></property>
		 </union-subclass>
	</class>
</hibernate-mapping>
时间: 2024-10-12 17:08:57

主键映射和Hibernate映射的相关文章

Hibernate(5)—— 联合主键 、一对一关联关系映射(xml和注解) 和 领域驱动设计

俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: One to One 映射关系 一对一单向外键(XML/Annotation) 一对一双向外键关联(XML/Annotation) 联合主键 一对一单向外键联合主键(Xml/Annotation) 一对一组件关联(XML/Annotation) 理解组件 领域驱动设计——自动生成数据库脚本 一对一关系的小结 一些出错问题的总结 自动生成数据库脚本 一般在项目开发过程中,我们的习惯是先建好数据库和表,然后在进

hibernate关联映射【一对一主键】

从三个部分介绍Hibernate一对一主键关联映射. 1.基本介绍2.代码展示3.总结注意  1.基本介绍 一对一关联有两种情况: 单向一对一主键关联.双向一对一主键关联.一对一主键关联: 是指两个表之间通过主键形成一对一的映射,例如,每个公民只允许拥有一个身份证,公民与身份证就是一对一的关系,定义两张表,一张People表,一张IdCard表,People表的id既是该表的主键也是该表的外键,并且People的id也就是IdCard的id, 2.代码 单向一对一主键关联:people表的id既

hibernate笔记--基于主键的单(双)向的一对一映射关系

上一节介绍的基于外键的一对一映射关系中,在Person表中有一个外键列idCard_id,对应的idCard表的主键id,至于基于主键的一对一映射关系,就是指Person表中抛弃了idcard_id这个外键列,而与idCard表共用一个主键,或者说是其外键为主键的表结构,这种基于主键的双向一对一映射关系应该这样配置: 新建一个IdCard实体类: public class IdCard { private int id; private String code; private Person p

hibernate中基于主键映射1-1关联关系和基于外键映射1-1关联关系的不同

基于主键映射1-1关联关系和基于外键映射1-1关联关系的不同,主要区别是在配置映射文件上会有区别 两个持久化类为Manager和Department 1:基于主键映射1-1关联关系 1)使用其他持久化类的主键生成主键的实体的映射文件 首先需要指定主键生成方式为foreigner 格式为: <id name="departmentId" type="java.lang.Integer"> <column name="department_i

Hibernate 查询排序与联合主键映射

1.查询排序 (1)数据库排序(推荐) <map order-by="name ase" > <!--name的升序,降序desc--> session.createQuery(" ").uniqueResult() //返回唯一的对象,前台对象只有一个 <set order-by="name asc"> (2)内存排序 <set sort="natural" > sort属性值

Hibernate 表映射 主键生成策略与复合主键

主要分析三点: 一.数据表和Java类的映射 : 二.单一主键映射和主键的生成策略 : 三.复合主键的表映射 : 一.数据表和Java类的映射  Hibernate封装了数据库DDL语句,只需要将数据表和类之间实现映射,即可对数据表进行操作. 示例:数据库中存在表interface_admin.ds_area,实现表和类之间映射,其中单一主键oggKeyId,使用主键自动生成策略UUID,具体第二点进行阐述 . package com.pec.model; import java.io.Seri

Hibernate复合主键映射

目录: 1. 实现方式一:将复合主键对应的属性与实体其他普通属性放在一起 2. 实现方式二:将主键属性提取到一个主键类中,实体类只需包含主键类的一个引用 在日常开发中会遇到这样一种情况,数据库中的某张表需要多个字段列才能唯一确定一行记录,这时表需要使用复合主键.面对这样的情况Hibernate为我们提供了两种方式来解决复合主键问题. 方式一:将复合主键对应的属性与实体其他普通属性放在一起 例如实体类People中"id"和"name"属性对应复合主键: /*实体类,

联合主键的映射运用

1.联合主键的映射规则 1) 类中的每个主键属性都对应到数据表中的每个主键列. Hibernate要求具有联合主键的实体类实现Serializable接口,并且重写hashCode与equals方法,重写这两个方法的原因在于Hibernate要根据数据库的联合主键来判断某两行记录是否是一样的,如果一样那么就认为是同一个对象,如果不一样,那么就认为是不同的对象.这反映到程序领域中就是根据hashCode与equals方法来判断某两个对象是否能够放到诸如Set这样的集合当中.联合主键的实体类实现Se

主键映射

目录: 1. 实现方式一:将复合主键对应的属性与实体其他普通属性放在一起 2. 实现方式二:将主键属性提取到一个主键类中,实体类只需包含主键类的一个引用 在日常开发中会遇到这样一种情况,数据库中的某张表需要多个字段列才能唯一确定一行记录,这时表需要使用复合主键.面对这样的情况Hibernate为我们提供了两种方式来解决复合主键问题. 方式一:将复合主键对应的属性与实体其他普通属性放在一起 例如实体类People中"id"和"name"属性对应复合主键: /*实体类,