文章目录
- 1 基于HBM文件的配置
- 2 Annotation配置
首先在开发之中复合主键是一中强烈不建议使用的技术,在任何一张数据表里面如果要设置主键应该只设置一个字段,但是复合主键毕竟属于标准的SQL语法,所以在Hibernate或者是JPA之中也都有复合主键的定义支持。
范例:数据库脚本
-- 删除数据表 DROP TABLE IF EXISTS member; -- 创建数据表 CREATE TABLE member( mid VARCHAR(50), mname VARCHAR(50), mage INT, CONSTRAINT pk_mid_name PRIMARY KEY(mid,name) );
此时设置了两个主键,但是一定要记住一点,主键不应该重复,所以在随后生成Hibernate操作的时候就要观察它生成类的形式。
1 基于HBM文件的配置
范例:定义MemberId类
@SuppressWarnings("serial") public class MemberId implements java.io.Serializable { // Fields private String mid; private String mname; }
为了能够确定唯一,在这个MemberId类里面必须要覆写equals()和hashCode()两个方法。
范例:在Member类里面利用MemberId来描述复合主键
@SuppressWarnings("serial") public class Member implements java.io.Serializable { // Fields private MemberId id; private Integer mage; }
随后需要观察Member.hbm.xml文件的组成。
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "https://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <hibernate-mapping> <class name="org.lks.pojo.Member" table="member" catalog="hedb"> <!-- 取代的是id元素,表示此时的id是一个复合主键 --> <composite-id name="id" class="org.lks.pojo.MemberId"> <key-property name="mid" type="java.lang.String"> <column name="mid" length="50" /> </key-property> <key-property name="mname" type="java.lang.String"> <column name="mname" length="50" /> </key-property> </composite-id> <property name="mage" type="java.lang.Integer"> <column name="mage" /> </property> </class> </hibernate-mapping>
范例:测试代码
package org.lks.test; import org.lks.dbc.HibernateSessionFactory; import org.lks.pojo.Member; import org.lks.pojo.MemberId; public class TestMemberInsert { public static void main(String[] args) { MemberId id = new MemberId(); id.setMid("3161301220"); id.setMname("lks"); Member vo = new Member(); vo.setId(id); vo.setMage(23); HibernateSessionFactory.getSession().save(vo); HibernateSessionFactory.getSession().beginTransaction().commit(); HibernateSessionFactory.closeSession(); System.exit(0); } }
Hibernate: insert into hedb.member (mage, mid, mname) values (?, ?, ?)
此时信息可以正常保存(复合主键不重复)。
当然在进行数据查询的时候也有一些需要注意的概念,既然ID不能够重复,所以在数据查询中使用的get()方法来讲就必须考虑到复合主键不能重复的特点,所以才覆写了hashCode()以及equals()方法。
范例:数据查询
package org.lks.test; import org.lks.dbc.HibernateSessionFactory; import org.lks.pojo.Member; import org.lks.pojo.MemberId; public class TestMemberGet { public static void main(String[] args) { MemberId id = new MemberId(); id.setMid("3161301220"); id.setMname("lks"); Member vo = (Member)HibernateSessionFactory.getSession().get(Member.class, id); System.out.println(vo); HibernateSessionFactory.closeSession(); System.exit(0); } }
Hibernate: select member0_.mid as mid1_0_0_, member0_.mname as mname2_0_0_, member0_.mage as mage3_0_0_ from hedb.member member0_ where member0_.mid=? and member0_.mname=? org.lks.pojo.Member@3d7fa3ae
所有的类的属性都会自动的根据配置进行不同类型的关系组成。
2 Annotation配置
虽然复合主键出现较少,但是在JPA的开发标准中依然支持了复合主键映射,并且这个复合主键的映射与之前的细粒度划分不同,它可以完美的配置。
范例:观察生成的MemberId程序类
package org.lks.pojo; import javax.persistence.Column; import javax.persistence.Embeddable; /** * MemberId entity. @author MyEclipse Persistence Tools */ @SuppressWarnings("serial") @Embeddable public class MemberId implements java.io.Serializable { // Fields private String mid; private String mname; // Constructors /** default constructor */ public MemberId() { } /** full constructor */ public MemberId(String mid, String mname) { this.mid = mid; this.mname = mname; } // Property accessors @Column(name = "mid", nullable = false, length = 50) public String getMid() { return this.mid; } public void setMid(String mid) { this.mid = mid; } @Column(name = "mname", nullable = false, length = 50) public String getMname() { return this.mname; } public void setMname(String mname) { this.mname = mname; } public boolean equals(Object other) { if ((this == other)) return true; if ((other == null)) return false; if (!(other instanceof MemberId)) return false; MemberId castOther = (MemberId) other; return ((this.getMid() == castOther.getMid()) || (this.getMid() != null && castOther.getMid() != null && this.getMid().equals(castOther.getMid()))) && ((this.getMname() == castOther.getMname()) || (this.getMname() != null && castOther.getMname() != null && this.getMname().equals(castOther.getMname()))); } public int hashCode() { int result = 17; result = 37 * result + (getMid() == null ? 0 : this.getMid().hashCode()); result = 37 * result + (getMname() == null ? 0 : this.getMname().hashCode()); return result; } }
范例:观察Member.java类
package org.lks.pojo; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.Table; /** * Member entity. @author MyEclipse Persistence Tools */ @SuppressWarnings("serial") @Entity @Table(name = "member", catalog = "hedb") public class Member implements java.io.Serializable { // Fields private MemberId id; private Integer mage; // Constructors /** default constructor */ public Member() { } /** minimal constructor */ public Member(MemberId id) { this.id = id; } /** full constructor */ public Member(MemberId id, Integer mage) { this.id = id; this.mage = mage; } // Property accessors @EmbeddedId @AttributeOverrides({ @AttributeOverride(name = "mid", column = @Column(name = "mid", nullable = false, length = 50)), @AttributeOverride(name = "mname", column = @Column(name = "mname", nullable = false, length = 50)) }) public MemberId getId() { return this.id; } public void setId(MemberId id) { this.id = id; } @Column(name = "mage") public Integer getMage() { return this.mage; } public void setMage(Integer mage) { this.mage = mage; } }
由于有开发工具的支持,使用复合主键比较方便。
数据库技术:10 15 Hibernate之复合主键映射地址:https://blog.csdn.net/weixin_43762330/article/details/107139357
需要了解更多数据库技术:10 15 Hibernate之复合主键映射,都可以关注数据库技术分享栏目—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/dtteaching/629322.html