024_ID生成策略_联合主键_XML

6.联合组件 (对于串知识点很重要)

a) xml:

   i:为什么要重写equals和hashcode

   ii:为什么要实现serializable

b)@IdClass

在面向对象中

 两个值为主键

就要分成两个类,一个类转为主键类,一个为正常的类。

扫描二维码关注公众号,回复: 706534 查看本文章

步骤

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}

猜你喜欢

转载自yuzhouxiner.iteye.com/blog/2268317