Hibernate教程02_ID生成策略


本教程每节课都附带源码,强烈大家建议配合源码学习。
本节源码:http://download.csdn.net/detail/e421083458/5253687


在开始新课之前先讲一下:创建测试专用Source Folder进行测试。

1.新建Source Folder名称为test
2.创建package=com.bjsxt.hiberante
3.创建测试脚本:
HibernateQLTest.java
package com.bjsxt.hiberante;
import java.util.Date;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.Session;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.bjsxt.hibernate.Category;
import com.bjsxt.hibernate.Gender;
import com.bjsxt.hibernate.Student;
import com.bjsxt.hibernate.StudentPK;
import com.bjsxt.hibernate.TTeacher;
import com.bjsxt.hibernate.TTeacherPK;
import com.bjsxt.hibernate.Teacher;

public class HibernateQLTest {
    private static SessionFactory sf;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        System.out.println("BeforeClass");
        sf = new AnnotationConfiguration().configure().buildSessionFactory();
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        System.out.println("AfterClass");
        sf.close();
    }
}



没错,我们将重复操作的步骤放到了方法中。这样测试效率更高了!:>

注意:我们观察hibernate生成表的结构并不是为了将来就用它生成,(可能还有自己的扩展,比如index等)而是为了明白我们应该建立什么样的表和实体类映射

下面只讲实体类,映射自己添加!

自增主键映射:

package com.bjsxt.hibernate;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Category {
    private int id;
    private String name;
    @Id
    @GeneratedValue
    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;
    }
}


测试方法:

@Test
    public void testSave(){
        Session session = sf.openSession();
        session.beginTransaction();
        
        for(int i=0;i<10;i++){
            Category c = new Category();
            c.setName("c"+i);
            session.save(c);
        }
        session.getTransaction().commit();
        session.close();        
        System.out.println("yes!!!");
    }



uuid作为主键

package com.bjsxt.hibernate;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name = "_teacher")
public class Teacher {
    private String id;
    private String name;
    private String title;
    private String yourWifeName;
    private Date birthDate;
    @Id
    @GeneratedValue(generator="teacherUUID")
    @GenericGenerator(name="teacherUUID", strategy="uuid")
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getYourWifeName() {
        return yourWifeName;
    }
    public void setYourWifeName(String yourWifeName) {
        this.yourWifeName = yourWifeName;
    }
    public Date getBirthDate() {
        return birthDate;
    }
    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }
}



测试方法:

@Test
    public void testTeacher(){
        Session session = sf.openSession();
        session.beginTransaction();
        Teacher t = new Teacher();
        t.setName("t1");
        t.setTitle("middle");
        t.setYourWifeName("up");
        t.setBirthDate(new Date());
        session.save(t);
        session.getTransaction().commit();
        session.close();
    }



联合主键XML方式

package com.bjsxt.hibernate;

public class Student {
    private StudentPK pk;
    private String sex;
    private boolean good;
    public StudentPK getPk() {
        return pk;
    }
    public void setPk(StudentPK pk) {
        this.pk = pk;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public boolean isGood() {
        return good;
    }
    public void setGood(boolean good) {
        this.good = good;
    }
}



package com.bjsxt.hibernate;

import java.io.Serializable;

public class StudentPK implements Serializable {
    private int id;
    private String name;
    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;
    }
    @Override
    public boolean equals(Object o){
        if(o instanceof StudentPK){
            StudentPK pk = (StudentPK) o;
            if(this.id == pk.getId()&&this.name.equals(pk.getName())){
                return true;                
            }
        }
        return false;
    }
    @Override
    public int hashCode(){
        return this.name.hashCode();        
    }
}


关联文件:
<?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.bjsxt.hibernate.Student" table="__student">
        
            
        <composite-id name="pk" class="com.bjsxt.hibernate.StudentPK">
            <key-property name="id"></key-property>
            <key-property name="name"></key-property>
        </composite-id>
        
        <property name="sex" />
        <property name="good" type="yes_no"></property>
    </class>
    
</hibernate-mapping>



测试方法:

@Test
    public void testStudent(){
        Session session = sf.openSession();
        session.beginTransaction();
        StudentPK pk = new StudentPK();
        pk.setId(1);
        pk.setName("zhangsan");
        Student t = new Student();
        t.setPk(pk);
        t.setSex("man");
        t.setGood(false);        
        session.save(t);
        session.getTransaction().commit();
        session.close();
    }


    



联合主键Annotation方式

package com.bjsxt.hibernate;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
@Entity
public class TTeacher {
    private TTeacherPK ttpk;
    private String title;
    private String yourWifeName;
    private Date birthDate;
    private boolean good=true;
    private Gender gender;
    @Id
    public TTeacherPK getTtpk() {
        return ttpk;
    }
    public void setTtpk(TTeacherPK ttpk) {
        this.ttpk = ttpk;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getYourWifeName() {
        return yourWifeName;
    }
    public void setYourWifeName(String yourWifeName) {
        this.yourWifeName = yourWifeName;
    }
    public Date getBirthDate() {
        return birthDate;
    }
    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }
    public boolean isGood() {
        return good;
    }
    public void setGood(boolean good) {
        this.good = good;
    }
    @Enumerated(EnumType.STRING)
    public Gender getGender() {
        return gender;
    }
    public void setGender(Gender gender) {
        this.gender = gender;
    }
    
}



TTeacherPK.java


package com.bjsxt.hibernate;

import java.io.Serializable;

