我是如何学习Hibernate的(三)

前述

在学习Struts2、Hibernate、Sping、String MVC、Mybatis等几大框架的时候,并没有使用版本控制软件。我知道版本控制的重要性,所以我在其间学习了Git,我会在学完了Git之后写一篇我如何学习Git的文章。

关联关系

一对一关系映射即为关系双方都含有对方的一个引用,比如人和身份证,学生和学号都是一对一关系映射。(了解)

  • 主表的主键,与从表的外键,形成主外键关系。
    比如:课程编号(课程表中的主键) — 课程编号(学生表中的外键)
  • 主表的主键,与从表的主键,形成主外键关系。(从表的主键是主表的外键)

    一对多

    一对多关系映射中,一方含有多方的一个集合引用,而多方含有一方的单个引用。
    以Customer和Order为例子演示一对多的实现:

    Customer类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package com.hibernate3;

    import java.util.HashSet;
    import java.util.Set;

    import javax.persistence.Entity;
    import javax.persistence.Id;

    public class Customer {

    private Integer uid;
    private String name;
    private Set<Order> orderSet = new HashSet<Order>();
    }

Customer.hbm.xml配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.hibernate3.Customer" table="customer">
<id name="uid" column="id" >
<generator class="native" />
</id>
<set name="orderSet" inverse="true">//inverse=true,表示控制反转,通常由一方交出控制权给多方
<key column="uid" />
<one-to-many class="com.hibernate3.Order"/> //这里写对应的many方的class全名
</set>
<property name="name" column="name" />
</class>
</hibernate-mapping>

Order类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.hibernate3;

import java.util.HashSet;
import java.util.Set;

public class Order {

private Integer oid;
private Integer price;
private Customer customer;
}
```

## Order.hbm.xml配置文件
``` bash
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.hibernate3.Order" table="t_order">
<id name="oid" column="id" >
<generator class="native" />
</id>
<many-to-one name="customer" class="com.hibernate3.Customer" column="uid">
</many-to-one>
<property name="price" />
</class>
</hibernate-mapping>

Hibernate的工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.hibernate3;

import javax.imageio.spi.ServiceRegistry;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtils {

private static SessionFactory sessionFactory;
private static Session session;

static{
Configuration config = new Configuration().configure();
sessionFactory = config.buildSessionFactory();
session=sessionFactory.openSession();
}

public static SessionFactory getSessionFactory() {
return sessionFactory;
}


public static Session getSession() {
return session;
}

public static void closeSession(Session session){
if(session!=null){
session.close();
session=null;
}
}
}

OneToManyDao

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.hibernate3;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class OneToManyDao {

@Test
public void add(){
Session session =HibernateUtils.getSession();
Transaction tc = session.beginTransaction();

Customer c= new Customer();
c.setName("李明辉");
Order o = new Order();
o.setPrice(3);
c.getOrderSet().add(o);
o.setCustomer(c);


session.save(c);
session.save(o);//可交换顺序看看哪种方式是最优方式

tc.commit();
HibernateUtils.closeSession(session);

}
}

多对多

多个学生可以学习 不同课程

1
2
3
4
5
6
7
8
9
/** 学生实体类 */

public class Student {

private Long id; //对象标识符(OID)
private String name; //姓名
private String grade; //所在班级
private Set<Course> courses; //所有所选课程的集合
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<hibernate-mapping>

<!-- 映射持久化类 -->

<class name="com.domain.Student" table="student">

<!-- 映射对象标识符 -->

<id name="id" column="id" type="long">

<generator class="native" />

</id>

<!-- 映射普通属性 -->

<property name="name" />

<property name="grade" />

<!-- 映射集合属性,指定连接表 -->

<set name="courses" table="student_course">

<!-- 用key元素指定本持久类在连接表中的外键字段名 -->

<key column="student_id" />

<!-- 映射多对多关联类 -->

<many-to-many column="course_id"

class="com.omain.Course" />

</set>

</class>

</hibernate-mapping>
1
2
3
4
5
6
7
8
9
/** 课程实体类 */

public class Course {

private Long id; //对象标识符(OID)
private String name; //课程名
private Double creditHours; //课时数
private Set<Student> students; //选择了这门课程的学生的集合
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Course.hbm.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!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.domain.Course" table="course">

<!-- 映射对象标识符 -->

<id name="id" column="id" type="long">

<generator class="native" />

</id>

<!-- 映射普通属性 -->

<property name="name" />

<property name="creditHours" column="credit_hours" />

<!-- 映射集合属性,指定连接表 -->
<!-- inverse="true"表示交出控制权,在多对多关系映射中,必须有一方要设置为true -->
<set name="students" table="student_course" inverse="true">

<!-- 用key元素指定本持久类在连接表中的外键字段名 -->

<key column="course_id" />

<!-- 映射多对多关联类 -->

<many-to-many column="student_id" class="com.domain.Student" />

</set>

</class>

</hibernate-mapping>