Hibernate 创建复合主键的步骤

Hibernate 创建复合主键的步骤


今天在恢复wordpress数据表xxx_term_relationships 的数据的时候,出现了主键重复问题

如下面的数据


INSERT INTO `xxx_term_relationships` (`object_id`, `term_taxonomy_id`, `term_order`) VALUES
(1, 3, 0),
(1, 2, 0),
(7, 5, 0),
(7, 4, 0),
(10, 7, 0),
(10, 2, 0);
这条数据不能正常的被更新


因为主键是重复的,第二个和第三个字段也有重复的,我们都知道,主键是不能重复的

后来查看数据库结果发现,他是这样的结构


CREATE TABLE IF NOT EXISTS `xxx_term_relationships` (
  `object_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `term_taxonomy_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `term_order` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`object_id`,`term_taxonomy_id`),
  KEY `term_taxonomy_id` (`term_taxonomy_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
就是说创建了一个复合主键



那么在Hibernate中如何实现呢

需要写两个两个类,一个类是主键类,一个类是我们普通的实体类,然后在实体类中注入主键类即可

主键类,里面包含了主键的信息,一个无参的构造函数,一个有参的构造函数,参数为主键,重新hashCode和equals

如下面的代码所示


package springMVC.NLoveB.po;

import java.io.Serializable;

public class Term_relationships_map implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private int objectid;		//文章id
	private int taxonomyid;		//分类方法id
	
	public Term_relationships_map(){
		
	}
	
	public Term_relationships_map(int objectid,int taxonomyid){
		this.objectid=objectid;
		this.taxonomyid=taxonomyid;
	}
	
	public int getObjectid() {
		return objectid;
	}

	public void setObjectid(int objectid) {
		this.objectid = objectid;
	}

	public int getTaxonomyid() {
		return taxonomyid;
	}

	public void setTaxonomyid(int taxonomyid) {
		this.taxonomyid = taxonomyid;
	}
	
	public int hashCode() {  
        final int PRIME = 31;  
        int result = 1;  
        result = PRIME * result + (objectid == 0 ? 0 : String.valueOf(objectid).hashCode());  
        result = PRIME * result + (taxonomyid == 0 ? 0 : String.valueOf(taxonomyid).hashCode());   
        return result;  
    } 
	
	public boolean equals(Object obj) {  
        if(this == obj) return true;  
        if(obj == null) return false;  
        if(!(obj instanceof Term_relationships_map)) return false;  
        Term_relationships_map objKey = (Term_relationships_map)obj;  
        if(objectid==(objKey.objectid) && taxonomyid==(objKey.taxonomyid)) {  
            return true;  
        }  
        return false;  
    } 
}
然后是实体类,实体类就是一个普通的实体类,只是需要我们添加 一个注解 @IdClass(Term_relationships_map.class)  这个注解中的参数就是上面的主键类,然后把主键用@id标注


实体类如下:


@Entity(name="term_relationships")
@Table(name="blog_term_relationships")
@DynamicInsert(value = true)
@DynamicUpdate(value = true)
@IdClass(Term_relationships_map.class)
public class Term_relationships {
	private int objectid;		//文章id
	private int taxonomyid;		//分类方法id
	private int order;			//排序
	
	@Id
	@Column(name = "object_id", unique = false, nullable = false,columnDefinition="bigint(20) NOT NULL DEFAULT '0'")
	public int getObjectid() {
		return objectid;
	}
	public void setObjectid(int objectid) {
		this.objectid = objectid;
	}
	
	@Id
	@Column(name = "term_taxonomy_id", unique = false, nullable = false,columnDefinition="bigint(20) NOT NULL DEFAULT '0'")
	public int getTaxonomyid() {
		return taxonomyid;
	}
	public void setTaxonomyid(int taxonomyid) {
		this.taxonomyid = taxonomyid;
	}
	
	@Column(name = "term_order", unique = false, nullable = false,columnDefinition="int(11) NOT NULL DEFAULT '0'")
	public int getOrder() {
		return order;
	}
	public void setOrder(int order) {
		this.order = order;
	}
	
	
}
需要注意的是,这里的主键不是唯一的了,也就是unique=false了,不能是true否则会出错,所有的主键都应该标注unique=false,当然根据您自己的业务需求,也可以是unique=true



爆款云服务器s6 2核4G 低至0.46/天,具体规则查看活动详情Blog Img