经过前面的学习,现在是不是学hibernate有点得心应手,那赶紧趁热打铁进行下一章。
映射关系
- 一对多
- 多对一
- 一对一
- 多对多
hibernate单向一对多关联映射实例(一个班级可以有多个学生)
- 创建实体类
package com.example.test.hibernate.entity;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class Grade {
private int gid;
private String gdesc;
private Set<Student> students = new HashSet<Student>();
/* 如何实现一对多映射
在一方其定义多方的集合,可以使用set表示无序的,list表示有序的。*/
public Grade() {
super();
// TODO Auto-generated constructor stub
}
public Grade(int gid, String gdesc, Set<Student> students) {
super();
this.gid = gid;
this.gdesc = gdesc;
this.students = students;
}
public int getGid() {
return gid;
}
public void setGid(int gid) {
this.gid = gid;
}
public String getGdesc() {
return gdesc;
}
public void setGdesc(String gdesc) {
this.gdesc = gdesc;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
public Grade(String gdesc) {
super();
this.gdesc = gdesc;
}
}
package com.example.test.hibernate.entity;
import java.util.Set;
public class Student {
private int sid;
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
private String name;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Student(int sid, String name, String sex) {
super();
this.sid = sid;
this.name = name;
this.sex = sex;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}
}
- 配置数据库映射关系文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-8-6 10:09:41 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.example.test.hibernate.entity.Grade" table="GRADE">
<id name="gid" type="integer">
<column name="GID" />
<generator class="increment" /> <!-- 主键生成策略,自增 -->
</id>
<property name="gdesc" type="java.lang.String">
<column name="GDESC" length="100"/>
</property>
<set name="students" table="STUDENT">
<key column="GID"></key>
<one-to-many class="com.example.test.hibernate.entity.Student"/>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-8-6 10:09:41 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.example.test.hibernate.entity.Student" table="STUDENT">
<id name="sid" type="integer">
<column name="SID" />
<generator class="increment" /> <!-- 主键生成策略,自增 -->
</id>
<property name="name" type="java.lang.String">
<column name="NAME" not-null="true" length="20"/>
</property>
<property name="sex" type="java.lang.String" length="10">
<column name="SEX" />
</property>
</class>
</hibernate-mapping>
- 添加学生,班级
public void testApp() {
Grade g =new Grade("测试一班");
Student s = new Student("刘锦", "男");
Student s1 = new Student("刘锦1", "男");
g.getStudents().add(s);//班级中的得到学生的集合对象,往里面添加学生。
g.getStudents().add(s1);
Session session = HibernateUtils.getSession();
Transaction t = session.beginTransaction();
session.save(g);
session.save(s1);
session.save(s);
t.commit();
HibernateUtils.closeSession();
- 查询学生信息(查询是由班级到学生,注意查询方向)
Session session = HibernateUtils.getSession();
Grade g = session.get(Grade.class,1);//根据Grade主键值取查询
Set<Student> students = g.getStudents();
for(Student s:students){
System.out.println(s.getName()+s.getSex());
}
- 修改学生信息
Student s = session.get(Student.class,1);
Grade g = new Grade("java 2班");
g.getStudents().add(s);
session.save(s);
session.save(g);
Transaction t = session.beginTransaction();
t.commit();
- 删除学生信息
Student s = session.get(Student.class,1);
session.delete(s);
Transaction t = session.beginTransaction();
t.commit();
hibernate单向多对一事例(基于学生----班级)
- 修改持久化类
package com.example.test.hibernate.entity;
import java.util.Set;
public class Student {
private int sid;
private Grade grade;//在多方定义一方的引用,并且提供set、get方法
public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
private String name;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Student(int sid, String name, String sex) {
super();
this.sid = sid;
this.name = name;
this.sex = sex;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}
}
package com.example.test.hibernate.entity;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class Grade {
private int gid;
private String gdesc;
public Grade() {
super();
// TODO Auto-generated constructor stub
}
public int getGid() {
return gid;
}
public void setGid(int gid) {
this.gid = gid;
}
public String getGdesc() {
return gdesc;
}
public void setGdesc(String gdesc) {
this.gdesc = gdesc;
}
public Grade(String gdesc) {
super();
this.gdesc = gdesc;
}
}
- 配置关系映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-8-6 10:09:41 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.example.test.hibernate.entity.Student" table="STUDENT">
<id name="sid" type="integer">
<column name="SID" />
<generator class="increment" /> <!-- 主键生成策略,自增 -->
</id>
<property name="name" type="java.lang.String">
<column name="NAME" not-null="true" length="20"/>
</property>
<property name="sex" type="java.lang.String" length="10">
<column name="SEX" />
</property>
<!--配置多对一关系 -->
<many-to-one name="grade" class="com.example.test.hibernate.entity.Grade" column="GID"></many-to-one>
</class>
</hibernate-mapping>
- 添加学生信息
Grade g = new Grade("java 3班");
Student s = new Student("刘锦2", "男");
Student s1 = new Student("刘锦3","男");
s.setGrade(g);//通过这个可以给学生设置相应的班级的gid。
s1.setGrade(g);
session.save(g);
session.save(s);
session.save(s1);
t.commit();
hibernate双向关联
在上述的例子中,学生到班级是单向多对一的关联,班级到学生是单向的一对多的关联,但是在实际中,班级和学生可能是双向,所以推出下面你的方法:
在一方和多方中都进行关联关系配置:
package com.example.test.hibernate.entity;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class Grade {
private int gid;
private String gdesc;
private Set<Student> students = new HashSet<Student>();
/* 如何实现一对多映射
在一方其定义多方的集合,可以使用set表示无序的,list表示有序的。*/
public Grade() {
super();
// TODO Auto-generated constructor stub
}
public Grade(int gid, String gdesc, Set<Student> students) {
super();
this.gid = gid;
this.gdesc = gdesc;
this.students = students;
}
public int getGid() {
return gid;
}
public void setGid(int gid) {
this.gid = gid;
}
public String getGdesc() {
return gdesc;
}
public void setGdesc(String gdesc) {
this.gdesc = gdesc;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
public Grade(String gdesc) {
super();
this.gdesc = gdesc;
}
}
package com.example.test.hibernate.entity;
import java.util.Set;
public class Student {
private int sid;
private Grade grade;//在多方定义一方的引用,并且提供set、get方法
public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
private String name;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Student(int sid, String name, String sex) {
super();
this.sid = sid;
this.name = name;
this.sex = sex;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}
}
对象关系映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-8-6 10:09:41 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.example.test.hibernate.entity.Grade" table="GRADE">
<id name="gid" type="integer">
<column name="GID" />
<generator class="increment" /> <!-- 主键生成策略,自增 -->
</id>
<property name="gdesc" type="java.lang.String">
<column name="GDESC" length="100"/>
</property>
<set name="students" table="STUDENT">
<key column="GID"></key>
<one-to-many class="com.example.test.hibernate.entity.Student"/>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-8-6 10:09:41 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.example.test.hibernate.entity.Student" table="STUDENT">
<id name="sid" type="integer">
<column name="SID" />
<generator class="increment" /> <!-- 主键生成策略,自增 -->
</id>
<property name="name" type="java.lang.String">
<column name="NAME" not-null="true" length="20"/>
</property>
<property name="sex" type="java.lang.String" length="10">
<column name="SEX" />
</property>
<!--配置多对一关系 -->
<many-to-one name="grade" class="com.example.test.hibernate.entity.Grade" column="GID"></many-to-one>
</class>
</hibernate-mapping>
添加学生:
Grade g = new Grade("java 3班");
Student s = new Student("刘锦2", "男");
Student s1 = new Student("刘锦3","男");
g.getStudents().add(s1);
g.getStudents().add(s);
s.setGrade(g);
s1.setGrade(g);
session.save(g);
session.save(s);
session.save(s1);
t.commit();
在这里因为进行了两次关联,所以他会多执行update,长期以往会影响性能,解决办法:
inverse
- <set>节点的inverse属性指定关联关系的控制方向,默认由one维护。
- 关联关系中,inverse设置为false,则主动方,由主动方负责维护关系。
- 在一对多关联中,只能设置one方的inverse为true,这将有助于性能改善。
修改下面,即可解决上述问题:
<set name="students" table="STUDENT" inverse="true">
<key column="GID"></key>
<one-to-many class="com.example.test.hibernate.entity.Student"/>
</set>
cascade级联
在上述的代码保存时,我们已经将学生添加到班级中,在save班级的时候,可不可以不save学生,由此引出级联。
cascade属性的设置会带来性能上的变动,需要谨慎设置
- all 对所有操作进行级联操作
- save-update 执行保存和更新操作进行级联操作
- delete 执行删除操作时进行级联操作
- none 对所有操作不进行级联操作
双向关联
基于上述的例子中,进行了学生和班级的双向配置,这样的话,可以由学生查找到班级,也可以由班级查找到学生信息,这点需要区别单向。
Myeclipse添加数据库连接
在myeclipse中将项目开发模式调成hibernate开发视图,如下图:
点击db browers 新建一个数据库连接,进入下面的配置:
需要根据大家使用的数据库类型进行配置。配置成功,就可以在myeclipse中查看数据库信息。
Myeclipse中添加hibernate支持
先创建一个java project,右击项目名选择myeclipse,project facts,找到hibernate开始添加,但是根据不同版本的myeclipse,所支持的hibernate是有不同。
这个图上告诉我们的,就是hibernate配置信息是放在src下,还有就是是否要创建一个sessionFactory,你需要为它创建一个包。这个工厂里提供了一个方法就是获取session。
在上面我们已经在myeclipse上创建了数据库连接,在这里可以拿过来直接用。
选择hibernate核心包
经过上述的配置,已经完成项目对hibernate的支持,打开配置信息,你会发现已经配置完成了。
hibernate的反向工程
他可以根据数据库的表创建的持久化类和表与表的映射关系。
首先将hibernate切换到hibernate模式下,选中两种你需要反向生成的表,右击有个hibernate 反向,进入如下图:
在其中需要填写的是要填写项目的src目录,和存放表的持久化类和映射文件的包,勾选的是,询问是否一定要创建hbm文件和将映射文件是否添加到配置文件中,这些都是必须选的。
在这步中不需要,进行其他修改,只需要进行数据库主键的生成策略修改,这里使用的是mysql的自增长。
在完成上述的配置,项目多出以下变化:
经过这样,我们就在也不需要麻烦进行编写hbm文件了。