实体关联:
一般有两种方式:
第一种是annotation方式(注解方式):在hibernate配置文件中加入
<mapping class="com.neusoft.hibernate.Student"/>
1定义嵌入类private Grade grade;//grade为枚举类型
//@Enumerated(EnumType.STRING)
@Enumerated(EnumType.ORDINAL)
2定义暂态属性
@Transient
public String getAddress() {
return address;
}
3定义序列
@SequenceGenerator( name="tea", sequenceName="teacher_seq")//GeneratedValue中调用
例如在对应id属性上加上@GeneratedValue(strategy= GenerationType.SEQUENCE, generator="tea")
4联合主键@Id(TeacherPk必需可序列化)
private TeacherPk pk
@EmbeddedId
public TeacherPk getPk() {
return pk;
}
public void setPk(TeacherPk pk) {
this.pk = pk;
}
@Entity//只能用在类上,用于定义一个Hibernate管理的bean
@Table(name="表名")//对应数据库表的名字,默认和类名相同的表
public class Student {
private int id;
private String name;
private double score;
private Date birthday;
private Set<Course> courses=new HashSet<Course>();
@ManyToMany
//定义联合表的名字和相应列
@JoinTable(name="s_c", joinColumns={@JoinColumn(name="s_id")},
inverseJoinColumns={@JoinColumn(name="c_id")})
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
}
@Id//定义标示符
@GeneratedValue//用默认方式
//属性有1strategy:设定生成策略(有四种:table,sequence,identity,auto),默认为auto 属性2 generator
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
//@Column(name="列名")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//定义日期类型默认为TIMESTAMP另外可选值Date和Time
//@Temporal(TemporalType.TIME)
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
第二种通过xml方式:在hibernate配置文件中加入
<mapping resource="com/neusoft/entity/Address.hbm.xml"/>
注意级联(<many-to-one cascade="true">)
一对多(多对一):
a)多对一单向关联
annotation:在多方的实体类中添加@ManyToOne
如果需要修改关联字段的名字,添加@JoinColumn(name="Class_ID")
xml:
在多方xml文件中添加
<hibernate-mapping package="com.neusoft.entity">
<class name="Person">
<id name="id">
<generator class="native"></generator>
<!--自动生成id -->
</id>
<property name="name"></property>
<property name="age"></property>
<many-to-one name="address" class="Address"></many-to-one>
<!--many-to-one 和propertity层次相同-->
</class>
</hibernate-mapping>
b)一对多单向关联(会生成中间表)
annotation:在一方中实体类中加入 private Set<Student> stus=new HashSet<Student>();
在一方的实体类中添加@OneToMany
XML:
在一方添加
<hibernate-mapping package="com.neusoft.hibernate">
<class name="Class" >
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<set name="stus">
<key column="c_id"></key>
<one-to-many class="Student"/>
</set>
<!-- set和propertity层次相同-->
</class>
</hibernate-mapping>
c)一对多(多对一)双向关联
annotation:在多方添加@ManyToOne,
在一方添加@OneToMany(mappedBy="c")由另一个many的c(c为many中一个属性)维护关系
xml:在一方添加:
<set name="stus">
<key column="c_id"></key>
<one-to-many class="Student"/>
</set>
在多方添加:
<many-to-one name="c" class="Class" column="c_id"></many-to-one>
d)多对多:
1单向关联
annotation:在某一方添加@ManyToMany
如果需要修改中间表的表名、列名
@JoinTable(name="s_c", joinColumns={@JoinColumn(name="s_id")},
inverseJoinColumns={@JoinColumn(name="c_id")})
xml:
<set name="courses" table="stu_course">
<key column="stu_id"></key>
<many-to-many class="Course" column="CID"></many-to-many>
</set>
2双向关联:
annotation:双方均添加@ManyToMany,在其中一方上添加 (mappedBy="courses")
由另一个many的courses(courses为many中一个属性)维护关系
xml: inverse="true"关系由另一方维护默认为false关系由双方维护
<set name="courses" inverse="true" >
<key column="stu_id"></key>
<many-to-many class="Course"></many-to-many>
</set>
<set name="stus" table="stu_course" inverse="false">
<key column="CID"></key>
<many-to-many class="Student" column="stu_id"></many-to-many>
</set>
有关联关系的CRUD的级联:
添加:cascade={CascadeType.ALL}
查询:fetch
一对多默认值是LAZY(懒执行,如果用不到数据不执行查询)
多对一默认值是EAGER(渴望默认查询所有)
千万不要双方均设EAGER
修改:
删除:双方均做了级联,级联删除,数据有可能都删掉
解决方法:
1)取消关联关系:将对应属性 setXxx(null);
2)HQL:
Query q=session.createQuery("delete from Student s where id=211");
q.executeUpdate();