import javax.persistence.Embeddable;
@Embeddable
public class TTeacherPK implements Serializable {
    private int id;
    private String name;
    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;
    }
    @Override
    public boolean equals(Object o){
        if(o instanceof StudentPK){
            StudentPK pk = (StudentPK) o;
            if(this.id == pk.getId()&&this.name.equals(pk.getName())){
                return true;                
            }
        }
        return false;
    }
    @Override
    public int hashCode(){
        return this.name.hashCode();        
    }
}



测试方法:

@Test
    public void testTTeacher(){
        Session session = sf.openSession();
        session.beginTransaction();
        TTeacherPK ttpk = new TTeacherPK();
        ttpk.setId(1);
        ttpk.setName("name");
        TTeacher tt = new TTeacher();
        tt.setTtpk(ttpk);
        tt.setBirthDate(new Date());
        tt.setGender(Gender.MALE);
        tt.setGood(true);
        tt.setTitle("title");
        tt.setYourWifeName("wife");
        session.save(tt);
        session.getTransaction().commit();
        session.close();
    }



当然Annotaion的方式有2种,如果大家有兴趣可以研究一下!

总结:

1.xml生成id
    <id name="id" >
        <generator class="native"></generator>
    </id>
    常用四个:native identity sequence uuid(跨平台 native uuid)
2.注解方式:
    自定义ID
    @GeneratedValue
    表示的意思为AUTO_INCREMENT(直接写相当如native)
    默认:对 MySQL,使用auto_increment
    对 Oracle使用hibernate_sequence(名称固定)
    IDENTITY(@GeneratedValue(strategy=GenerationType.IDENTITY))
    SEQUENCE(@GeneratedValue(strategy=GenerationType.SEQUENCE))
    
    
    @SequenceGenerator(可自定义在数据库生成指定的sequence名)
            @Id
       //在@GeneratedValue中增加 generator="teacherSEQ"
       @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="teacherSEQ")
       //"teacherSEQ"为@SequenceGenerator的标识名
       //"teacherSEQ_DB"为指定到数据库生成的Sequence名
       @SequenceGenerator(name="teacherSEQ", sequenceName="teacherSEQ_DB")
       public int getId() {
                return id;
       }
    TABLE (使用附加表作为主键的方式)
    @TableGenerator
    @TableGenerator(name="teacherID",
            table="teacherID_DB",
            pkColumnName="key_value",
            pkColumnValue="pk_value",
            valueColumnName="teacher",
            allocationSize=1)

    如果使用注解方式的uuid 如下:
    @Id
  @GeneratedValue(generator="teacherUUID")
  @GenericGenerator(name="teacherUUID", strategy="uuid")


3.FAQ;
    用Junit测试时Hibernate Session Factory初始化异常不提示.疑似一个bug
    用main来做测试
    
    比如:
    public static void main(String args[]){
        sf = new AnnotationConfiguration().configure().buildSessionFactory();
        
        Session session = sf.openSession();
        session.beginTransaction();
        StudentPK pk = new StudentPK();
        pk.setId(1);
        pk.setName("zhangsan");
        Student t = new Student();
        t.setPk(pk);
        t.setSex("man");
        t.setGood(false);        
        session.save(t);
        session.getTransaction().commit();
        session.close();
        
        sf.close();
        
    }
    field [age] not found on com.bjsxt.hibernate.Student
    
4.联合主键
4.1 Xml方式: composite-id
将联合主键的属性提取出来,重新编写一个pojo类(原pojo类中的id,name要删除 并新加入属性“StudentPK”)
    public class StudentPK implements Serializable {
    private String id;
    private String name;
    新建pojo类必须实现 java.io.Serializable 序列化接口
    新pojo类要重写equals和hashCode方法
    @Override
    public boolean equals(Object o) {
        if(o instanceof StudentPk) {
            StudentPk pk = (StudentPk)o;
            if(this.id == pk.getId() && this.name.equals(pk.getName())) {
              return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        return this.name.hashCode();
    }
    联合主键生成策略XML配置方法
        <hibernate-mapping>
            <class name="com.bjsxt.pojo.Student" >
                <composite-id name="studentPK" class="com.bjsxt.pojo.StudentPK">
                    <key-property name="id"></key-property>
                    <key-property name="name"></key-property>
                </composite-id>
                <property name="age" />
                <property name="sex" />
                <property name="good" type="yes_no"></property>
            </class>
    </hibernate-mapping>

4.2 Annotation
前三步与Xml方式前三步一样 都要建立新pojo类 都要实现Serializable接口 重写equals和hashCode方法.
方法1在新类前写@Embeddable,在原pojo类的新属性“TercherPK”的get方法前写@ld,如下
@ Embeddable
public class TeacherPK implements Serializable {
private String id;
private String name;

@Entity
public class Teacher {
        private TeacherPK teacherPK ;
        @Id
        public TeacherPK getTeacherPK() {
        return teacherPK;
}

方法2:@EmbeddedlD(*)  新pojo类无需加注解,只需在原pojo类新属性“TercherPK”的get方法前写@EmbeddedlD即可
方法3:@ld  @IdClass(*)  新pojo类无需加注解,原pojo类的id,name属性保留不变,也无需新增“TercherPK”属性。 只在id,name的get方法前都加@Id,并在原pojo类前加“@IdClass(TeacherPK).class)”,如下
@Entity
@IdClass(TeacherPK.class)
public class Teacher {
        private String id;
        private String name;
        @Id
        public String getId() {
        return id;
        }
        @Id
        public String getName() {
        return name;
        }

你可能感兴趣的:(Hibernate教程02_ID生成策略)