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

将主键所对应的属性提取出一个类(称之为主键类),并且主键类需要实现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!


你可能感兴趣的:(联合主键)