`

联合主键二:组件映射方式

 
阅读更多
将主键所对应的属性提取出一个类(称之为主键类),并且主键类需要实现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":可能是以...

    hibernate4.1中文api

    - **动态组件**: 动态创建组件映射。 #### 10. 继承映射 - **三种策略**: - **表每个类层次**: 每个继承树使用一个表。 - **表每个子类**: 每个子类使用一个表。 - **表每个子类:使用一个鉴别器**: 结合多个...

    Hibernate 参考文档

    - **composite-id联合ID**:当实体类具有多个主键字段时的映射方法。 - **识别器(discriminator)**:用于区分继承体系中的不同子类。 - **版本(version)**:乐观锁实现策略之一。 - **时间戳(timestamp)**...

    Hibernate_学习笔记.

    - **联合主键关联(Annotation方式)**:两个对象通过联合主键进行关联。 - **Component(组件)关联映射** - **Component关联映射**:将一个对象的某些属性作为一个单独的对象进行处理。 - **User实体类**:表示...

    hibernate_3.2_官方中文参考手册.

    - **5.1.17 联合子类**:用于联合继承的映射。 - **5.1.18 连接**:定义表间关联的元素。 - **5.1.19 键**:关联映射中的外键字段。 - **5.1.20 字段和规则元素**:具体字段的映射及计算字段的定义。 - **...

    hibernate_reference中文文档.pdf

    - **8.5 动态组件 (Dynamic components)**:介绍动态组件映射的实现方式。 #### 9. 继承映射 (Inheritance Mapping) 这一章讲解了 Hibernate 中的继承映射策略。 - **9.1 三种策略** - **9.1.1 每个类分层结构...

    hibernate组件之间的关联

    **联合主键(Composite Key)** 在某些场景下,可能需要多个字段共同构成主键。使用 @Embeddable 和 @EmbeddedId 注解可以定义复合主键。 以上就是 Hibernate 组件之间的关联关系及其配置方法的详细介绍。了解并...

    mybatis中文教程

    7. **ResultMap**:结果映射是MyBatis的强项,它允许你定义复杂的结果映射,包括联合主键、嵌套结果集和自定义类型处理器。 8. **Mapper接口和Mapper XML文件**:MyBatis允许开发者定义一个接口,然后在XML文件中...

    Nhibernate 全面分析.doc

    4. **联合主键**:当表使用多个字段作为主键时,可以在实体类中使用接口`ICompositeUserType`实现自定义主键。 ### 查询API NHibernate提供HQL(Hibernate Query Language)和 Criteria API,它们是面向对象的查询...

    Java相关课程系列笔记之十四Hibernate学习笔记

    - 联合主键:支持多个字段作为主键。 - 聚集函数:HQL支持SUM、COUNT、AVG等聚合操作。 - 分页查询:通过设置firstResult和maxResults实现分页。 - 异构查询:支持不同类型的对象混合查询。 通过深入学习和实践,...

    Hibernate开发指

    3. 联合主键:多个字段共同构成主键的映射。 4. 继承映射:单表继承、多表继承和表-per-hierarchy等策略。 八、性能优化 1. 分页查询:避免一次性加载大量数据,使用Query的setFirstResult()和setMaxResults()方法...

    Hibernate Reference Documentation

    - **复合主键**:当主键由多个字段组成时的映射方式。 - **区分器**:定义多态映射时的区分器字段。 - **版本**:可选元素,用于实现乐观锁。 - **时间戳**:可选元素,用于记录实体的最后修改时间。 - **属性*...

    Hibernate学习教程和笔记

    - **组件映射**: 将对象的一部分作为组件映射,适用于地址、联系人信息等具有固定结构的数据。 通过以上知识点的学习,可以全面掌握Hibernate的基本原理和核心用法,进而有效地应用于实际的Java项目中,实现高效的...

    Hibernate继承映射

    【Hibernate继承映射】是Java开发中...以上就是关于Hibernate继承映射、一对一关系、组件映射以及HQL的基础知识,这些概念和实践技巧在Java企业级开发中非常常见,熟练掌握能有效提高数据操作的效率和代码的可维护性。

    nhibernate_reference.pdf

    11. **组件映射**:映射复杂的嵌套对象结构。 12. **子类映射**:在继承模式下映射子类。 13. **联合子类映射**:一种特殊的继承映射策略。 14. **集合映射**:定义集合类型的映射。 15. **导入声明**:使用 `import...

    Hibernate hibernate

    2. 联合主键:支持多个字段构成的复合主键。 3. 异步操作:利用Hibernate的异步API,提高系统响应速度。 4. 数据库分页:Query对象提供了分页查询的功能。 5. 动态模型:允许在运行时动态构建查询,增强了灵活性。 ...

    MyBatis面试题分享.rar

    - 通过resultMap,MyBatis可以方便地处理这些复杂关系的映射,如联合主键、嵌套结果映射等。 9. **MyBatis的MyBatis Generator**: - MyBatis Generator是一个代码生成工具,可以根据数据库表结构自动生成Java...

    hibernate教程

    - **组件映射**:`component` 和 `dynamic-component` 元素用于映射复杂类型的属性。 - **子类映射**:`subclass` 元素用于单表继承时映射子类。 - **联合子类映射**:`joined-subclass` 元素用于多表继承时映射子类...

    JPA 批注参考Java JPA

    Java 持续性API(JPA)是Java企业版5(Java EE 5)的一部分,作为Enterprise JavaBean(EJB)3.0规范的组件,它的目标是简化EJB的持久性处理,并提供了一种面向对象的关系映射机制。JPA允许开发者以声明式的方式定义...

Global site tag (gtag.js) - Google Analytics