您现在的位置是:首页
>
mysql怎么添加复合主键 Hibernate复合主键映射
Hi er ate复合主键映射 在日常开发中会遇到这样一种情况 数据库中的某张表需要多个字段列才能唯一确定一行记录 这时表需要使用复合主键 面对这样的情况Hi er ate为我们提供了两种方式来解决复
Hibernate复合主键映射
在日常开发中会遇到这样一种情况 数据库中的某张表需要多个字段列才能唯一确定一行记录 这时表需要使用复合主键 面对这样的情况Hibernate为我们提供了两种方式来解决复合主键问题 方式一 将复合主键对应的属性与实体其他普通属性放在一起 例如实体类People中 id 和 name 属性对应复合主键 public class People implements Serializable { private static final long serialVersionUID = L; private String id; private String name; private int age; public People() { } 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 int getAge() { return age; } public void setAge(int age) { this age = age; } @Override public int hashCode() { final int prime = ; int result = ; result = prime * result + ((id == null) ? : id hashCode()) result = prime * result + ((name == null) ? : name hashCode()) return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj getClass()) return false; People other = (People) obj; if (id == null) { if (other id != null) return false; } else if (!id equals(other id)) return false; if (name == null) { if (other name != null) return false; } else if (!name equals(other name)) return false; return true; } } People hbm xml: <?xml version= encoding= utf ?> <!DOCTYPE hibernate mapping PUBLIC //Hibernate/Hibernate Mapping DTD //EN mapping dtd > <hibernate mapping> <class name= suxiaolei hibernate pojos People table= people > <! 复合主键使用posite id标签 > <posite id> <! key property标签表示哪一些属性对应复合主键 > <key property name= id column= id type= string ></key property> <key property name= name column= name type= string ></key property> </posite id> <property name= age column= age type= integer ></property> </class> </hibernate mapping> Hibernate中使用复合主键时需要注意一些规则 使用复合主键的实体类必须实现Serializable接口 必须实现Serializable接口的原因很简单 我们查找数据的时候是根据主键查找的 打开Hibernate的帮助文档我们可以找到get与load方法的声明形式如下 Object load(Class theClass Serializable id) Object get(Class theClass Serializable id) 当我们查找复合主键类的对象时 需要传递主键值给get()或load()方法的id参数 而id参数只能接收一个实现了Serializable接口的对象 而复合主键类的主键不是一个属性可以表示的 所以只能先new出复合主键类的实例(例如 new People()) 然后使用主键属性的set方法将主键值赋值给主键属性 然后将整个对象传递给get()或load()方法的id参数 实现主键值的传递 所以复合主键的实体类必须实现Serializable接口 使用复合主键的实体类必须重写equals和hashCode方法 必须重写equals和hashCode方法也很好理解 这两个方法使用于判断两个对象 (两条记录)是否相等的 为什么要判断两个对象是否相等呢?因为数据库中的任意两条记录中的主键值是不能相同的 所以我们在程序中只要确保了两个对象的主键值不同就可以防止主键约束违例的错误出现 也许这里你会奇怪为什么不使用复合主键的实体类不重写这两个方法也没有主键违例的情况出现 这是因为使用单一主键方式 主键值是Hibernate来维护的 它会确保主键不会重复 而复合主键方式 主键值是编程人员自己维护的 所以必须重写equals和hashCode方法用于判断两个对象的主键是否相同 重写的equals和hashCode方法 只与主键属性有关 普通属性不要影响这两个方法进行判断 这个原因很简单 主键才能决定一条记录 其他属性不能决定一条记录 保存测试 public class Client { public static void main(String[] args) { Session session = HibernateUtil getSessionFactory() openSession() Transaction tx = null; try { tx = session beginTransaction() People people = new People() people setId( ) people setName( zhangsan ) people setAge( ) session save(people) mit() } catch (Exception e) { if(tx != null) { tx rollback() } e printStackTrace() } finally { session close() } } } 看看数据库 数据被正确的插入到数据库中了 读取数据测试 public class Client { public static void main(String[] args) { Session session = HibernateUtil getSessionFactory() openSession() Transaction tx = null; try { tx = session beginTransaction() People peoplePrimaryKey = new People() peoplePrimaryKey setId( ) peoplePrimaryKey setName( zhangsan ) People people = (People)session get(People class peoplePrimaryKey) System out println( people age is: +people getAge()) mit() } catch (Exception e) { if(tx != null) { tx rollback() } e printStackTrace() } finally { session close() } } } 控制台输出 people age is: 可以看到数据成功的取出了 方式二 将主键属性提取到一个主键类中 实体类只需包含主键类的一个引用 主键类 public class PeoplePrimaryKey implements Serializable { private static final long serialVersionUID = L; private String id; private String name; public PeoplePrimaryKey() { } 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; } @Override public int hashCode() { final int prime = ; int result = ; result = prime * result + ((id == null) ? : id hashCode()) result = prime * result + ((name == null) ? : name hashCode()) return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj getClass()) return false; PeoplePrimaryKey other = (PeoplePrimaryKey) obj; if (id == null) { if (other id != null) return false; } else if (!id equals(other id)) return false; if (name == null) { if (other name != null) return false; } else if (!name equals(other name)) return false; return true; } }
实体类 public class People { private PeoplePrimaryKey peoplePrimaryKey; private int age; public People() { } public PeoplePrimaryKey getPeoplePrimaryKey() { return peoplePrimaryKey; } public void setPeoplePrimaryKey(PeoplePrimaryKey peoplePrimaryKey) { this peoplePrimaryKey = peoplePrimaryKey; } public int getAge() { return age; } public void setAge(int age) { this age = age; } } People hbm xml文件稍有一点变动 <?xml version= encoding= utf ?> <!DOCTYPE hibernate mapping PUBLIC //Hibernate/Hibernate Mapping DTD //EN mapping dtd > <hibernate mapping> <class name= suxiaolei hibernate pojos People table= people > <! 复合主键使用posite id标签 > <! name 指定了复合主键对应哪一个属性 class 指定了复合主键属性的类型 > <posite id name= peoplePrimaryKey class= suxiaolei hibernate pojos PeoplePrimaryKey > <! key property指定了复合主键由哪些属性组成 > <key property name= id column= id type= string ></key property> <key property name= name column= name type= string ></key property> </posite id> <property name= age column= age type= integer ></property> </class> </hibernate mapping> 场景测试与方式一大同小异这里不再举例了 主键类为什么实现Serializable接口和为什么重写equals和hashCode方法上面已经解释的很清楚了 lishixinzhi/Article/program/Java/ky/201311/28901
很赞哦! (1063)