一、综述
目前为止项目用到的实体类关系有3种:
- 单向一对多
- 单向多对一
- 双向一对多(双向多对一)
二、说明
@Entity --注释声明该类为持久类。将一个Javabean类声明为一 个实体的数据库表映射类,最好实现序列化.此时,默认情况下,所有的类属性都为映射到数据表的持久性字段.若在类中,添加另外属性,而非映射来数据库的, 要用下面的Transient来注解.
@Table(name="promotion_info") --持久性映射的表(表名="promotion_info).@Table是类一级的注解,定义在@Entity下,为实体bean映射表,目录和schema的名字,默认为实体bean的类名,不带包名.
@Id--注释可以表明哪种属性是该类中的独特标识符(即相当于数据表的主键)。
@GeneratedValue --定义自动增长的主键的生成策略.
@Transient --将忽略这些字段和属性,不用持久化到数据库.适用于,在当前的持久类中,某些属性不是用于映射到数据表,而是用于其它的业务逻辑需要,这时,须将这些属性进行transient的注解.否则系统会因映射不到数据表相应字段而出错.
@Temporal(TemporalType.TIMESTAMP)--声明时间格式
@Enumerated --声明枚举
@Version --声明添加对乐观锁定的支持
@OneToOne --可以建立实体bean之间的一对一的关联
@OneToMany --可以建立实体bean之间的一对多的关联
@ManyToOne --可以建立实体bean之间的多对一的关联
@ManyToMany --可以建立实体bean之间的多对多的关联
@Formula --一个SQL表达式,这种属性是只读的,不在数据库生成属性(可以使用sum、average、max等)
@OrderBy --Many端某个字段排序(List)
特别对于一对多的时候:
// mappedBy相当于过去的inverse="true".
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "myclass")
public Set<Student> getStudents() {
return this.students;
}
其中mappedBy="myclass"为关联表的外键列字段。
其类似在XML中的inverse=true。
三、双向一对多实体类配置
假设有班级和学生2个实体类。
对于一对多或者多对一,就删除另外一方的相关配置即可。
MyClasss
package com.mc.entity;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* Myclass entity. @author MyEclipse Persistence Tools
*/
@Entity
@Table(name = "myclass", catalog = "test")
public class Myclass implements java.io.Serializable {
// Fields
private Integer id;
private String className;
private Set<Student> students = new HashSet<Student>(0);
// Constructors
/** default constructor */
public Myclass() {
}
/** full constructor */
public Myclass(String className, Set<Student> students) {
this.className = className;
this.students = students;
}
// Property accessors
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "ID", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "CLASS_NAME")
public String getClassName() {
return this.className;
}
public void setClassName(String className) {
this.className = className;
}
// mappedBy相当于过去的inverse="true".
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "myclass")
public Set<Student> getStudents() {
return this.students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
Student
package com.mc.entity;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
* Student entity. @author MyEclipse Persistence Tools
*/
@Entity
@Table(name = "student", catalog = "test")
public class Student implements java.io.Serializable {
// Fields
private Integer id;
private Myclass myclass;
private String stuName;
private Timestamp stuBirth;
// Constructors
/** default constructor */
public Student() {
}
/** full constructor */
public Student(Myclass myclass, String stuName, Timestamp stuBirth) {
this.myclass = myclass;
this.stuName = stuName;
this.stuBirth = stuBirth;
}
// Property accessors
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "ID", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "STUCLASS_ID")
public Myclass getMyclass() {
return this.myclass;
}
public void setMyclass(Myclass myclass) {
this.myclass = myclass;
}
@Column(name = "STU_NAME")
public String getStuName() {
return this.stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
@Column(name = "STU_BIRTH", length = 19)
public Timestamp getStuBirth() {
return this.stuBirth;
}
public void setStuBirth(Timestamp stuBirth) {
this.stuBirth = stuBirth;
}
}
四、保存
// Hibernate: insert into test.myclass (CLASS_NAME) values (?)
// Hibernate: insert into test.student (STUCLASS_ID, STU_BIRTH, STU_NAME) values (?, ?, ?)
// 有效
public static void test2() {
Session session = HibernateSessionFactory.getSession();
// Hibernate必须要有这个事物才行。
Transaction beginTransaction = session.beginTransaction();
Student student = new Student();
student.setStuName("LCF88");
Myclass myclass = new Myclass();
myclass.setClassName("JAVA88");
myclass.getStudents().add(student);
student.setMyclass(myclass);
session.save(myclass);
beginTransaction.commit();
session.close();
}
// 有效,3条语句(不推荐)
// Hibernate: insert into test.student (STUCLASS_ID, STU_BIRTH, STU_NAME) values (?, ?, ?)
// Hibernate: insert into test.myclass (CLASS_NAME) values (?)
// Hibernate: update test.student set STUCLASS_ID=?, STU_BIRTH=?, STU_NAME=? where ID=?
public static void test3() {
Session session = HibernateSessionFactory.getSession();
// Hibernate必须要有这个事物才行。
Transaction beginTransaction = session.beginTransaction();
Student student = new Student();
student.setStuName("LCF21");
Myclass myclass = new Myclass();
myclass.setClassName("JAVA21");
student.setMyclass(myclass);
session.save(student);
session.save(myclass);
beginTransaction.commit();
session.close();
}
// 有效,2条语句,推荐,理论上先插入class在插入student
// Hibernate: insert into test.myclass (CLASS_NAME) values (?)
// Hibernate: insert into test.student (STUCLASS_ID, STU_BIRTH, STU_NAME) values (?, ?, ?)
public static void test4() {
Session session = HibernateSessionFactory.getSession();
// Hibernate必须要有这个事物才行。
Transaction beginTransaction = session.beginTransaction();
Student student = new Student();
student.setStuName("LCF22");
Myclass myclass = new Myclass();
myclass.setClassName("JAVA22");
student.setMyclass(myclass);
session.save(myclass);
session.save(student);
beginTransaction.commit();
session.close();
}
// 无效
// Hibernate: insert into test.myclass (CLASS_NAME) values (?)
public static void test5() {
Session session = HibernateSessionFactory.getSession();
// Hibernate必须要有这个事物才行。
Transaction beginTransaction = session.beginTransaction();
Student student = new Student();
student.setStuName("LCF16");
Myclass myclass = new Myclass();
myclass.setClassName("JAVA16");
student.setMyclass(myclass);
session.save(myclass);
beginTransaction.commit();
session.close();
}
推荐第4种,最容易理解,在多的一方进行多的一方的数据的维护。
Demo下载地址如下:https://yunpan.cn/cxhAb54V6BNwJ 访问密码 963b