组合主键及JPA映射

来源:互联网 发布:常用的数据库管理系统 编辑:程序博客网 时间:2024/06/13 11:58

组合主键

主键最常见的是单字段主键,组合主键使用两个及以上的字段作为主键,常用于多个字段能唯一标示一条记录的表。比如,股票数据表,股票代码、日期和收盘价作为主键。每支股票,在一个特定日期,只能有一个收盘价。
数据库管理系统使用MySQL,创建一个具有组合主键的表Person。
CREATE TABLE PERSON (name VARCHAR(255) NOT NULL,    age BIGINT UNSIGNED NOT NULL,    adress VARCHAR(255) ,PRIMARY KEY (name, age)) ENGINE = InnoDB;

JPA映射之@IdClass

定义工具类

package com.gxz.entities;import java.io.Serializable;public class PersonCompositeId implements Serializable {private String name;    private long age;    public String getName() {return name;}public void setName(String name) {this.name = name;}public long getAge() {return age;}public void setAge(long age) {this.age = age;}}
该工具类的属性必须和实体类的@Id属性完全匹配。包括数量、名字,不能有额外的属性。

定义实体类

package com.gxz.entities;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.IdClass;import javax.persistence.Table;@Entity@Table@IdClass(PersonCompositeId.class)public class Person {private String name;    private long age;    private String adress;        @Idpublic String getName() {return name;}public void setName(String name) {this.name = name;}@Idpublic long getAge() {return age;}public void setAge(long age) {this.age = age;}public String getAdress() {return adress;}public void setAdress(String adress) {this.adress = adress;}}
该实体类有两个属性标示为@Id,表示主键为组合主键,主键属性为name、age。相应地,工具类PersonCompositeId必须有两个属性,分别为name、age。注意,此处指的是工具类必须有getName、setName、getAge、setAge,而不是指必须有字段name、age,注意区分属性和字段的区别。@IdClass(PersonCompositeId.class):表示使用工具类PersonCompositeId定义组合主键。另外,工具类PersonCompositeId必须实现序列化Serializable,否则,报出如下异常。
[PersistenceUnit: EntityMappings] Unable to build Hibernate SessionFactoryComposite-id class must implement Serializable: com.gxz.entities.PersonCompositeIdComposite-id class must implement Serializable: com.gxz.entities.PersonCompositeId

持久化

 Person person = new Person();            person.setName("李四");            person.setAge(40);            person.setAdress("广州市");            manager.persist(person);

根据id查找实体

 PersonCompositeId personCompositeId = new PersonCompositeId();            personCompositeId.setName("张三");            personCompositeId.setAge(50);            Person person = manager.find(Person.class, personCompositeId);            if (person != null) {            System.out.println("name:" + person.getName() + " age:" + person.getAge());}

JPA映射之@EmbeddedId

定义工具类

package com.gxz.entities;import java.io.Serializable;import javax.persistence.Embeddable;@Embeddablepublic class PersonCompositeId implements Serializable {private String name;    private long age;    public String getName() {return name;}public void setName(String name) {this.name = name;}public long getAge() {return age;}public void setAge(long age) {this.age = age;}}

@Embeddable:表示该工具类用于组合主键,属性就是组合主键的属性。

定义实体类

package com.gxz.entities;import javax.persistence.EmbeddedId;import javax.persistence.Entity;import javax.persistence.Table;@Entity@Tablepublic class Person {private PersonCompositeId personCompositeId;@EmbeddedId    public PersonCompositeId getPersonCompositeId() {return personCompositeId;}public void setPersonCompositeId(PersonCompositeId personCompositeId) {this.personCompositeId = personCompositeId;}private String adress;    public String getAdress() {return adress;}public void setAdress(String adress) {this.adress = adress;}}
@EmbeddedId:表示该属性是组合主键,类型是组合主键工具类。

持久化

PersonCompositeId personCompositeId = new PersonCompositeId();            personCompositeId.setName("搜噶");            personCompositeId.setAge(100);            person.setPersonCompositeId(personCompositeId);                        person.setAdress("广州市");            manager.persist(person);            transaction.commit();

两种映射方式的比较

第一种方式,工具类和实体类有一模一样的属性,属于冗余,第二种方式则没有没有冗余,显得更加科学。因此,实际工作中,第二种方式更加常用。


0 0
原创粉丝点击