Hibernate入门示例(架构图)
?在 Java Web 开发应用中,Hibernate可以作为应用程序的数据访问层。
这里以一个简单用户注册用例来说明如何开发一个Hibernate的应用程序。
该例子的需求:把注册页面输入的用户名、密码、性别、年龄方面的信息存入数据库中。
如果采用经典的MVC模式的话,那么各层的构建如下:
?
DROP TABLE IF EXISTS `t_register`;
CREATE TABLE `t_register` (
??`id` int(11) NOT NULL,
??`username` varchar(30) collate utf8_unicode_ci default NULL,
??`password` varchar(30) collate utf8_unicode_ci default NULL,
??`sex` varchar(10) collate utf8_unicode_ci default NULL,
??`age` int(10) default NULL,
??PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
2、创建视图层页面
清单1:register.jsp
?
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
????<head>
????????<title>用户注册页面</title>
????</head>
????<body>
????????<form action="RegisterServlet" method="post">
????????????用户名:
????????????<input type="text" name="username">
????????????<br>
????????????密码:
????????????<input type="password" name="password">
????????????<br>
????????????性别:
????????????<input type="text" name="sex">
????????????<br>
????????????年龄:
????????????<input type="text" name="age">
????????????<br />
????????????<input type="submit" name="submit" value="submit">
????????</form>
????</body>
</html>
清单2:reply.jsp
?
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<html>
??<head>
????<title>Successfully</title>
??</head>
??<body>
????Inster data into database <br>
??</body>
</html>
?
3、设计持久化类
对应于数据库中表项。
清单3:Register.java
?
package register;
public class Register {
????int id;
????Integer age;
????String username = new String();
????String password = new String();
????String sex = new String();
????
????public Integer getAge() {
????????return age;
????}
????public void setAge(Integer age) {
????????this.age = age;
????}
????public int getId() {
????????return id;
????}
????public void setId(int id) {
????????this.id = id;
????}
????public String getPassword() {
????????return password;
????}
????public void setPassword(String password) {
????????this.password = password;
????}
????public String getSex() {
????????return sex;
????}
????public void setSex(String sex) {
????????this.sex = sex;
????}
????public String getUsername() {
????????return username;
????}
????public void setUsername(String username) {
????????this.username = username;
????}
}
4、设计Hibernate配置文件
清单4:hibernate.cfg.xml
?
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
??????????"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
??????????"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
????<session-factory>
????????<property name="connection.username">root</property>
????????<property name="connection.url">jdbc:mysql://localhost:3306/study</property>
????????<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
????????<property name="myeclipse.connection.profile">MySQL</property>
????????<property name="connection.password">123456</property>
????????<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
????
????????<mapping resource="register.hbm.xml" />
????</session-factory>
</hibernate-configuration>
?
5、设计映射文件
数据库表到Java类数据项的映射
清单5:register.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 package="register">
????<class name="register.Register" table="T_Register">
????????<id name="id" type="java.lang.Integer">
????????????<column name="id" />
????????????<generator class="increment"></generator>
????????</id>
????????<property name="username" type="java.lang.String">
????????????<column name="username" length="30" />
????????</property>
????????<property name="password" type="java.lang.String">
????????????<column name="password" 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>
?
6、设计Hibernate的基础类HibernateSessionFactory.java
?HibernateSessionFactory.java包含了Configuration实例、SessionFactory实例和Session实例的生成函数,
这样应用程序就可以直接调用HibernateSessionFactory来生成Session实例,不必再重复编写Configuration实例、
SessionFactory实例和Session实例的生成代码了。
清单6:HibernateSessionFactory.java
?
package register;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
public class HibernateSessionFactory {
????private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
????private static final ThreadLocal threadLocal = new ThreadLocal();
????private static Configuration configuration = new Configuration();
????private static org.hibernate.SessionFactory sessionFactory;
????private static String configFile = CONFIG_FILE_LOCATION;
????private HibernateSessionFactory() {
????}
????/**
???? * Returns the ThreadLocal Session instance. Lazy initialize
???? * the <code>SessionFactory</code> if needed.
???? *
???? * @return Session
???? * @throws HibernateException
???? */
????public static Session getSession() throws HibernateException {
????????Session session = (Session) threadLocal.get();
????????if (session == null || !session.isOpen()) {
????????????if (sessionFactory == null) {
????????????????rebuildSessionFactory();
????????????}
????????????session = (sessionFactory != null) ? sessionFactory.openSession()
????????????????????: null;
????????????threadLocal.set(session);
????????}
????????return session;
????}
????/**
???? * Rebuild hibernate session factory
???? *
???? */
????public static void rebuildSessionFactory() {
????????try {
????????????configuration.configure(configFile);
????????????sessionFactory = configuration.buildSessionFactory();
????????} catch (Exception e) {
????????????System.err.println("%%%% Error Creating SessionFactory %%%%");
????????????e.printStackTrace();
????????}
????}
????/**
???? * Close the single hibernate session instance.
???? *
???? * @throws HibernateException
???? */
????public static void closeSession() throws HibernateException {
????????Session session = (Session) threadLocal.get();
????????threadLocal.set(null);
????????if (session != null) {
????????????session.close();
????????}
????}
????/**
???? * return session factory
???? *
???? */
????public static org.hibernate.SessionFactory getSessionFactory() {
????????return sessionFactory;
????}
????/**
???? * return session factory
???? *
???? *????session factory will be rebuilded in the next call
???? */
????public static void setConfigFile(String configFile) {
????????HibernateSessionFactory.configFile = configFile;
????????sessionFactory = null;
????}
????/**
???? * return hibernate configuration
???? *
???? */
????public static Configuration getConfiguration() {
????????return configuration;
????}
}
?
7、设计控制类
?从页面提取数据,然后调用HibernateSessionFactory通过Hibernate机制将数据插入到数据库中。
清单7:RegisterServlet.java
?
package register;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.hibernate.*;
public class RegisterServlet extends HttpServlet{
????
????private static final String CONTENT_TYPE = "text/html; charset=GBK";
????
????protected void doGet(HttpServletRequest request, HttpServletResponse response)
????????????throws ServletException, IOException {
????????response.setContentType(CONTENT_TYPE);
????????
????????//从页面得到数据值
????????String username = request.getParameter("username");
????????String password = request.getParameter("password");
????????String sex = request.getParameter("sex");
????????Integer age = new Integer(request.getParameter("age"));
????????
????????
????????//将值传递给持久类->对应的是数据库里的表
????????Register rg = new Register();
????????rg.setUsername(username);
????????rg.setPassword(password);
????????rg.setSex(sex);
????????rg.setAge(age);
????????
????????Session session = HibernateSessionFactory.getSession();
????????Transaction tx = session.beginTransaction();
????????
????????try {
????????????session.save(rg);//保存,准备提交
????????????tx.commit();//提交到数据库
????????????session.close();
????????????response.sendRedirect("reply.jsp");
????????} catch (Exception e) {
????????????e.printStackTrace();
????????????tx.rollback();//出现异常,将刚刚提交动作回转,rollback
????????}
????}
????protected void doPost(HttpServletRequest request, HttpServletResponse response)
????????????throws ServletException, IOException {????
????????doGet(request, response);
????}
}
?
8、配置web.xml
清单8:web.xml
?
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
????xmlns="http://java.sun.com/xml/ns/j2ee"
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
????xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
????http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
????
????<servlet>
????????<servlet-name>RegisterServlet</servlet-name>
????????<servlet-class>register.RegisterServlet</servlet-class>
????</servlet>????
????
????<servlet-mapping>
????????<servlet-name>RegisterServlet</servlet-name>
????????<url-pattern>/RegisterServlet</url-pattern>
????</servlet-mapping>
????
</web-app>
?
?
?
?
?
?
?
?
hibernate框架简介
?
?一 历史与背景
1 应用程序的分层体系结构
??? 随着计算机应用软件的发展,应用程序逐渐由单层体系结构发展为多层体系结构。其中,三层结构是目前典型的一种应用软件结构,如图1左。
表述层:提供与用户交互的界面,如GUI(图形用户界面),web页面等;
业务逻辑层:负责各种业务逻辑,直接访问数据库,提供对业务数据的保存、更新、删除和查询操作;
数据库层:负责存放管理应用的持久性业务数据
?
三层结构的特点是:所有下层向上层提供调用的接口,具体实现细节对上层透明。层与层之间存在自上而下的依赖关系,即上层会访问下层的API,但下层不依赖于上层。
?
2?? 持久化层(如图1右)
(1)什么叫持久化?
在图1右中,分离出的持久化层封装了数据访问细节,为业务逻辑层提供了面向对象的API。
持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的数据存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。
(2)什么叫持久层?
持久层(Persistence Layer),即专注于实现数据持久化应用领域的某个特定系统的一个逻辑层面,将数据使用者和数据实体相关联。
(3)为什么要持久化?增加持久层的作用是什么?
数据库的读写是一个很耗费时间和资源的操作,当大量用户同时直接访问数据库的时候,效率将非常低,如果将数据持久化就不需要每次从数据库读取数据,直接在内存中对数据进行操作,这样就节约了数据库资源,而且加快了系统的反映速度。
增加持久化层提高了开发的效率,使软件的体系结构更加清晰,在代码编写和系统维护方面变得更容易。特别是在大型的应用里边,会更有利。同时,持久化层作为单独的一层,人们可以为这一层独立的开发一个软件包,让其实现将各种应用数据的持久化,并为上层提供服务。从而使得各个企业里做应用开发的开发人员,不必再来做数据持久化的底层实现工作,而是可以直接调用持久化层提供的API。
(4)目前在持久化层领域,实现模式有以下几种:
A 业务逻辑和数据访问耦合
B 主动域对象模式
C ORM模式
D JDO模式
E CMP模式
3 ORM介绍
ORM(Object Relational Mapping),即对象关系映射。
指以O/R原理设计的持久化框架(Framework),包括 O/R机制、SQL自生成、事务处理和Cache管理等。
ORM的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样开发人员就可以把对数据库的操作转化为对这些对象的操作。因此它的目的是为了方便开发人员以面向对象的思想来实现对数据库的操作。
常用的ORM中间件有:
Apache OJB (http://db.apache.org/ojb/)
Cayenne (http://objectstyle.org/cayenne/)
Jaxor (http://jaxor.sourceforge.net)
Hibernate (http://www.hibernate.org)
iBatis (http://www.ibatis.com)
jRelationalFramework (http://ijf.sourceforge.net)
mirage (http://itor.cq2.org/en/oss/mirage/toon)
SMYLE (http://www.drjava.de/smyle)
TopLink (http://otn.oracle.com/products/ias/toplink/index.html)
其中 Hibernate 的轻量级 ORM 模型逐步确立了在 Java ORM 架构中领导地位,甚至取代复杂而又繁琐的 EJB 模型而成为事实上的 Java ORM 工业标准。而且其中的许多设计均被 J2EE 标准组织吸纳而成为最新 EJB 3.0 规范的标准。
二 Hibernate定义
Hibernate是一种Java语言下的对象关系映射解决方案。 它是一种自由、开源的软件。它用来把对象模型表示的对象映射到基于SQL 的关系模型结构中去,为面向对象的领域模型到传统的关系型数据库的映射,提供了一个使用方便的框架。
三 Hibernate的作用
Hibernate 不仅管理Java 类到数据库表的映射(包括从Java数据类型到SQL数据类型的映射),还提供数据查询和获取数据的方法,可以大幅度减少开发时人工使用SQL 和JDBC 处理数据的时间。
它的设计目标是将软件开发人员从大量相同的数据持久层相关编程工作中解放出来。无论是从设计草案还是从一个遗留数据库开始,开发人员都可以采用Hibernate。
四 Hibernate的应用
Hibernate对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,它既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用。最具革命意义的是,Hibernate可以在应用EJB(Enterprise JavaBeans是Java应用于企业计算的框架)的J2EE架构中取代CMP,完成数据持久化的重任。
五 Hibernate API简介
1 Hibernate API中的接口可以分为以下几类:
(1) 提供访问数据库的操作的接口,包括session、Transaction、Query接口;
(2) 用于配置Hibernate的接口,Configuration;
(3) 间接接口,使应用程序接受Hibernate内部发生的事件,并作出相关的回应,包括:Interceptor、Lifecycle、Validatable;
(4) 用于扩展Hibernate功能的接口,如UserType、CompositeUserType、IdentifierGenerator接口。
Hibernate内部还封装了JDBC、JTA(Java Transaction API)和JNDI(Java Naming And Directory Interface)。其中,JDBC提供底层的数据访问操作,只要用户提供了相应的JDBC驱动程序,Hibernate可以访问任何一个数据库系统。JTA和JNDI使Hibernate能够和J2EE应用服务器集成。
2?????? Hibernate的核心接口框图
六?? Hibernate的优缺点
(1)优点:
??? a.Hibernate 使用 Java 反射机制 而不是字节码增强程序来实现透明性。
??? b.Hibernate 的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。
??? c. 它支持各种关系数据库,从一对一到多对多的各种复杂关系。
(2)缺点:
??? Hibernate限制您所使用的对象模型。例如,一个持久性类不能映射到多个表。
?