将主键所对应的属性提取出一个类(称之为主键类),并且主键类需要实现Serializable接口,
重写equals方法和hashCode 方法,原因同联合主键一:普通方式
场景和联合主键一:普通方式相同,只不过该方法将主键单独抽取为一个类,当然在配置文件时需要有所改变,个人感觉该方法比较好
主键类:StudentPrimaryKey.java
package com.fgh.hibernate;
import java.io.Serializable;
/**
* Student 主键类
*
* @author fgh
*
*/
public class StudentPrimaryKey implements Serializable {
private static final long serialVersionUID = 5129414054059220497L;
private String cardId;
private String name;
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cardId == null) ? 0 : cardId.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final StudentPrimaryKey other = (StudentPrimaryKey) obj;
if (cardId == null) {
if (other.cardId != null)
return false;
} else if (!cardId.equals(other.cardId))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
学生类:Student.java
package com.fgh.hibernate;
/**
*
* @author fgh
*
*/
public class Student {
//主键类的引用
private StudentPrimaryKey studentPrimaryKey;
private int age;
public StudentPrimaryKey getStudentPrimaryKey() {
return studentPrimaryKey;
}
public void setStudentPrimaryKey(StudentPrimaryKey studentPrimaryKey) {
this.studentPrimaryKey = studentPrimaryKey;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Student.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">
<hibernate-mapping>
<class name="com.fgh.hibernate.Student" table="student_composite">
<!-- 组件映射 使用class属性指定主键类 这里一定要指定好 name属性 否则找不到主键 -->
<composite-id name="studentPrimaryKey"
class="com.fgh.hibernate.StudentPrimaryKey">
<key-property name="cardId" column="cardId" type="string"></key-property>
<key-property name="name" column="name" type="string"></key-property>
</composite-id>
<property name="age" column="age" type="int"></property>
</class>
</hibernate-mapping>
hinernate.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">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="connection.url">
jdbc:mysql://localhost:3306/hibernate
</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="show_sql">true</property>
<mapping resource="Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
建表类:CreateTable.java
package com.fgh.hibernate;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
public class CreateTable {
public static void main(String[] args) {
SchemaExport export = new SchemaExport(new Configuration().configure());
export.create(true, true);
}
}
测试类:hibernateTest.java
package com.fgh.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
/**
* 联合主键二
*
* @author fgh
*
*/
public class HibernateTest {
private static SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure()
.buildSessionFactory();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// 保存-------begin-------
StudentPrimaryKey studentPrimaryKey = new StudentPrimaryKey();
studentPrimaryKey.setCardId("123");
studentPrimaryKey.setName("zhangsan");
Student student = new Student();
student.setStudentPrimaryKey(studentPrimaryKey);
student.setAge(20);
session.save(student);
// 保存-------end-------
// 查询 -------begin------
// Student student = (Student)
// session.get(Student.class,studentPrimaryKey);
// System.out.println(student.getAge());
// 查询 -------end------
tx.commit();
} catch (Exception e) {
e.printStackTrace();
if (null != tx) {
tx.rollback();
}
} finally {
session.close();
}
}
}
如果执行两次相同的保存操作,会报主键相同的错误,因为这时候主键已经不是hibernate自动生成了,而是我们根据自己的业务 逻辑自己定义的
报错信息:
Hibernate: insert into student_composite (age, cardId, name) values (?, ?, ?)
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.fgh.hibernate.HibernateTest.main(HibernateTest.java:46)
Caused by: java.sql.BatchUpdateException: Duplicate entry '123-zhangsan' for key 'PRIMARY'
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1693)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1108)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
... 8 more
Thanks,it's over,I hope for your help!
分享到:
相关推荐
组件映射与继承映射.ppt":组件映射涉及如何将一个对象拆分为多个部分进行存储,而继承映射则是关于如何处理类继承关系在数据库中的表示,可能包含单表继承、多表继承和联合继承等策略。 - "图解.xlsx":可能是以...
- **动态组件**: 动态创建组件映射。 #### 10. 继承映射 - **三种策略**: - **表每个类层次**: 每个继承树使用一个表。 - **表每个子类**: 每个子类使用一个表。 - **表每个子类:使用一个鉴别器**: 结合多个...
- **composite-id联合ID**:当实体类具有多个主键字段时的映射方法。 - **识别器(discriminator)**:用于区分继承体系中的不同子类。 - **版本(version)**:乐观锁实现策略之一。 - **时间戳(timestamp)**...
- **联合主键关联(Annotation方式)**:两个对象通过联合主键进行关联。 - **Component(组件)关联映射** - **Component关联映射**:将一个对象的某些属性作为一个单独的对象进行处理。 - **User实体类**:表示...
- **5.1.17 联合子类**:用于联合继承的映射。 - **5.1.18 连接**:定义表间关联的元素。 - **5.1.19 键**:关联映射中的外键字段。 - **5.1.20 字段和规则元素**:具体字段的映射及计算字段的定义。 - **...
- **8.5 动态组件 (Dynamic components)**:介绍动态组件映射的实现方式。 #### 9. 继承映射 (Inheritance Mapping) 这一章讲解了 Hibernate 中的继承映射策略。 - **9.1 三种策略** - **9.1.1 每个类分层结构...
**联合主键(Composite Key)** 在某些场景下,可能需要多个字段共同构成主键。使用 @Embeddable 和 @EmbeddedId 注解可以定义复合主键。 以上就是 Hibernate 组件之间的关联关系及其配置方法的详细介绍。了解并...
7. **ResultMap**:结果映射是MyBatis的强项,它允许你定义复杂的结果映射,包括联合主键、嵌套结果集和自定义类型处理器。 8. **Mapper接口和Mapper XML文件**:MyBatis允许开发者定义一个接口,然后在XML文件中...
4. **联合主键**:当表使用多个字段作为主键时,可以在实体类中使用接口`ICompositeUserType`实现自定义主键。 ### 查询API NHibernate提供HQL(Hibernate Query Language)和 Criteria API,它们是面向对象的查询...
- 联合主键:支持多个字段作为主键。 - 聚集函数:HQL支持SUM、COUNT、AVG等聚合操作。 - 分页查询:通过设置firstResult和maxResults实现分页。 - 异构查询:支持不同类型的对象混合查询。 通过深入学习和实践,...
3. 联合主键:多个字段共同构成主键的映射。 4. 继承映射:单表继承、多表继承和表-per-hierarchy等策略。 八、性能优化 1. 分页查询:避免一次性加载大量数据,使用Query的setFirstResult()和setMaxResults()方法...
- **复合主键**:当主键由多个字段组成时的映射方式。 - **区分器**:定义多态映射时的区分器字段。 - **版本**:可选元素,用于实现乐观锁。 - **时间戳**:可选元素,用于记录实体的最后修改时间。 - **属性*...
- **组件映射**: 将对象的一部分作为组件映射,适用于地址、联系人信息等具有固定结构的数据。 通过以上知识点的学习,可以全面掌握Hibernate的基本原理和核心用法,进而有效地应用于实际的Java项目中,实现高效的...
【Hibernate继承映射】是Java开发中...以上就是关于Hibernate继承映射、一对一关系、组件映射以及HQL的基础知识,这些概念和实践技巧在Java企业级开发中非常常见,熟练掌握能有效提高数据操作的效率和代码的可维护性。
11. **组件映射**:映射复杂的嵌套对象结构。 12. **子类映射**:在继承模式下映射子类。 13. **联合子类映射**:一种特殊的继承映射策略。 14. **集合映射**:定义集合类型的映射。 15. **导入声明**:使用 `import...
2. 联合主键:支持多个字段构成的复合主键。 3. 异步操作:利用Hibernate的异步API,提高系统响应速度。 4. 数据库分页:Query对象提供了分页查询的功能。 5. 动态模型:允许在运行时动态构建查询,增强了灵活性。 ...
- 通过resultMap,MyBatis可以方便地处理这些复杂关系的映射,如联合主键、嵌套结果映射等。 9. **MyBatis的MyBatis Generator**: - MyBatis Generator是一个代码生成工具,可以根据数据库表结构自动生成Java...
- **组件映射**:`component` 和 `dynamic-component` 元素用于映射复杂类型的属性。 - **子类映射**:`subclass` 元素用于单表继承时映射子类。 - **联合子类映射**:`joined-subclass` 元素用于多表继承时映射子类...
Java 持续性API(JPA)是Java企业版5(Java EE 5)的一部分,作为Enterprise JavaBean(EJB)3.0规范的组件,它的目标是简化EJB的持久性处理,并提供了一种面向对象的关系映射机制。JPA允许开发者以声明式的方式定义...