前面已经对Hibernate有了基本的了解,下面说一下Hibernate的各种映射
映射关系包含四种
①一对多 one-to-many
②多对一 many-to-one
③一对一 one-to-one
④多对多 many-to-many
这个里面还区别单向和双向
单向一对多映射
实现核心:在one方持有many方的集合
一个班级包含多个学生,在班级中添加学生的集合List集/Set集
班级是一方,学生是多方
下面以http://sunyuqian.iteye.com/blog/2248913中实例为基础来实现一个单向一对多实例
1.hibernate.cfg.xml
在基础(一)的blog中已经对各个属性进行了说明,在此不赘述。
注意一点是:使用到了getCurrentSession(),所以添加了"hibernate.current_session_context_class"配置
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- oracle数据库驱动 -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<!-- oracle想要连接的数据库名称 -->
<property name="connection.url">jdbc:oracle:thin:@10.1.0.169:1521:orcl</property>
<!-- 数据库的登陆用户名 -->
<property name="connection.username">SUNYQ</property>
<!-- 数据库的登陆密码 -->
<property name="connection.password">123456</property>
<!-- 方言:为每一种数据库提供适配器,方便转换 -->
<property name="hibernate.dialect">org.hibernate.dialect.Oracle9iDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hbm2ddl">create</property>
<mapping resource="Students.hbm.xml"/>
<mapping resource="Grade.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
2.创建持久化实体类
也可在数据库中事先创建出来学生表和班级表,也可以通过配置文件来设置,方式根据需求来定,本文使用配置文件来生成数据库表。
Students类:
package com.iteye.sunyq.hibernate;
public class Students {
public Students() {
}
private int sid;
private String sname;
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Students(String sname) {
super();
this.sname = sname;
}
}
Grade类
package com.iteye.sunyq.hibernate;
import java.util.HashSet;
import java.util.Set;
public class Grade {
public Grade(){
}
private int gid;
private String gname;
private String gdesc;
private Set<Students> studentSet = new HashSet<Students>();
public int getGid() {
return gid;
}
public void setGid(int gid) {
this.gid = gid;
}
public String getGname() {
return gname;
}
public void setGname(String gname) {
this.gname = gname;
}
public String getGdesc() {
return gdesc;
}
public void setGdesc(String gdesc) {
this.gdesc = gdesc;
}
public Set<Students> getStudentSet() {
return studentSet;
}
public void setStudentSet(Set<Students> studentSet) {
this.studentSet = studentSet;
}
public Grade(String gname, String gdesc) {
super();
this.gname = gname;
this.gdesc = gdesc;
}
}
注意:根据一对多映射关系的实现原理-》是在一方持有多方的集合,也就是在Grade.java中包含Students.java的集合。
private Set<Students> studentSet = new HashSet<Students>();
那么通过这种方式生成的表结构是什么样的呢?提前看一下
grade表:
students表:
students表中外键gid:
所以,通过持久化类中包含students集合实际就是students表与grade表gid进行了外键的关联
3.映射文件
Students.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.iteye.sunyq.hibernate.Students" table="students">
<id name="sid" type="integer">
<column name="id"></column>
<generator class="native"></generator>
</id>
<property name="sname" type="string">
<column name="sname"></column>
</property>
</class>
</hibernate-mapping>
Grade.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.iteye.sunyq.hibernate.Grade" table="grade">
<id name="gid" type="integer">
<column name="id"></column>
<generator class="native"></generator>
</id>
<property name="gname" type="string">
<column name="gname"></column>
</property>
<property name="gdesc" >
<column name="gdesc"></column>
</property>
<set name="studentSet">
<key column="gid"/>
<one-to-many class="com.iteye.sunyq.hibernate.Students"></one-to-many>
</set>
</class>
</hibernate-mapping>
注意:
①首先在Students表中的外键gid是不需要写到Students.hbm.xml中的,这个外键是在一方进行维护,就是Grade.hbm.xml中进行维护
②Grade.hbm.xml中外键gid是写在<set>标签中的
<set name="studentSet">
<key column="gid"/><!-- Students表中外鍵名称 -->
<one-to-many class="com.iteye.sunyq.hibernate.Students"></one-to-many><!-- 映射的实体类 -->
</set>
4.Hibernate工具类
对Hibernate的链接数据库抽象到一个工具类中
package com.iteye.sunyq.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class HibernateUtil {
private static SessionFactory sessionFactory;
private static Session session;
static{
Configuration config = new Configuration().configure();
ServiceRegistry service = new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();
sessionFactory = config.buildSessionFactory(service);
}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
public static Session getSession(){
session = sessionFactory.openSession();
return session;
}
public static void closeSession(Session session){
if(session != null)
session.close();
}
}
5.测试:增删改查
注意:通过配置文件建立关联关系之后,可以比较方便的根据一来导航到多的对象
但是,反过来是不可以的,因为是单向的。也就是说可以通过班级来对学生进行一定的操作,而是用学生却不能对班级进行相应的操作。
举例:可以通过班级来查询到该班级下的所有学生对象的信息,而只去查询学生,并不能查询到班级对象的信息。
package com.iteye.sunyq.hibernate;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
public class Test {
public static void main(String[] args) {
addStudent();
findStudent();
deleteStudent();
update();
}
public static void addStudent(){
Session session = HibernateUtil.getSession();
Transaction transaction = session.beginTransaction();
Grade grade = new Grade("班级二","班级二描述");
Students student1 = new Students("王五");
grade.getStudentSet().add(student1);
session.save(grade);
session.save(student1);
transaction.commit();
HibernateUtil.closeSession(session);
}
public static void findStudent(){
Session session = HibernateUtil.getSession();
Transaction transaction = session.beginTransaction();
Grade grade = (Grade) session.get(Grade.class, 1);
System.out.println("班级:"+grade.getGid()+","+grade.getGname()+","+grade.getGdesc());
Set<Students> students = grade.getStudentSet();
for(Students info : students){
System.out.println("学生:"+info.getSid()+""+info.getSname());
}
//注意:因为是单向映射,我们不能通过student的信息来获取到grade信息。
Students s = (Students)session.get(Students.class, 2);
System.out.println("查询学生信息:"+s.getSid()+"-"+s.getSname());
transaction.commit();
HibernateUtil.closeSession(session);
}
public static void deleteStudent(){
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction transaction = session.beginTransaction();
Students student = (Students)session.get(Students.class, 9);
session.delete(student);
transaction.commit();
}
public static void update(){
Session session = HibernateUtil.getSession();
Transaction transaction = session.beginTransaction();
Grade grade = (Grade) session.get(Grade.class, 8);
Students student = (Students) session.get(Students.class, 9);
student.setSname("哈哈");
grade.getStudentSet().add(student);
session.save(grade);
transaction.commit();
HibernateUtil.closeSession(session);
}
}