Hibernate框架-联合主键映射
来源:互联网 发布:电脑主题壁纸软件 编辑:程序博客网 时间:2024/05/22 04:36
Hibernate联合主键映射
Hibernate允许直接将实体类的多个属性映射成联合主键,如果需要直接将实体类的多列映射成联合主键,则该实体类必须满足如下条件:
i. 有无参的构造方法
ii. 实现Java.io.Serializable接口
iii. 建议根据联合主键列所映射的属性来重写equals()和hashCode()方法
例:
import java.io.Serializable;import java.util.Date;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.EnumType;import javax.persistence.Enumerated;import javax.persistence.Id;import javax.persistence.Table;import javax.persistence.Temporal;import javax.persistence.TemporalType;@Entity@Table(name="teacher")public class Teacher implements Serializable{ private static final long serialVersionUID = 4938691487727505015L; private int id; private String name; private Title title; private Date date; @Id //!! public int getId() { return id; } public void setId(int id) { this.id = id; } @Id //!! @Column(length=50) public String getName() { return name; } public void setName(String name) { this.name = name; } @Enumerated(EnumType.STRING) public Title getTitle() { return title; } public void setTitle(Title title) { this.title = title; } @Temporal(TemporalType.DATE) public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } @Override //重写equals()方法,根据id, name进行判断 public boolean equals(Object obj) { if(obj == null) { return false; } if(obj instanceof TeacherPk) { TeacherPk pk = (TeacherPk) obj; if(this.id == pk.getId() && this.name.equals(pk.getName())) { return true; } return false; } return false; } @Override public int hashCode() { return this.getName().hashCode(); }}
测试方法:
@Test public void Teacher() { Teacher teacher = new Teacher(); teacher.setId(1); teacher.setName("teacher"); teacher.setTitle(Title.A); teacher.setDate(new Date()); SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); session.save(teacher); transaction.commit(); session.close(); HibernateUtil.close(); }
控制台日志
尝试插入相同的记录
传统方式
如果使用传统方式来开发Hibernate实体类,则实体类的设计不同于单一主键时:要将属于联合主键的字段从实体类中分离,单独建立一个主键类,这个主键类要求拥有无参的构造方法、实现**Java.io.Serializable**接口和重写**equals()**和**hashCode()**方法,因为数据库是要根据不同的字段的值判断是否为唯一主键的,那么判断机制肯定不能够和以往基于单一主键的判断机制相同。
实体类
public class Student { private int id; private String name; private int age; 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; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}
XML方式:
现在要改造为联合主键(id和name字段)
首先将id和name分离出去,建立主键类
//主键类import java.io.Serializable;public class StudentPk implements Serializable{ private static final long serialVersionUID = 8538253779495022662L; 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 boolean equals(Object obj) { if(obj == null) { return false; } if(obj instanceof StudentPk) { StudentPk pk = (StudentPk) obj; if(this.id == pk.getId() && this.name.equals(pk.getName())) { return true; } return false; } return false; } @Override public int hashCode() { return this.name.hashCode(); }}
新的实体类
public class Student { private StudentPk pk = null; private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public StudentPk getPk() { return pk; } public void setPk(StudentPk pk) { this.pk = pk; }}
student.hbm.xml文件
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="pers.msidolphin.hibernate.domain"> <class name="Student" table="_STUDENT"> <!--这个name属性指定的是主键对象在实体类中的属性名 class当然是主键类对应的完整类名--> <composite-id name="pk" class="pers.msidolphin.hibernate.domain.StudentPk"> <!--映射联合主键里的各个属性--> <key-property name="id" column="ID"></key-property> <key-property name="name" column="NAME" length="50"></key-property> </composite-id> <property name="age" column="AGE"/> </class></hibernate-mapping>
测试方法:
@Test public void Student() { Student stu = new Student(); StudentPk pk = new StudentPk(); pk.setId(1); pk.setName("admin"); stu.setAge(21); stu.setPk(pk); Configuration cfg = new Configuration(); cfg = cfg.configure(); SessionFactory sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); Transaction transaction = session.beginTransaction(); session.save(stu); transaction.commit(); session.close(); sf.close(); }
控制台日志打印出的建表语句,primary key(id, name)说明以id和name字段建立了联合主键
查看插入结果:
尝试插入相同的记录
注解(Annotation)方式:
有三种:
i. **@Embeddable**:将主键类注解为@Embeddable,并将实体类的主键类对象属性加上@Id注解
ii. **@EmbeddedId**:直接把实体类的主键类对象属性加上此注解
iii. **@IdClass**:在实体类加上@IdClass注解,并且将该实体类中所有属于主键的属性都注解为@Id(这种方式在实体类中保留了主键字段,但是还是要依赖主键类)
@Embeddable方式:
实体类:
import java.util.Date;import javax.persistence.Entity;import javax.persistence.EnumType;import javax.persistence.Enumerated;import javax.persistence.Id;import javax.persistence.Temporal;import javax.persistence.TemporalType;@Entity@Table(name="teacher1")public class Teacher { private TeacherPk pk = null; private Title title; private Date date; @Id //!! public TeacherPk getPk() { return pk; } public void setPk(TeacherPk pk) { this.pk = pk; } @Enumerated(EnumType.STRING) public Title getTitle() { return title; } public void setTitle(Title title) { this.title = title; } @Temporal(TemporalType.DATE) public Date getDate() { return date; } public void setDate(Date date) { this.date = date; }}
主键类:
import java.io.Serializable;import javax.persistence.Column;import javax.persistence.Embeddable;@Embeddable //!!public class TeacherPk implements Serializable{ private static final long serialVersionUID = 1084438907442149399L; private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(length=50) public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public boolean equals(Object obj) { if(obj == null) { return false; } if(obj instanceof TeacherPk) { TeacherPk pk = (TeacherPk) obj; if(this.id == pk.getId() && this.name.equals(pk.getName())) { return true; } return false; } return false; } @Override public int hashCode() { return this.name.hashCode(); }}
测试结果:
@EmbeddedId方式:
实体类:
import java.util.Date;import javax.persistence.EmbeddedId;import javax.persistence.Entity;import javax.persistence.EnumType;import javax.persistence.Enumerated;import javax.persistence.Temporal;import javax.persistence.TemporalType;@Table(name="teacher2")public class Teacher2 { private TeacherPk2 pk = null; private Title title; private Date date; @EmbeddedId //!! public TeacherPk2 getPk() { return pk; } public void setPk(TeacherPk2 pk) { this.pk = pk; } @Enumerated(EnumType.STRING) public Title getTitle() { return title; } public void setTitle(Title title) { this.title = title; } @Temporal(TemporalType.DATE) public Date getDate() { return date; } public void setDate(Date date) { this.date = date; }}
主键类:
import java.io.Serializable;import javax.persistence.Column;public class TeacherPk2 implements Serializable{ private static final long serialVersionUID = 1084438907442149399L; private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(length=50) public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public boolean equals(Object obj) { if(obj == null) { return false; } if(obj instanceof TeacherPk2) { TeacherPk2 pk = (TeacherPk2) obj; if(this.id == pk.getId() && this.name.equals(pk.getName())) { return true; } return false; } return false; } @Override public int hashCode() { return this.name.hashCode(); }}
测试结果:
@IdClass方式:
实体类:
import java.util.Date;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.EnumType;import javax.persistence.Enumerated;import javax.persistence.Id;import javax.persistence.IdClass;import javax.persistence.Temporal;import javax.persistence.TemporalType;@Entity()@Table(name="teacher3")@IdClass(TeacherPk3.class) //!!public class Teacher3 { private int id; private String name; private Title title; private Date date; @Id //!! public int getId() { return id; } public void setId(int id) { this.id = id; } @Id //!! @Column(length=50) public String getName() { return name; } public void setName(String name) { this.name = name; } @Enumerated(EnumType.STRING) public Title getTitle() { return title; } public void setTitle(Title title) { this.title = title; } @Temporal(TemporalType.DATE) public Date getDate() { return date; } public void setDate(Date date) { this.date = date; }}
主键类:
- Hibernate框架-联合主键映射
- Hibernate映射联合主键
- Hibernate联合主键映射
- hibernate映射联合主键
- Hibernate联合主键映射
- Hibernate联合主键映射
- Hibernate联合主键映射
- Hibernate联合主键映射
- hibernate联合主键映射
- Hibernate联合主键映射
- Hibernate联合主键映射
- Hibernate联合主键映射以及组件映射
- Hibernate 映射视图的联合主键
- 联合主键用Hibernate注解映射方式
- hibernate里联合主键composite-id映射
- Hibernate中联合主键映射学习
- hibernate基于注解的联合主键映射
- hibernate笔记-009-联合主键一对一映射
- hdu1702 Java 栈和队列
- LeetCode 599. Minimum Index Sum of Two Lists(map,unordered_map)
- tensorflow设置log等级
- JSONObject使用方法
- jquery的.post和 .ajax的区别
- Hibernate框架-联合主键映射
- POJ-1330(LCA算法之RMQ)
- arduino读取处理UWB(匿名科技的)数据集
- Glide加载图片并保存到本地返回file,bitmap
- leetcode | 最大装水量问题 | python
- charAt()使用
- Java网络编程——第九章 服务端Sokcet
- jQuery语法结构
- 给IT新人的15点建议:苦逼程序员的辛酸反省与总结