(2)id:单个属性(AUTO、Table)联合主键三种实现方式

一、单个主键

@Entity 
//从这个包(javax.persistence.Entity)可以看出,是个标准,不依赖于hibernate
//@Table(name="_Teacher") //当model类和数据库的表名,不一致时,应该在这里指定。在这里类名为:teacher,表名是:_Teacher

//生成一个表名是GENERATOR_TABLE的表,有两个字段pk_key、pk_value。 pkColumnValue是一条记录pk_key
//简单理解:这个表存表名和下一次的id号
//下面的getId:处写@GeneratedValue(strategy=GenerationType.TABLE,generator="teacher_GEN" )
//这是跨数据库平台【但是这很少用】
@javax.persistence.TableGenerator(
        name="teacher_GEN",
        table="GENERATOR_TABLE",
        pkColumnName = "pk_key",
        valueColumnName = "pk_value",
        pkColumnValue="teacher",
        allocationSize=1
    )
/*
 * 这个演示单个主键
 */
public class teacher {

    private int id;
    private String name;
    private int age;
    private String sex;
    private Date birthDate;
    private ZhiCheng zhicheng;

    @Id //必须加在getId上面
    //@GeneratedValue(strategy=GenerationType.IDENTITY)//这样指定,只能在mysql或者sql service
   // @GeneratedValue(strategy=GenerationType.SEQUENCE)//这样指定,能在oracle中运用

    /*@GeneratedValue 在只这样写,而没有()里面的内容时
     * 【常用】
     * auto:可以是identity column类型或者sequence类型、table类型,取决于底层数据库 ,不用人为判断
     * auto :在mysql、sql service中用auto_increment(identity)  在oracle中用sequence  
     */
    @GeneratedValue(strategy=GenerationType.TABLE,generator="teacher_GEN" )
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

1.@Id可以将实体bean中的某个属性定义为标识符,该属性的值可以通过应用自身进行设置,也可以通过hibernate生成(推荐),如何让hibernate生成呢?使用@GeneratedValue注解可以定义该标识符的生产策略:
AUTO:依据底层的数据库自动选择生成策略。在mysql 、sql service中用auto_increment(identity)在oracle中用sequence。若只写@GeneratedValue,即默认情况,则是auto ,具体来说是identity
TABLE 可以让多个表共享一个生成策略,

//定义在类外
@javax.persistence.TableGenerator(
        name="teacher_GEN",//在类中生成器的名称
        table="GENERATOR_TABLE",//生成器表名
        pkColumnName = "pk_key",//列名
        valueColumnName = "pk_value",//列名
        pkColumnValue="teacher",// pkColumnName对应的值
        allocationSize=1
    )
@Id
    @GeneratedValue(strategy=GenerationType.TABLE,generator="teacher_GEN")
    public int getId() {
        return id;
    }
GENERATOR_TABLE表
-------------------------
pk_key    |  pk_value
------------------------------
teacher    | 下一次插入的键值
------------------------

这是类级生成器,类级别生成器杂类外是不可见的。若要多个类是同一个表级生成策略,则应该在每个类中均要写
二、联合主键
一般要把联合主键放在单独的类中,并且该类必须实现serializable,必须复写hashcode、equals方法

用注解的方式实现组合主键,只是省略了配置文件,还是要实现serializable、复写hashcode、equals方法。
有三种实现方式:
①组件类注解为@Embeddable,并将组件的属性注解为@Id【注意是将引用该类的类中注解@Id】
②将组件的属性注解为@EmbeddedId 【简单方便】
③将类注解为@IdClass ,并将该实体中所有主键的属性都注解为@Id
这种方式中,teacher中仍然有主键属性,详情看:com.model1.teacher3
但是teacher1PK必须得写



//@Embeddable//方式一
public class teacher1PK 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 int hashCode() {

        return id*10+name.hashCode();
    }
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof teacher1PK){
            teacher1PK pk=(teacher1PK) obj;
            if(pk.id==this.id&&pk.name==this.name)
            {
                return false;
            }
        }
        return true;
    }
}

teacher1

@Entity 


public class teacher1 {

    private teacher1PK pk;
    private int age;
    private String sex;
    private Date birthDate;

    //@Id方式一
    //@EmbeddedId//方式二
    public teacher1PK getPk() {
        return pk;
    }
    public void setPk(teacher1PK pk) {
        this.pk = pk;
    }   
}

teacher3类

@Entity 
@IdClass(value = teacher1PK.class)//指明对应的主键类
public class teacher3 {

    private int id;
    private String name;
    private int age;
    private String sex;
    private Date birthDate;


    @Id
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }


    @Column(name="_name",
    length=10,nullable=false)//当类中属性名和数据库中字段名不一致时,通过这个注解,就能实现类中字段name到数据库字段_name的映射。但要注意要写在get方法上面
    //若对数据库中的属性字段有限制,可以在@Column中设定
    @Id
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
posted @ 2017-11-12 10:43  测试开发分享站  阅读(125)  评论(0编辑  收藏  举报