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
分享到:
相关推荐
本篇文章将深入探讨Hibernate如何处理复合主键映射,并通过实例进行解析。 复合主键在数据库设计中是常见的,例如,考虑一个订单明细表,其中订单号(order_id)和商品编号(product_id)结合在一起可以唯一识别一...
在无主键表映射的情况下,数据库中的表应该没有明确的`PRIMARY KEY`约束,而是依赖于复合主键字段的唯一性。例如: ```sql CREATE TABLE Orders ( customerId VARCHAR(255) NOT NULL, orderId VARCHAR(255) NOT ...
《Hibernate复合主键配置与使用详解》 在Java开发中,Hibernate作为一款强大的ORM框架,大大简化了数据库操作。然而,当我们面临复杂的数据表结构,尤其是涉及到复合主键时,如何在Hibernate中进行配置和使用就显得...
在Hibernate的映射文件(XML方式)或者使用JPA注解(Java方式)中,需要为复合主键提供相应的配置。对于XML配置,你可能会看到类似以下的设置: ```xml <hibernate-mapping> <!-- 其他属性的映射 --> ...
在Java的Hibernate框架中,复合主键映射是一种处理多列组合成主键的情况,它使得在数据库表中由两个或更多个字段组成的主键能够被正确地映射到实体类。在使用复合主键时,我们需要遵循一定的步骤和规则。 首先,...
在Java的持久化框架Hibernate中,复合主键(Composite Key)是一种特殊的数据结构,用于处理具有多个字段作为唯一标识的情况。本实例将深入探讨如何在Hibernate中实现复合主键,并提供一个具体的示例来帮助理解。 ...
在一对多或多对一的关系映射中,如果关联的主键是复合的,需要在`@ManyToOne`或`@OneToMany`注解中指定`mappedBy`属性,以便于Hibernate理解关联关系。 总结来说,Hibernate通过`@IdClass`和`@EmbeddedId`两种方式...
### Hibernate复合主键详解 在关系型数据库设计中,经常会出现使用多个字段组合起来作为主键的情况,这种类型的主键被称为复合主键。而在Java领域,尤其是使用Hibernate框架进行持久化操作时,复合主键的应用变得尤...
### Hibernate中对数据库复合主键的支持 #### 一、引言 在软件开发过程中,特别是在J2EE领域中,Hibernate作为一种流行的ORM(Object-Relational Mapping)框架被广泛使用。ORM框架的主要作用是将关系型数据库中的...
在Hibernate中,Map通常对应于数据库的复合主键或者关联表。配置示例: ```xml ``` 这里的`<map>`元素定义了一个名为`preferences`的Map集合,`<key>`元素对应外键,`<map-key>`元素指定Map的键列和类型,...
通过这种方式,Hibernate将知道如何处理`UserRole`类,将其映射到具有复合主键的数据库表。 3. 嵌入式主键(Embedded Id): 如果希望将主键字段作为实体类的一部分,而不是单独的类,可以使用`@EmbeddedId`和`@...
在Java开发中,Hibernate是一个非常重要的对象关系映射(ORM)框架,它允许开发者使用面向对象的方式来操作数据库,极大地简化了数据库操作。本教程将详细讲解Hibernate中的关联关系映射配置,帮助你理解和掌握如何...
总结来说,Hibernate的复合主键映射允许我们将由多个属性组成的主键映射到对象上,通过在映射配置文件中使用`<composite-id>`标签,并为每个主键属性创建`<key-property>`。此外,通过创建一个专门的主键类,我们...
Hibernate的映射标签和属性是其核心功能之一,其中<hibernate-mapping>标签用于定义映射文件的根元素,标签用于定义持久化类的映射,标签用于定义类的主键映射,标签用于定义类的属性映射。通过这些标签,可以创建...
6. `<join>`:用于处理复合主键或者跨表的复杂映射。 生成工具的工作原理大致如下: 1. 连接数据库:工具会首先连接到指定的数据库,获取数据库的元数据信息,如表名、列名、约束等。 2. 分析表结构:根据数据库中...
2. **复合主键映射**:使用`@Embeddable`和`@EmbeddedId`注解,定义一个包含多个字段的复合主键类,这个类作为子对象的一部分,存储在父对象的表中。 3. **一对一嵌入映射**:使用`@OneToOne`配合`@MapsId`和`@...
这样做可以让Hibernate知道哪些字段应该被视为复合主键的一部分。 例如,在`s2sh_relation05_one2one_uni_fk_composite`的示例中,假设我们有一个`Student`实体和一个`Address`实体,它们之间存在一对一(One-to-...