`
sarin
  • 浏览: 1749250 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
E3b14d1f-4cc5-37dd-b820-b6af951740bc
Spring数据库访问系列...
浏览量:172921
C2083dc5-6474-39e2-993e-263652d27795
Android学习笔记
浏览量:366753
5f40a095-b33c-3e8e-8891-606fcf3b8d27
iBatis开发详解
浏览量:188432
B272a31d-e7bd-3eff-8cc4-c0624ee75fee
Objective-C学习...
浏览量:98901
社区版块
存档分类
最新评论

Hibernate中复合主键的映射

阅读更多
    Hibernate中除了使用<generator>来生成主键之外,还可以根据具体的需求让持久化类的标识符属性映射成数据库的符合主键。为了说明问题,我们首先在数据库建立一个USERS表,其中主键使用USERNAME和BIRTH_DATE作为复合主键。其中创建表的SQL语句如下:
create table USERS(
	USERNAME VARCHAR2(20) NOT NULL,
	PASSWORD VARCHAR2(20) NOT NULL,
	BIRTH_DATE VARCHAR2(8) NOT NULL, --使用String类型,存4位年2位月2位日
	EMAIL VARCHAR2(40),
	PRIMARY KEY(USERNAME,BIRTH_DATE)
);


    持久化对象User如下:
package demo.domain;
public class User implements java.io.Serializable {
	private String username;
	private String password;
	private String birthDate;
	private String email;
	public User() {
	}
	public User(String username, String birthDate) {
		this.username = username;
		this.birthDate = birthDate;
	}
	// 省略所有getter和setter方法
}
映射文件如下,使用复合主键方式映射:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="demo.domain.User" table="USERS">
		<composite-id>
			<key-property name="username" type="java.lang.String"
				column="USERNAME" />
			<key-property name="birthDate" type="java.lang.String"
				column="BIRTH_DATE" />
		</composite-id>
		<property name="password" type="java.lang.String" column="PASSWORD" />
		<property name="email" type="java.lang.String" column="EMAIL" />
	</class>
</hibernate-mapping>

    字段含义和单主键的是一致的,就不用多说什么了。测试类如下:
package demo;
import org.hibernate.*;
import demo.domain.User;
public class Test {
	public void addUser(User user) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction tx = session.beginTransaction();
		session.save(user);
		tx.commit();
	}
	public User getUser(User user) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction tx = session.beginTransaction();
		User user2 = (User) session.get(User.class, user);
		tx.commit();
		return user2;
	}
	public void printUser(User user) {
		System.out.print("用户名:" + user.getUsername() + "\t");
		System.out.print("密码:" + user.getPassword() + "\t");
		System.out.print("出生日期:" + user.getBirthDate() + "\t");
		System.out.println("email地址:" + user.getEmail() + "\t");
	}
	public static void main(String[] args) {
		Test test = new Test();
		User user = new User("Sarin", "19870801");
		user.setPassword("123456");
		user.setEmail("test@test.com");
		test.addUser(user);
		System.out.println("----------读取一条记录----------");
		user = new User();
		user.setUsername("Sarin");
		user.setBirthDate("19870801");
		test.printUser(test.getUser(user));
		HibernateUtil.getSessionFactory().close();
	}
}

    运行程序,我们得到如下结果:

    Hibernate在查询记录是就按照联合主键方式来查找了。
    当然,我们也可以抽取主键类来映射符合主键,则把上面的代码改为如下方式:
package demo.domain;
import java.io.Serializable;
public class UserId implements Serializable {
	private String username;
	private String birthDate;
	public UserId() {
	}
	public UserId(String username, String birthDate) {
		this.username = username;
		this.birthDate = birthDate;
	}
	// 省略所有getter和setter方法
}

package demo.domain;
public class User implements java.io.Serializable {
	private UserId id;
	private String password;
	private String email;
	public User() {
	}
	public User(UserId id, String password, String email) {
		this.id = id;
		this.password = password;
		this.email = email;
	}
// 省略所有getter和setter方法
}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="demo.domain.User" table="USERS">
		<composite-id name="id" class="demo.domain.UserId">
			<key-property name="username" type="java.lang.String"
				column="USERNAME" />
			<key-property name="birthDate" type="java.lang.String"
				column="BIRTH_DATE" />
		</composite-id>
		<property name="password" type="java.lang.String" column="PASSWORD" />
		<property name="email" type="java.lang.String" column="EMAIL" />
	</class>
</hibernate-mapping>

    映射文件修改很简单,在<composite-id>元素上加入name和class两个属性即可。其他都不用修改。测试类如下修改即可:
package demo;
import org.hibernate.*;
import demo.domain.*;
public class Test {
	public void addUser(User user) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction tx = session.beginTransaction();
		session.save(user);
		tx.commit();
	}
	public User getUser(UserId id) {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction tx = session.beginTransaction();
		User user = (User) session.get(User.class, id);
		tx.commit();
		return user;
	}
	public void printUser(User user) {
		System.out.print("用户名:" + user.getId().getUsername() + "\t");
		System.out.print("密码:" + user.getPassword() + "\t");
		System.out.print("出生日期:" + user.getId().getBirthDate() + "\t");
		System.out.println("email地址:" + user.getEmail() + "\t");
	}
	public static void main(String[] args) {
		Test test = new Test();
		User user = new User();
		UserId id = new UserId("Sarin", "19870801");
		user.setId(id);
		user.setPassword("123456");
		user.setEmail("test@test.com");
		test.addUser(user);
		System.out.println("----------读取一条记录----------");
		id = new UserId("Sarin", "19870801");
		user = test.getUser(id);
		test.printUser(user);
		HibernateUtil.getSessionFactory().close();
	}
}

    代码中的HibernateUtil是抽取出的Hibernate单例模式工具类。在实际项目中能尽可能减少复合主键也是有必要的,因为复合主键使用的是自然属性作为码,一旦自然属性需要修改,那么修改主键是非常麻烦的一件事情,所以使用代理主键作为数据库的主键策略是最好的。
  • 大小: 53.8 KB
  • 大小: 55.4 KB
5
0
分享到:
评论

相关推荐

    hibernate复合主键映射

    复合主键映射 &lt;br&gt;通常将复合主键相关属性,单独抽取出来,建立一个独立的类 * 必须实现序列化接口 * 必须实现equals和hashcode方法 采用标签进行映射,其它属性采用正常映射

    hibernate 无主键表映射

    hibernate 无主键表映射资源说明: 1. 简单Demo 2. Demo对应的sql语句 3. 对应博客文档

    Java的Hibernate框架中复合主键映射的创建和使用教程

    复合主键映射用起来比普通的增加主键字段要复杂,这里我们就来共同学习Java的Hibernate框架中复合主键映射的创建和使用教程,需要的朋友可以参考下

    Hibernate学习笔记

    023 复合主键 关联映射 024 其它 关联映射 025 hibernate 悲观锁、乐观锁 026 hibernate 操作树形结构 027 hibernate 查询语言(HQL) 028 hibernate 缓存(性能优化策略) 029 hibernate 抓取策略

    hibernate学习笔记

    复合(联合)主键映射(hibernate_composite) 27 集合(collection)映像 (hibernate_collection) 28 Hibernate 对数据库的并发支持 30 悲观锁(hibernate_pessimistic) 30 乐观锁(hibernate_optimistic) 32 HQL...

    Hibernate映射配置入门进阶详解

    1)根元素映射&lt;hibernate-mapping/&gt; 2)类映射 3)属性映射 4)主键的配置 5)主键生成策略 复合主键策略 史上最详细

    Hibernate Annotations 中文文档

    2.2.6. 映射复合主键与外键 2.2.7. 映射二级表(secondary tables) 2.3. 映射查询 2.3.1. 映射EJBQL/HQL查询 2.3.2. 映射本地化查询 2.4. Hibernate独有的注解扩展 2.4.1. 实体 2.4.2. 标识符 2.4.3. 属性 2.4...

    Hibernate3.1_学习源码

    04 04Hibernate_Composite : 复合主键的使用,在开发中很少用到,一般良好的设计都会为一个表添加一个自动增长的主键标识列。其中重点配置方法和Hibernate中普遍采用的方法链编程的使用。还需注意可以将组合主键构建...

    Hibernate入门(代码+笔记)

    总共分5部分:1和2为hibernate入门,3为hibernate实体映射,4为hibernate复合主键,5为hibernate实体层设计.

    hibernate annotation 中文文档

    2.2.6. 映射复合主键与外键 2.2.7. 映射二级表(secondary tables) 2.3. 映射查询 2.3.1. 映射EJBQL/HQL查询 2.3.2. 映射本地化查询 2.4. Hibernate独有的注解扩展 2.4.1. 实体 2.4.2. 标识符 2.4.3. 属性 2.4.3.1. ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     15.1.2 按照主键映射  15.2 映射单向多对多关联  15.3 映射双向多对多关联关系  15.3.1 关联两端使用元素  15.3.2 在inverse端使用元素  15.3.3 使用组件类集合  15.3.4 把多对多关联分解为两个一对多关联 ...

    hibernate注解案例

    Hibernate 的注解学习 ExportDBAnnotation HibernateAnnotationUtils 【一对一】关系映射【一对多】关系映射 【多对多】关系映射 【composite复合主键】关系映射【component组件】关系映射

    hibernate annotation帮助文档

    2.2.6. 映射复合主键与外键 2.2.7. 映射二级表(secondary tables) 2.3. 映射查询 2.3.1. 映射EJBQL/HQL查询 2.3.2. 映射本地化查询 2.4. Hibernate独有的注解扩展 2.4.1. 实体 2.4.2. 标识符 2.4.3. 属性 2.4...

    精通hibernate:对象持久化技术孙卫琴第二版part2

    6.5.2 映射复合自然主键 140 6.6 小结 143 6.7 思考题 144 第7章 映射一对多关联关系 147 本章介绍一对多关联关系的映射方法,重点介绍inverse属性和cascade属性的用法。本章还将介绍通过Hibernate API来保存、...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     15.1.2 按照主键映射  15.2 映射单向多对多关联  15.3 映射双向多对多关联关系  15.3.1 关联两端使用元素  15.3.2 在inverse端使用元素  15.3.3 使用组件类集合  15.3.4 把多对多关联分解为两个一对多关联 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     15.1.2 按照主键映射  15.2 映射单向多对多关联  15.3 映射双向多对多关联关系  15.3.1 关联两端使用元素  15.3.2 在inverse端使用元素  15.3.3 使用组件类集合  15.3.4 把多对多关联分解为两个一对多关联 ...

Global site tag (gtag.js) - Google Analytics