我是如何学习Hibernate的(一)

前述

在搭建这个博客之前,我一直使用Word,OneNote等工具来记录我的学习过程。我会经常上iteye,CSDN查阅我想要的知识点。如果碰到很复杂的问题,或者说很少遇到的问题,那么我会在Stack Overflow查找相关问题,我的网站取名为OneStack,也有一半是为此。另一半大概就是我的理想是成为全栈工程师吧。

Hibernate入门

简介

  • ORM框架:Object Relational Mapping(对象关系映射)是关系型数据库和面向对象型数据库过渡时期的一个框架。Object指的是JavaBean,Relational指的是关系,二维表,数据库中的表。Mapping对象中的属性,与表的字段,存在的对应关系。
  • Hibernate:在基于MVC设计模式的JAVA WEB应用中,Hibernate可以作为模型层/数据访问层。它通过配置文件(hibernate.cfg.xml)和映射文件(*.hbm.xml)把JAVA对象或PO(Persistent Object,持久化对象)映射到数据库中的数据库,然后通过操作PO,对数据表中的数据进行增,删,改,查等操作。
  • PO:Persistent Object 持久化对象。
  • JPA Java Persistence API (规范):JPA 是 JCP 组织发布的 Java EE 标准之一,因此任何声称符合 JPA 标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。
  • 优点:
    hibernate对JDBC访问数据库的代码进行了封装,大大简化了数据访问层繁琐的重复性代码。
    hibernate是一个持久化框架,是一个优秀的ORM实现,很大程度上简化了dao层的工作。
    hibernate使用了Java的反射机制。
    hibernate性能非常好,因为它是一个轻量级框架。映射的灵活性很出色,它支持关系性数据库,从一对一到多对多的各种复杂关系。

    hibernate核心组件

  • Configuration类:用来读取Hibernate配置文件,并生成SessionFactory对象。
  • SessionFactory接口:实例化Session工厂。
  • Session接口:用来操作PO,有get(),load(),save(),update(),delete()等方法来对PO进行加载,保存,更新,删除等操作。它是Hibernate的核心接口。
  • Query接口:用来对PO进行查询操作。,它可以从Session的createQuery()方法生成。
  • Transcation接口: 用来管理数据的的事务的接口,调用begin()方法可以开启事务,调用end()方法结束事务。在开启事务期间,可以commit()把PO保存到数据库中,或者rollback()回滚当前事务的操作。

    Persistent Object

    持久化对象可以是普通的JavaBean,唯一的区别就是PO与且仅与一个Session想关联。JavaBean在Hibenate中存在三种状态(理解,不背):
  • 临时状态(transient):当new出来的JavaBean,在内存中孤立存在,不与数据库中的数据有任何联系时(没ID),称这个JavaBean为临时对象。
  • 持久化状态(Persistent Object):当一个JavaBean与Session相关联时,JavaBean就从transient转变为perisistent。
  • 脱管态状态(detached):当与JavaBean相关联的Session关闭时,JavaBean也就变成了detached状态,可以被应用程序的任何层自由使用,例如可以作与表示层打交道的数据对象(Data Tranfer Object)。

    Hibernate的运行过程

  • 应用程序首先调用Configration类,该类读取Hibernate的配置文件及映射文件中的信息,并用这些信息生成一个SessionFactory对象。
  • SessionFactory对象生成一个Session,用Session联系一个PO,并让Session产生一个Transaction,通过session的get(),load(),save(),update(),delete()等方法,对PO进行操作。当session执行commit()时,将事务里的操作提交到数据库。如果执行rollback(),那就不提交。在查询情况下,可通过Session.createQuery()生成一个Query对象,然后Query对象可以调用list()执行查询操作。
  • Hibernate的运行过程如下图:

一次完整的Hibernate编程

数据库

create table T_register
(
id int primary key,
userName varchar(30),
userPwd varchar(30),
sex varchar(10),
age int
)

