6.联合组件 (对于串知识点很重要)
a) xml:
i:为什么要重写equals和hashcode
ii:为什么要实现serializable
b)@IdClass
在面向对象中
两个值为主键
就要分成两个类,一个类转为主键类,一个为正常的类。
步骤
1、进行写student类
2.、写studentpk类
3.配置Student.hbm.xml
4.进行写测试类HibernateIDTest.java
疑问:
1.在主键类中为什么要实现public class StudentPK implements java.io.Serializable{}
为什么要用序列化:
作为student中,存在多条数据,多个student对象,
每个对象都有一个studentPK对象,
1.需要系统集群的服务,想传给另一台服务器,发现不实现序列化传不出去了。
2.内存满了,需要在硬盘上开辟一块虚拟内存,就要用序列化来实现,才能进行传递。
实现
在数据库中用主键来进行区分数据的;
内存里也应该用这样一种逻辑来区分,不然就不能数据库中的内容同步,不匹配了。
所有重写equals()和hashcode()
用联合主键就应该用equals()和hashcode()方法。
从数据库的角度讲,主键相同才返回true。
从内存的角度讲,我的id 和nanme和你相同才返回true。
我为什么重写hashcode()
装在hash表中,查hash表中的时候,要先查hashcode。
在找一个值时,进行找hashcode(找到后的一个链表进行遍历)
首先找studentPK的hashcode,然后再找到这个链表,再比较那个对象和我们这个对象equals。
代码案例:
StudentPK
package com.zhuhw.hibernate.model; public class StudentPK implements java.io.Serializable{ @Override public boolean equals(Object o) { if(o instanceof StudentPK) { StudentPK spk = (StudentPK)o; if(this.id == spk.getId()&& this.name == spk.getName()){ return true; } }return false; } @Override public int hashCode() { // TODO Auto-generated method stub return this.name.hashCode(); } private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } private String name; }
package com.zhuhw.hibernate.model; import javax.persistence.Id; public class Student { StudentPK spk; @Id public StudentPK getSpk() { return spk; } public void setSpk(StudentPK spk) { this.spk = spk; } private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } /* private String name;*/ }
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 找不到entity,是因为这个类没改包名 -->
<hibernate-mapping package="com.zhuhw.hibernate.model">
<class name="Student">
<!-- id主键;name=id对应的是Student中的getid() -->
<!--<id name="id" >
<generator class="uuid"></generator>
<generator class="native"></generator>
</id>
-->
<!-- 联合组件配置 -->
<composite-id name = "spk" class="com.zhuhw.hibernate.model.StudentPK">
<key-property name="id"></key-property>
<key-property name="name"></key-property>
</composite-id>
<property name="age" />
<!-- hibernater知道了怎么将class与表中的字段对应到一起了 -->
</class>
</hibernate-mapping>
package com.zhuhw.hibernate.model; import java.util.Date; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; public class HibernateIDTest { public static SessionFactory sf = null; @BeforeClass public static void beforeClass(){ sf = new AnnotationConfiguration().configure().buildSessionFactory(); } @Test public void TestStudentID(){ Student s = new Student(); /*配置文件中使用generator * s.setId(9); * */ StudentPK spk = new StudentPK(); spk.setId(11); spk.setName("waxun"); s.setAge(8); s.setSpk(spk); Session session = sf.openSession(); session.beginTransaction(); session.save(s); session.getTransaction().commit(); session.close(); } @Test public void TestTeacherID(){ Teacher t = new Teacher(); t.setName("yuzhou1"); t.setTitle("ccc"); t.setBirthdate(new Date()); t.setYourWifeName("yourWifeName1"); t.setZhicheng(ZhiCheng.A); //因为使用的annotation,所以Configuration要使用AnnotationConfiguration /*Configuration cf = new AnnotationConfiguration(); SessionFactory sf = cf.configure().buildSessionFactory();*/ Session session = sf.openSession(); //在hibernate中执行操作要在一个事务里面 session.beginTransaction(); session.save(t); session.getTransaction().commit(); session.close(); } @AfterClass public static void afterClass(){ sf.close(); } }
运行结果:
com.zhuhw.hibernate.model.Student{spk=component[id,name]{id=11, name=waxun}, age=8}