Hbernate的web应用与前面2个小节讲的独立的java应用非常的相似。然而,一些常见的模式是有用的。现在你可以写一各EventManagerServlet类。这个Servlet可以列出所有的存储在数据库中事件记录,并提供一个HTML表单来收集你输入新的事件数据存储到数据库中。
1.3.1. 写一个简单的Servlet
package org.hibernate.tutorial.web; // Imports public class EventManagerServlet extends HttpServlet { protected void doGet( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { SimpleDateFormat dateFormatter = new SimpleDateFormat( "dd.MM.yyyy" ); try { // Begin unit of work HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction(); // Process request and render page... // End unit of work HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit(); } catch (Exception ex) { HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().rollback(); if ( ServletException.class.isInstance( ex ) ) { throw ( ServletException ) ex; } else { throw new ServletException( ex ); } } } }文件保存为: src/main/java/org/hibernate/tutorial/web/EventManagerServlet.java
这里应用的模式被称为“按请求会话”。当一个请求到达一个新的servlet,Hibernate通过调用SessionFactory.getcurrentsession()获取第一个会话(session)。然后开始一个数据库事务。所有的数据访问都发生在一个事务中,不论数据是读还是写。不要在应用程序中使用自动提交模式。
不要为每一个数据库操作使用一个新的Hibernate会话。使Hibernate的session的作用域为整个请求期间。使用getcurrentsession()方法,这样它会将session自动绑定到当前java线程。
下一步,该请求的可能行为进行响应的HTML渲染。我们很快就会到达那一部分。
最后,当处理和渲染完成时,工作单元结束。如果在处理或渲染过程中发生了任何问题,将引发异常,并回滚数据库事务。这样就完成了每个请求模式的会话。你也可以写一个servlet过滤器,而不用在每一个Servlet中都写事物开启、提交代码。查看Hibernate官网和WiKi网站,更多关于这种模式的更多信息,有一个被称为视图中开放会话模式。当你想要在JSP渲染你的页面,不是在一个servlet时,你会需要它。(Open Session in View确实在ssh项目中可能会用到,不是用这种模式,在struts2视图经常无法获取Hibernate查询出来的数据,抛出异常。)
1.3.2. 处理与渲染
// Write HTML header PrintWriter out = response.getWriter(); out.println("<html><head><title>Event Manager</title></head><body>"); // Handle actions if ( "store".equals(request.getParameter("action")) ) { String eventTitle = request.getParameter("eventTitle"); String eventDate = request.getParameter("eventDate"); if ( "".equals(eventTitle) || "".equals(eventDate) ) { out.println("<b><i>Please enter event title and date.</i></b>"); } else { createAndStoreEvent(eventTitle, dateFormatter.parse(eventDate)); out.println("<b><i>Added event.</i></b>"); } } // Print page printEventForm(out); listEvents(out, dateFormatter); // Write HTML footer out.println("</body></html>"); out.flush(); out.close();这种编码风格,混合了java和html,不适合使用在一个更复杂的应用;记住, 本教程只是在演示基本Hibernate的概念。一个HTML代码打印页眉和页脚。在这个网页,显示 数据库中的所有事件条目列表和的HTML表单。第一种方法是平常的,只有输出的HTML:
private void printEventForm(PrintWriter out) { out.println("<h2>Add new event:</h2>"); out.println("<form>"); out.println("Title: <input name='eventTitle' length='50'/><br/>"); out.println("Date (e.g. 24.12.2009): <input name='eventDate' length='10'/><br/>"); out.println("<input type='submit' name='action' value='store'/>"); out.println("</form>"); }的listEvents()方法使用Hibernate绑定到当前线程的session执行查询:
private void listEvents(PrintWriter out, SimpleDateFormat dateFormatter) { List result = HibernateUtil.getSessionFactory() .getCurrentSession().createCriteria(Event.class).list(); if (result.size() > 0) { out.println("<h2>Events in database:</h2>"); out.println("<table border='1'>"); out.println("<tr>"); out.println("<th>Event title</th>"); out.println("<th>Event date</th>"); out.println("</tr>"); Iterator it = result.iterator(); while (it.hasNext()) { Event event = (Event) it.next(); out.println("<tr>"); out.println("<td>" + event.getTitle() + "</td>"); out.println("<td>" + dateFormatter.format(event.getDate()) + "</td>"); out.println("</tr>"); } out.println("</table>"); } }最后,该存储操作进入到createAndStoreEvent()方法,并使用当前线程的会话:
protected void createAndStoreEvent(String title, Date theDate) { Event theEvent = new Event(); theEvent.setTitle(title); theEvent.setDate(theDate); HibernateUtil.getSessionFactory() .getCurrentSession().save(theEvent); }Servlet是现在算是完成了。一个对Servlet的请求将 在一个单个会话和事务中被处理。对比于之前独立的Hibernate应用,Hibernate可以自动绑定对象到当前线程的执行。这样就给了你编码的自由,你能在任何你喜欢的地方访问访SessionFactory。通常情况下,您将使用一个更复杂的设计,将数据访问代码移动到数据访问对象(即“DAO”模式)中。看到 Hibernate更多例子查看维基百科。
1.3.3. 发布与测试
src/main/webapp/WEB-INF/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>Event Manager</servlet-name> <servlet-class>org.hibernate.tutorial.web.EventManagerServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Event Manager</servlet-name> <url-pattern>/eventmanager</url-pattern> </servlet-mapping> </web-app>构建和部署通过调用mvn package打包你的项目,复制你的hibernate-tutorial.war文件到Tomcat的webapps目录。
一旦部署和tomcat运行,使用http://localhost:8080/hibernate-tutorial/eventmanager访问项目进行测试。
注:如果你没有安装Tomcat的,从http://tomcat.apache.org/下载并按照说明安装。
我们的应用程序使用tomcate的标准配置文件就可以了,不用进行任何更改。
(因为我在之前的pom.xml中集成了jetty,所以可以不使用tomcate,当使用mvn package打包项目后,直接使用mvn jetty:run运行项目进行测试)
源码:git@code.csdn.net:xiaozaq/hibernatewebdemo.git