转自:http://www.blogjava.net/DoubleJ/archive/2008/03/04/183781.html
Hibernate 3.x 提供的session的检索策略默认为延时加载.他有以下优点:
减少数据库并发性
减少数据的IO次数
下面的例子是关于session的延时加载的例子.
建立数据库example1
1
# SQL Manager 2005 Lite for MySQL 3.6.5.8
2
# ---------------------------------------
3
# Host : localhost
4
# Port : 3306
5
# Database : example1
6
7
8
/**//*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
9
/**//*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
10
/**//*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
11
/**//*!40101 SET NAMES gb2312 */;
12
13
SET FOREIGN_KEY_CHECKS=0;
14
15
DROP DATABASE IF EXISTS `example1`;
16
17
CREATE DATABASE `example1`
18
CHARACTER SET 'gbk'
19
COLLATE 'gbk_chinese_ci';
20
21
USE `example1`;
22
23
#
24
# Structure for the `department` table :
25
#
26
27
DROP TABLE IF EXISTS `department`;
28
29
CREATE TABLE `department` (
30
`d_id` int(11) NOT NULL auto_increment,
31
`d_name` varchar(20) NOT NULL,
32
PRIMARY KEY (`d_id`),
33
UNIQUE KEY `d_name` (`d_name`)
34
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
35
36
#
37
# Data for the `department` table (LIMIT 0,500)
38
#
39
40
INSERT INTO `department` (`d_id`, `d_name`) VALUES
41
(1,'Office');
42
43
COMMIT;
44
45
#
46
# Structure for the `emplyee` table :
47
#
48
49
DROP TABLE IF EXISTS `emplyee`;
50
51
CREATE TABLE `emplyee` (
52
`e_id` int(11) NOT NULL auto_increment,
53
`e_name` varchar(20) NOT NULL,
54
`e_login_name` varchar(20) NOT NULL,
55
`e_password` varchar(20) NOT NULL,
56
`e_reg_date` date default NULL,
57
`d_id` int(11) default NULL,
58
PRIMARY KEY (`e_id`),
59
UNIQUE KEY `e_login_name` (`e_login_name`),
60
KEY `d_id` (`d_id`),
61
CONSTRAINT `emplyee_fk` FOREIGN KEY (`d_id`) REFERENCES `department` (`d_id`)
62
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
63
64
#
65
# Data for the `emplyee` table (LIMIT 0,500)
66
#
67
68
INSERT INTO `emplyee` (`e_id`, `e_name`, `e_login_name`, `e_password`, `e_reg_date`, `d_id`) VALUES
69
(1,'YiJun','DoubleJ','windows','2008-03-01',1),
70
(2,'ZhangSan','Zs','windows','2008-03-04',1);
71
72
COMMIT;
73
74
75
76
/**//*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
77
/**//*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
78
/**//*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

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

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76


77


78


新建一javaWeb工程,取名为 DJ_HIBERNATE
在MyEclipse里的database Explorer建立数据源,连接上example1数据库,并将hibernate 3.0导入到工程中!
创建以下类:
org.dj.pojo.DepartmentPojo.java









































































并在org.dj.pojo包下创建DepartmentPojo.hbm.xml关系配置文件
1
<?xml version="1.0"?>
2
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
3
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
4
<hibernate-mapping>
5
<class name="org.dj.pojo.DepartmentPojo" table="department">
6
<id name="did" column="d_id" type="java.lang.Integer">
7
<generator class="native"></generator>
8
</id>
9
<property name="dname" column="d_name"
10
type="java.lang.String">
11
</property>
12
<set name="emps">
13
<key column="d_id"></key>
14
<one-to-many class="org.dj.pojo.EmplyeePojo" />
15
</set>
16
</class>
17
</hibernate-mapping>

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

再创建org.dj.pojo.EmplyeePojo类,
1
package org.dj.pojo;
2
3
import java.sql.Date;
4
5
public class EmplyeePojo
{
6
private Integer eid;
7
8
private String ename;
9
10
private String eloginName;
11
12
private String epassword;
13
14
private java.sql.Date eregDate;
15
16
private DepartmentPojo department;
17
18
public DepartmentPojo getDepartment()
{
19
return department;
20
}
21
22
public void setDepartment(DepartmentPojo department)
{
23
this.department = department;
24
}
25
26
public EmplyeePojo()
{
27
// TODO Auto-generated constructor stub
28
}
29
30
public EmplyeePojo(String ename, String eloginName, String epassword,
31
Date eregDate)
{
32
super();
33
this.ename = ename;
34
this.eloginName = eloginName;
35
this.epassword = epassword;
36
this.eregDate = eregDate;
37
}
38
39
public EmplyeePojo(Integer eid, String ename, String eloginName,
40
String epassword, Date eregDate)
{
41
super();
42
this.eid = eid;
43
this.ename = ename;
44
this.eloginName = eloginName;
45
this.epassword = epassword;
46
this.eregDate = eregDate;
47
}
48
49
public Integer getEid()
{
50
return eid;
51
}
52
53
public void setEid(Integer eid)
{
54
this.eid = eid;
55
}
56
57
public String getEloginName()
{
58
return eloginName;
59
}
60
61
public void setEloginName(String eloginName)
{
62
this.eloginName = eloginName;
63
}
64
65
public String getEname()
{
66
return ename;
67
}
68
69
public void setEname(String ename)
{
70
this.ename = ename;
71
}
72
73
public String getEpassword()
{
74
return epassword;
75
}
76
77
public void setEpassword(String epassword)
{
78
this.epassword = epassword;
79
}
80
81
public java.sql.Date getEregDate()
{
82
return eregDate;
83
}
84
85
public void setEregDate(java.sql.Date eregDate)
{
86
this.eregDate = eregDate;
87
}
88
89
}
90

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

48

49



50

51

52

53



54

55

56

57



58

59

60

61



62

63

64

65



66

67

68

69



70

71

72

73



74

75

76

77



78

79

80

81



82

83

84

85



86

87

88

89

90

再在org.dj.pojo包下创建与其对应的配置文件EmplyeePojo.hbm.xml
1
<?xml version="1.0"?>
2
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
3
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
4
<hibernate-mapping>
5
<class name="org.dj.pojo.EmplyeePojo" table="emplyee">
6
<id name="eid" column="e_id" type="java.lang.Integer">
7
<generator class="native"></generator>
8
</id>
9
<property name="ename" column="e_name"
10
type="java.lang.String">
11
</property>
12
<property name="eloginName" column="e_login_name"
13
type="java.lang.String">
14
</property>
15
<property name="epassword" column="e_password"
16
type="java.lang.String">
17
</property>
18
<property name="eregDate" column="e_reg_date"
19
type="java.sql.Date">
20
</property>
21
<many-to-one name="department"
22
class="org.dj.pojo.DepartmentPojo" column="d_id">
23
</many-to-one>
24
</class>
25
</hibernate-mapping>

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

再创建一个dao对象用来得到一个员工记录,些类为:
org.dj.dao.EmplyeeDao
1
package org.dj.dao;
2
3
import java.io.Serializable;
4
5
import org.dj.pojo.EmplyeePojo;
6
import org.dj.util.HibernateSessionFactory;
7
import org.hibernate.HibernateException;
8
import org.hibernate.Session;
9
import org.hibernate.Transaction;
10
11
public class EmplyeeDao
{
12
/** *//**
13
* 根据id得到用户
14
*
15
* @param eid
16
* @return
17
*/
18
public EmplyeePojo getEmplyee(Serializable eid)
{
19
EmplyeePojo emp = null;
20
Session session = HibernateSessionFactory.getSession();
21
// Transaction trans = session.beginTransaction();
22
try
{
23
emp = (EmplyeePojo) session.load(EmplyeePojo.class, eid);
24
// trans.commit();
25
} catch (HibernateException e)
{
26
e.printStackTrace();
27
// trans.rollback();
28
} finally
{
29
// HibernateSessionFactory.closeSession();
30
}
31
return emp;
32
}
33
}
34

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

一开始.请去掉我的代码注释;
下面,我们去写个Emplyee的Service类,写一个业务处理的方法, 通得员工ID计算已注册的天数
org.dj.service.EmplyeeManegerService
1
package org.dj.service;
2
3
import java.io.Serializable;
4
import java.util.Calendar;
5
6
import org.dj.dao.EmplyeeDao;
7
import org.dj.pojo.EmplyeePojo;
8
import org.dj.vo.EmplyeeVo;
9
10
public class EmplyeeManegerService
{
11
private EmplyeeDao empDao = new EmplyeeDao();
12
/** *//**
13
* 得到用户注册的天数(本网站的网齡)
14
* @param eid 用户的id
15
* @return 网龉
16
*/
17
public Long loadEmplyeeOnlineTime(Serializable eid)
{
18
EmplyeePojo emp = empDao.getEmplyee(eid);
19
java.sql.Date regDate = emp.getEregDate();
20
Long time = System.currentTimeMillis() - regDate.getTime();
21
long day = time/(24*60*60*1000);
22
return day;
23
}
24
25
public static void main(String[] args)
{
26
Long day = new EmplyeeManegerService().loadEmplyeeOnlineTime(1);
27
System.out.println(day);
28
}
29
}
30

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

里面有个main写的测试. 你去run的时候. 发现他会发生一个异常:
session was close;
解决这个方法,你可以这样做.
先修改HibernateSessionFactory类.
1
package org.dj.util;
2
3
import org.hibernate.HibernateException;
4
import org.hibernate.Session;
5
import org.hibernate.Transaction;
6
import org.hibernate.cfg.Configuration;
7
8
9
public class HibernateSessionFactory
{
10
11
12
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
13
14
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
15
16
private static final ThreadLocal<Transaction> trThreadLocal = new ThreadLocal<Transaction>();
17
18
private static Configuration configuration = new Configuration();
19
20
private static org.hibernate.SessionFactory sessionFactory;
21
22
private static String configFile = CONFIG_FILE_LOCATION;
23
24
static
{
25
try
{
26
configuration.configure(configFile);
27
sessionFactory = configuration.buildSessionFactory();
28
} catch (Exception e)
{
29
System.err.println("%%%% Error Creating SessionFactory %%%%");
30
e.printStackTrace();
31
}
32
}
33
34
private HibernateSessionFactory()
{
35
}
36
37
/** *//**
38
* Returns the ThreadLocal Session instance. Lazy initialize the
39
* <code>SessionFactory</code> if needed.
40
*
41
* @return Session
42
* @throws HibernateException
43
*/
44
public static Session getSession() throws HibernateException
{
45
Session session = (Session) threadLocal.get();
46
47
if (session == null || !session.isOpen())
{
48
if (sessionFactory == null)
{
49
rebuildSessionFactory();
50
}
51
session = (sessionFactory != null) ? sessionFactory.openSession()
52
: null;
53
threadLocal.set(session);
54
}
55
56
return session;
57
}
58
59
/** *//**
60
* Rebuild hibernate session factory
61
*
62
*/
63
public static void rebuildSessionFactory()
{
64
try
{
65
configuration.configure(configFile);
66
sessionFactory = configuration.buildSessionFactory();
67
} catch (Exception e)
{
68
System.err.println("%%%% Error Creating SessionFactory %%%%");
69
e.printStackTrace();
70
}
71
}
72
73
/** *//**
74
* Close the single hibernate session instance.
75
*
76
* @throws HibernateException
77
*/
78
public static void closeSession() throws HibernateException
{
79
Session session = (Session) threadLocal.get();
80
threadLocal.set(null);
81
82
if (session != null)
{
83
session.close();
84
}
85
}
86
87
/** *//**
88
* return session factory
89
*
90
*/
91
public static org.hibernate.SessionFactory getSessionFactory()
{
92
return sessionFactory;
93
}
94
95
/** *//**
96
* return session factory
97
*
98
* session factory will be rebuilded in the next call
99
*/
100
public static void setConfigFile(String configFile)
{
101
HibernateSessionFactory.configFile = configFile;
102
sessionFactory = null;
103
}
104
105
/** *//**
106
* return hibernate configuration
107
*
108
*/
109
public static Configuration getConfiguration()
{
110
return configuration;
111
}
112
113
public static void openTransaction()
{
114
Transaction tr = trThreadLocal.get();
115
if (tr == null)
{
116
tr = getSession().beginTransaction();
117
System.out.println("BeginTransaction");
118
trThreadLocal.set(tr);
119
}
120
}
121
122
public static void commitTransaction()
{
123
Transaction tr = trThreadLocal.get();
124
if (tr != null && !tr.wasCommitted() && !tr.wasRolledBack())
{
125
System.out.println("Commit !");
126
tr.commit();
127
trThreadLocal.set(null);
128
}
129
}
130
131
public static void RollbackTransaction()
{
132
Transaction tr = trThreadLocal.get();
133
if (tr != null && !tr.wasCommitted() && !tr.wasRolledBack())
{
134
tr.rollback();
135
System.out.println("Rollback!");
136
trThreadLocal.set(null);
137
}
138
}
139
140
}

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



48



49

50

51

52

53

54

55

56

57

58

59


60

61

62

63



64



65

66

67



68

69

70

71

72

73


74

75

76

77

78



79

80

81

82



83

84

85

86

87


88

89

90

91



92

93

94

95


96

97

98

99

100



101

102

103

104

105


106

107

108

109



110

111

112

113



114

115



116

117

118

119

120

121

122



123

124



125

126

127

128

129

130

131



132

133



134

135

136

137

138

139

140

注意最后面的三个方法和trThreadLocal的属性;
再写一个过滤器, 代码如下 :
org.dj.filter.HibernateSessionFilter
1
package org.dj.filter;
2
3
import java.io.IOException;
4
5
import javax.servlet.Filter;
6
import javax.servlet.FilterChain;
7
import javax.servlet.FilterConfig;
8
import javax.servlet.ServletException;
9
import javax.servlet.ServletRequest;
10
import javax.servlet.ServletResponse;
11
12
import org.dj.util.HibernateSessionFactory;
13
14
public class HibernateSessionFilter implements Filter
{
15
16
public void destroy()
{
17
// TODO Auto-generated method stub
18
19
}
20
21
public void doFilter(ServletRequest request, ServletResponse response,
22
FilterChain chain) throws IOException, ServletException
{
23
24
HibernateSessionFactory.getSession();
25
HibernateSessionFactory.openTransaction();
26
try
{
27
chain.doFilter(request, response);
28
HibernateSessionFactory.commitTransaction();
29
} catch (Exception e)
{
30
HibernateSessionFactory.RollbackTransaction();
31
e.printStackTrace();
32
} finally
{
33
HibernateSessionFactory.closeSession();
34
}
35
}
36
37
public void init(FilterConfig filterConfig) throws ServletException
{
38
// TODO Auto-generated method stub
39
40
}
41
42
}
43

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

并在web.xml里面配置这个过滤器,代码如下 :
1
<filter>
2
<filter-name>sessionFilter</filter-name>
3
<filter-class>org.dj.filter.HibernateSessionFilter</filter-class>
4
</filter>
5
<filter-mapping>
6
<filter-name>sessionFilter</filter-name>
7
<url-pattern>/*</url-pattern>
8
</filter-mapping>

2

3

4

5

6

7

8

这样,我们就写好了. 再回过头把我在EmplyeeDao对象里面注释重新注释上.并写个两个jsp和一个Serlvet进行测试.代码如下:
index.jsp:
1
<%
@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
2
<%
3
String path = request.getContextPath();
4
String basePath = request.getScheme() + "://"
5
+ request.getServerName() + ":" + request.getServerPort()
6
+ path + "/";
7
%>
8
9
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
10
<html>
11
<head>
12
<base href="<%=basePath%>">
13
14
<title>My JSP 'index.jsp' starting page</title>
15
<meta http-equiv="pragma" content="no-cache">
16
<meta http-equiv="cache-control" content="no-cache">
17
<meta http-equiv="expires" content="0">
18
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
19
<meta http-equiv="description" content="This is my page">
20
<!--
21
<link rel="stylesheet" type="text/css" href="styles.css">
22
-->
23
</head>
24
25
<body>
26
<form action="/DJ_HIBERNATE/servlet/GetOnlineDays">
27
员工编号:
28
<input name="eid">
29
<input type="submit">
30
</form>
31
32
33
</body>
34
</html>
35



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

disp.jsp:
1
<%
@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
2
<%
3
String path = request.getContextPath();
4
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
5
%>
6
7
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
8
<html>
9
<head>
10
<base href="<%=basePath%>">
11
12
<title>My JSP 'disp.jsp' starting page</title>
13
14
<meta http-equiv="pragma" content="no-cache">
15
<meta http-equiv="cache-control" content="no-cache">
16
<meta http-equiv="expires" content="0">
17
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
18
<meta http-equiv="description" content="This is my page">
19
<!--
20
<link rel="stylesheet" type="text/css" href="styles.css">
21
-->
22
23
</head>
24
25
<body>
26
${day }
27
</body>
28
</html>
29



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

org.dj.servlet.GetOnlineDays的serlvet的代码如果:





























好了. 让我们发布后测试一下吧.
你会发现session was close的异常没有了.
基本的工作原理如下 图.
