一、前言
二、相关概念与工具介绍
三、实例需求与总体设计
四、持久化层与业务层实践(Hibernate实践)
五、控制层与表示层实践(Struts实践)
六、发布与运行
七、写在最后
一、前言
J2EE和.NET是目前企业级运用的两大阵营,谁优谁劣各有说法。笔者是做J2EE方向的,觉得J2EE比起.NET最大的优势就是其经过长实践发展总结出来的大量模式和大量先进的框架。这些框架许多都是开源的——开源也是J2EE阵营的另一优势。本篇文章的主角就是目前J2EE web应用中最流行的两大开源框架——Hibernate和Struts。
二、相关概念与工具介绍
下面我将分别对本文“三大主角”所涉及到相关概念进行说明。
Hibernate及相关知识介绍
Hibernate:
中文意思是"冬眠“,呵呵,不知道设计者为何用这个名字。它是一个开源的ORM框架(关于ORM下文还会讲解),它是通过对JDBC API进行封装从而实现对java对象持久化的。有人可能要问:JDBC其实不难操作,为什么还要封装它哪?其实答案很简单,因为现在通用的数据库都是关系数据库,我们通过JDBC操作无法做到OOP,所以Hibernate将JDBC封装起来,并且提供了一套OO化的Hibernate API供顶层操作。Hibernate现在几乎已经成为ORM的公认标准了(刚推出的EJB 3.0标准中使用的ORM事实上就是Hibernate)
ORM:
这里解释下ORM。ORM是一种模式(关于模式,笔者之前在这里发表过一篇介绍工厂模式的文章,读者可以看看),它的英文是Object-Relation Mapping,中译为对象-关系映射,它指的是“在单个组建中负责所有实体域对象的持久化,封装数据访问细节”(注:此定义来自《精通Hibernate:java对象持久化技术详解》,孙卫琴,电子工业出版社)。笔者的觉得很容易理解:把关系数据库对象化。
Struts及相关知识介绍
Struts:
Struts是由著名的Apache基金会开发的开源项目。中译为“框架”,顾名思义,它就是一种MVC框架。众所周知,MVC是一种业务逻辑与表示分离的模式,在java web上的应用十分广泛。以前MVC的主要表现形式是JSP Model2,也就是JSP+Servlet+Javabean的应用,而近年来Struts的应用越来越广泛,目前已经是最流行的MVC框架了。
MVC:
Model-View-Controller,中译为模型-视图-控制器。MVC不是真正意义上的软件设计模式,而更是一种解决方案,它把软件系统的所有业务逻辑方面的编程交给了Model,把所有UI视图的设计和编程交给了View,再用Controller控制器控制Model并生成相应的View,从而真正实现了业务逻辑与用户界面的分离。
Eclipse介绍
Eclipse是由IBM公司开发出来,后来又免费捐献出来的开源工具,是一套主要用于Java开发的IDE(Eclipse通过添加某些插件可以实现对UML、C++等的开发)。Eclipse具有强大的扩展功能,加上其开源的特性,导致许多爱好者和公司为其开发了非常优秀的插件,Myeclipse就是其中之一。Myeclipse是面向J2EE开发者的Eclipse插件,功能强大,好用。本文的实例就是基于Eclipse+Myeclipse环境下开发出来的。
创建/运行本文实例除了安装以上工具和插件外还需要安装一个Web容器,本文使用的是Jboss,笔者可以自行选择使用Tomcat或Weblogic等,这些对运行本文实例影响不大。
本文选择的数据库是SQLServer2000,关于Mysql、Oracle等其他数据库的操作方法类似。
关于Eclipse下载和安装方法本文不做介绍,请读者自行在网上查找相关方法。
三、实例需求与总体设计
1、需求定义
由于本文的目的是介绍在Eclipse IDE下开发Struts+Hibernate的具体方法,而不是介绍项目开发/软件设计的技巧,所以本文实例需求非常简单。
本文实例是一个web留言簿,可以让匿名用户发表一些留言信息,并保存至数据库。做过web开发的朋友肯定做过这类实例,非常经典。由于实例简单并且容易理解,所以笔者也省去画用例图说明的步骤。
2、总体设计
本实例按传统J2EE web项目的设计方法,分为5层架构,自底向上分别是:数据库层 -> ORM层(Hibernate层) -> 业务逻辑层 -> 控制层(Struts Action) -> 视图表示层。
数据库的DDL语句如下:
四、持久化层与业务层实践(Hibernate实践)
好,戏肉开始。
1、先打开Eclipse。点击“新建项目”->“Web Project”,出现如下窗口,在窗口中Project Name填入“Memo”作为项目名:
create database memotest
create table Memo
(
ID int not null identity(1,1),
topic varchar(255),
content text,
guest varchar(50),
primary key(ID)
)
2、点击“窗口”->“打开透视图”->“其他”,出现如下窗口,双击“Myeclipse Database Explorer”,切换到如下视图:
3、在“DB Browser”控制面板点击“new”,新建一个数据库连接。在弹出的窗口中点击“new driver”新建一个数据库连接驱动。如下图:
4、上一步后回到以下视图,在列表中选择上一步创建的驱动,填入相关数据库资料,点击确定即可。(此步骤前必须已经打开数据库,最后已经按照本实例的DDL创建了库和表)
5、完成上一步后出现以下视图。点击“memo”的右键,点击“open connetion”->“确定”。如果上述步骤成功的话这里会连接到数据库,并显示相关的数据库结构。
成功后如下图:
6、点击“窗口”->“打开透视图”->“其他”->“Myeclipse”切换到项目控制视图。在项目名上点击右键->“myeclipse”->“Add Hibernate capabilites”,出现以下视图,并按下图填入相关信息:
点下一步后出现如下框图,按图片上内容填写:
提交后出现以下视图,按图片内容填写:
7、在项目名上点击右键->“myeclipse”->“Add Struts capabilites”,出现下面视图,按图中内容天下:
8、点击“窗口”->“打开透视图”->“其他”,出现如下窗口,双击“Myeclipse Database Explorer”,切换到数据库管理视图,找到我们为本次实例创建的表格,点右键->“create hibernate mapping”后出现下图,按图上内容填写:
9、至此Hibernate的创建工作已经完成,如下图,接下来我们写个DAO工厂类来操作Hibernate API。
点击com.woden包,新建个类,如下图:
输入以下代码:
package com.woden;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.Transaction;
public class MemoDAOFactory {
Session session;
Transaction tx;
public void add(Memo memo) throws HibernateException{
try{
session = SessionFactory.currentSession();
tx = session.beginTransaction();
session.save(memo);
tx.commit();
}catch(HibernateException e){
System.out.println(e.toString());
}finally{
if(tx!=null){
tx.rollback();
}
SessionFactory.closeSession();
}
}
}
以上只有一个插入方法,如果读者需要更多方法可以在DAO中自行添加。
至此,数据库层、ORM层和业务层的代码已经完成。
五、控制层与表示层实践(Struts实践)
如果读者没有安装ascii自动转unicode组建,可以直接copy我转换后的资源文件内容:
form.addmemo.err.content=u7559u8a00u5185u5bb9u4e0du80fdu4e3au7a7au3002
form.addmemo.err.guest=u7559u8a00u8005u59d3u540du4e0du80fdu4e3au7a7au3002
form.addmemo.err.topic=u7559u8a00u6807u9898u4e0du80fdu4e3au7a7au3002
jsp.addmemo.content=u8bf7u8f93u5165u5185u5bb9uff1a
jsp.addmemo.guest=u60a8u7684u59d3u540duff1a
jsp.addmemo.pagetitle=u7559u8a00u6dfbu52a0
jsp.addmemo.reset=u91cdu8bbe
jsp.addmemo.submit=u63d0u4ea4
jsp.addmemo.topic=u6807u9898uff1a
jsp.welcome.content=u6b22u8fceu4f7fu7528Hibernate+Strutsu5b9eu4f8bu3002
jsp.welcome.title=u4f60u597du3002u3002u3002
7、下面打开com.woden.form.MemoForm.java文件,输入以下代码:
package com.woden.form;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
public class MemoForm extends ActionForm {
private String topic;
private String content;
private String guest;
public ActionErrors validate(
ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if(getGuest()==null||"".equals(getGuest()))
{
errors.add("memoform.err.guest",new ActionMessage("form.addmemo.err.guest"));
}
if(getTopic()==null||"".equals(getTopic()))
{
errors.add("memoform.err.topic",new ActionMessage("form.addmemo.err.topic"));
}
if(getContent()==null||"".equals(getContent()))
{
errors.add("memoform.err.content",new ActionMessage("form.addmemo.err.content"));
}
return errors;
}
public void reset(ActionMapping mapping, HttpServletRequest request) {
this.topic=null;
this.content=null;
this.guest=null;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getGuest() {
return guest;
}
public void setGuest(String guest) {
this.guest = guest;
}
}
8、上面已经写出了ActionForm的代码,具体代码笔者在这里不解释,我想看过struts基础的朋友都应该很清楚了,下面贴处Action的代码:
package com.woden.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import com.woden.Memo;
import com.woden.MemoDAOFactory;
import com.woden.form.MemoForm;
public class MemoAction extends Action {
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
MemoForm memoForm = (MemoForm) form;
MemoDAOFactory memoDAO = new MemoDAOFactory();
Memo memo = new Memo();
memo.setTopic(memoForm.getTopic());
memo.setContent(memoForm.getContent());
memo.setGuest(memoForm.getGuest());
try{
memoDAO.add(memo);
}catch(Exception e)
{
System.out.print(e.toString());
}
return mapping.findForward("success");
}
}
9、最后编辑下几个相关jsp文件的内容,分别如下:
welcome.jsp
<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html:html>
<head>
<html:base />
<title><bean:message key="jsp.welcome.title"/></title>
</head>
<body>
<bean:message key="jsp.welcome.content"/>
</body>
</html:html>
addmemo.jsp
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
<html>
<head>
<title><bean:message key="jsp.addmemo.pagetitle"/></title>
</head>
<body>
<html:form action="/memo">
<bean:message key="jsp.addmemo.guest"/><html:text property="guest"/><html:errors property="memoform.err.guest"/><br/>
<bean:message key="jsp.addmemo.topic"/><html:text property="topic"/><html:errors property="memoform.err.topic"/><br/>
<bean:message key="jsp.addmemo.content"/><html:textarea property="content"/><html:errors property="memoform.err.content"/><br/>
<html:submit><bean:message key="jsp.addmemo.submit"/></html:submit>
<html:reset><bean:message key="jsp.addmemo.reset"/></html:reset>
</html:form>
</body>
</html>
至此,本实例完成。
六、发布与运行
1、在项目文件点右键->“myeclipse”->“Add and remove project deployment
2、点击图标,选择“Jboss”->“start”(注:这里如果用的是tomcat也类似操作,关于服务器配置的方法这里不祥谈,请读者自行在网上查找相关资料),会发现控制台会输出类似如下信息:
打开浏览器,输入:http://localhost:8080/
3、输入网址:http://localhost:8080/Memo/addmemo.jsp
4、按照正常流程和非正常流程分别留言一次,呵呵,效果出来没有?如果没有出现预期效果请检查前面步骤。
七、写在最后
在本文最后,笔者再次强调,本文的目的是介绍Eclipse IDE关于创建Struts+Hibernate应用的方法,而不是介绍j2ee框架的概念和运用,更不是介绍java设计与模式。本文对IDE的配置、服务器配置的方法也没做详细介绍,因为这都不是本文重点。对以上知识想了解多点的读者可以google一下。
本文的实例只是一个入门,强调的是一种方法,而不是强调功能,所以本文的实例只有一个简单的录入功能。在看完本文后读者可以添加更多的功能(我想,当这一架构搭建起来后,添加功能已经是相当容易的事情了)。