视图层: 注册页面register.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="servlet/RegisterServlet" method="POST">
    用户名:<input type="text" name="userName" /><BR>
    密  码:<input type="text" name="userPwd" /><BR>
    性  别:<input type="text" name="sex" /><BR>
    年  龄:<input type="text" name="age" /><BR>
    <input type="submit" value="save" />
</form>
</body>
</html>

设计持久化类TRegister.java

package hibernate.PO;
/**
 * 持久化类
 *以后的POJO,除了特别说明,均省略get、set方法和不重要的包名
 */

public class TRegister  implements java.io.Serializable {

     private Integer id;
     private String userName;
     private String userPwd;
     private String sex;
     private Integer age;



}

设计Hibernate配置文件hibernate.cfg.xml

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
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
	<hibernate-configuration>
<session-factory>
<!-- 配置Hibernate基本信息 -->

<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/hibernate001</property>
<property name="connection.username">root</property>
<property name="connection.password">12345</property>

<!-- 配置Hibernate方言 -->

<property name="hibernate.dialect ">
org.hibernate.dialect.MySQLDialect
</property>

<!-- 可选属性 -->
<property name="hibernate.show_sql">true</property>

<!-- 格式化sql -->
<property name="hibernate.format_sql">true</property>

<!-- 通知Hibernate加载哪些配置-->
<mapping resource="hibernate/PO/TRegister.hbm.xml" />

</session-factory>
</hibernate-configuration>
```
## 设计映射文件TRegister.hbm.xml
<hibernate-mapping>
<class name="hibernate.PO.TRegister" table="t_register">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="increment" />
</id>
<property name="userName" type="java.lang.String">
<column name="userName" length="30" />
</property>
<property name="userPwd" type="java.lang.String">
<column name="userPwd" length="30" />
</property>
<property name="sex" type="java.lang.String">
<column name="sex" length="10" />
</property>
<property name="age" type="java.lang.Integer">
<column name="age" />
</property>
</class>
</hibernate-mapping>

## 设计hibernate基础类HibernateUtil.java
``` bash
package hibernate;

public class HibernateUtil {

private static final SessionFactory sessionFactory;

static
{
try
{
Configuration config = new Configuration().configure("/hibernate/hibernate.cfg.xml");
sessionFactory = config.buildSessionFactory();
}
catch(Throwable e)
{
throw new ExceptionInInitializerError(e);
}
}

public static final ThreadLocal session = new ThreadLocal();

public static Session currentSession() throws HibernateException
{
Session s = (Session)session.get();
if(s == null || !s.isOpen())
{
s = sessionFactory.openSession();
session.set(s);
}
return s;
}

public static void closeSession() throws HibernateException
{
Session s = (Session)session.get();
session.set(null);
if(s != null)
s.close();
}

}

设计控制类

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
48
49
50
package hibernate.servlet;

public class RegisterServlet extends HttpServlet {

private static final String CONTENT_TYPE = "text/html;charset=UTF-8";
public void init() throws ServletException {

}
public void destroy() {
super.destroy();
}


public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

response.setContentType(CONTENT_TYPE);
request.setCharacterEncoding("UTF-8");

PrintWriter out = response.getWriter();

String userName = request.getParameter("userName");
String userPwd = request.getParameter("userPwd");
String sex = request.getParameter("sex");
int age = Integer.parseInt(request.getParameter("age"));

TRegister rg = new TRegister();
rg.setAge(age);
rg.setSex(sex);
rg.setUserName(userName);
rg.setUserPwd(userPwd);

Session session = HibernateUtil.currentSession();//生成Session实例
Transaction tx = session.beginTransaction();

try
{
session.save(rg); //保存持久类对象
tx.commit(); //提交到数据库
session.close();
response.sendRedirect("registerOK.jsp");
}
catch(HibernateException e)
{
e.printStackTrace();
tx.rollback();
}

}
}