首页logo
  •  

jonllen

金龙,目前就职于一家软件公司,从事Java和.Net信息安全开发设计。

个人档案

jonllen
心情闪存 | 给他留言
妮称:jonllen
来自:中国. 湖南. 湘潭
简述:金龙,目前就职于一家软件公司,从事Java和.Net信息安全开发设计。
博客日历

Struts+Hibernate学习笔记

分类:Java

目录

1.配置好Hibernate数据库连接

2.使用Hibernate映射数据库到实体类

3.创建struts应用程序

4.使用DispatchAction类执行不同方法

5.部署到Linux的Webligic应用服务器

一、配置好Hibernate数据库连接

创建一个名为Hibernate的新工程,要使用Hibernate需要先创建一个数据库连接,选择Window工具栏Show View菜单中选择Other,在MyEclipse Enterprise Workbench目录下找到DB Browser数据库浏览器,先新建一个数据库连接驱动,输入正确的Connection URL数据库连接字符串和用户名密码,Add JARs选择本地的数据驱动文件,系统会自动选择驱动文件里的驱动类,完成之后在DB Browse里就多了一个数据库连接项,选择一个配置好的数据库连接项右击Open Connection连接,如果我们可以看到数据库和下面的表则证明配置数据库连接成功。右击工程项目选择MyEclipse菜单中的Add Hibernate Capabilities项,添加对Hibernate标签库的引用,选择Hibernate 3.1版,Next下一步使用hibernate.cfg.xml默认配置文件名,在连接数据库的步骤里我们选择JDBC驱动连接方式,在DB Driver下拉列表项中我们可以看到刚开始在DB Browser里配置好的数据库连接,选择一个下面的Connection URL数据库连接字符串和用户名密码自动填充,如果MyEclipse还未使用DB Browser数据库连接浏览器,我们可以先新建一个DB Browser数据库连接或直接在这一步骤手动输入数据库连接信息(建议先在DB Browser里配置一个数据库连接,因为后面实体映射也将要用到DB Browser),在Next下一步里选择创建一个SessionFactory类,输入Java package包名,如果没有预先创建好可以选择后面New新建一个,Finish完成之后项目就会添加Hibernate3.1 Core Libraries核心标签库,以及HibernateSessionFactory类和hibernate.cfg.xml数据库连接配置文件。

二、使用Hibernate映射数据库到实体类

配置好Hibernate的连接之后,我们需要对数据库表进行与实体映射,打开DB Browser数据库浏览器,找到要映射的表右击Hibernate Reverse Engineering,Hibernate会根据数据库表反向生成实体类,这里我们预先在数据库里创建一个FA_User表,SQL语句如下:

create table FA_User(
userid
number not null,
username
varchar2(20) not null,
password
varchar(32) not null,
usernike
varchar2(20),
regtime date
not null,
constraint PK_FA_User primary key(userid)
);

 在Hibernate Reverse Engineering映射选项里,先选择Java src folder添加到的包文件夹,勾选Hibernate mapping file(*.hbm.xml) for each database table,将产生一个实体映射到对应表的xml配置文件;勾选Java Data Object (POJO <> DB Table),将根据数据库表结构反向产生一个Java实体类,取消Create abstract class选项将不创建为抽象类,默认为implements实现java.io.Serializable可序列化的实体类,当然可为实体类指定Base persistent class基类;勾选Java Data Access Object (DAO),会创建实体类的数据访问类(DAO),这里我们勾选选择产生,Next下一步类可配置映射的一些选项,如在Customized Type Mappings里我们可以自定义数据库类型映射到实体的类型,这里我们按默认就好,Next下一步,选择表后在右边输入映射的Class name类和ID Generator主键生成类型,类名注意是要包括包的全名,主键类型则应该根据连接的数据库类定,如mysql为auto_increment自动增加主键类型应该选increment,sqlserver数据库自增则选择identity,这么我们使用oracle序列则选择sequence,大家也可以去研究其他类型的用法。下面Include referenced tables (A->B)和Include referenced tables (A<-B)可以包含A引用表和被引用表,在实体里面将创建各引用表的对应关系。完成之后工程将新加如下文件:

名称 描述
IBaseHibernateDAO 数据库访问会话接口
BaseHibernateDAO IBaseHibernateDAO接口实现类,数据访问基类
HibernateSessionFactory 会话工厂实现类
UserDAO User表数据访问类
User User实体类
User.hbm.xml User表映射对应关系配置文件

三、创建struts应用程序

上面配置好Hibernate数据访问框架后,我们来创建一个Struts简单应用程序使用Hibernate访问数据库,首先需要在工程里添加对Struts的引用,右击项目工程在菜单中选择MyEclipse项中的Add Struts Capabilities,选择Struts 1.2版本,修改Base package for new classes默认创建的action包名,点击完成添加对Struts标签库的使用。下面我们先完成一个简单的添加用户功能,先新建useradd.jsp页面,然后依次新建Struts From(UserFrom)和Struts Action(UserAction)。为了更好的配合Hibernate,在Struts From里直接使用Hebernate生成的实体类做为表单元素,同时便于维护,避免创建多个结构相同的表单,UserFrom代码如下:

package struts.form;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;

public class UserForm extends ActionForm {
private hb.User user = new hb.User();
private List list;
public List getList() {
return list;
}

public void setList(List list) {
this.list = list;
}

public hb.User getUser() {
return user;
}

public void setUser(hb.User user) {
this.user = user;
}

public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
// TODO Auto-generated method stub
return null;
}

public void reset(ActionMapping mapping, HttpServletRequest request) {
// TODO Auto-generated method stub
}
}

要注意上面的Struts Form使用的是user对象里面的字段,所以一定要默认初始化,不然将会出错。同时修改对应的useradd.jsp页面:

<pre style="color:red"><html:errors /></pre>
<html:form action="/user.do">
<p>
用户名:
<html:text property="user.username"></html:text>
</p>
<p>
密 码:
<html:password property="user.password"></html:password>
</p>
<p>
昵 称:
<html:text property="user.usernike"></html:text>
</p>
<p>
<html:submit value="提交"></html:submit>
</p>
</html:form>

注意上面property与实体属性的对应关系,在提交表单的时候,表单的值将填充到对应的property属性,在Struts Action里我们对输入的值进行一个简单的效验,execute方法如下:

UserForm userForm = (UserForm) form;
ActionMessages errors
= new ActionMessages();
hb.UserDAO dao
= new hb.UserDAO();
String username
= userForm.getUser().getUsername(),password = userForm.getUser().getPassword();
if( username==null || username.trim().length()==0)
{
errors.add(
"username",new ActionMessage("用户名不能为空\n",false));
}
else if( dao.findByUsername(username).size() > 0)
{
errors.add(
"username",new ActionMessage("用户名已经存在\n",false));
}
if( password==null || password.length() == 0)
{
errors.add(
"password",new ActionMessage("密码不能为空\n",false));
}
if( errors.size() > 0 )
{
this.saveErrors(request,errors);
return mapping.getInputForward();
}
userForm.getUser().setRegtime(
new java.util.Date());
dao.merge(userForm.getUser());
return new ActionRedirect("/index.jsp?msg=success");

编译重新运行,跳转提示保存成功,我们在来看下数据库,唉,数据库里没有记录,没有插入成功?这是因为Hibernate的默认merge方法里没有提交事务的原因,修改merge方法如下以进行提交。

public User merge(User user) {
Session session
= getSession();
Transaction tr
= session.beginTransaction();
try {
tr.begin();
User result
= (User) session.merge(user);
tr.commit();
return result;
}
catch (RuntimeException re) {
tr.rollback();
throw re;
}
}

当然我们也可以在hibernate.cfg.xml配置文件里进行全局设置,在session-factory节点下增加<property name="connection.autocommit">true</property>设置Hibernate默认提交事物,另外我们还需要注意Hibernate对象有三种状态,各种保存方法存在很大的区别,Eclipse自动生成的方法如下:

方法名 备注
save 把一个新的对象保存
delete 删除,持久化实例调用变成脱管状态
findById 按ID查询数据
findByExample 按传入实体对象所有字段值条件查询
findByProperty 按某一字段属性值查
findAll 返回所有
merge 想当于save or update,并把一个游离态状态的对象转换为一个持久态对象,且返回这个对象
attachDirty 将传入的对象持久化并保存
attachClean

将传入的对象状态设置为Transient瞬态或者自由态

更多Hibernate对象状态和方法的详细介绍:http://www.blogjava.net/dreamstone/archive/2007/07/29/133071.html

更多Hibernate查询化语言HQL:http://blog.csdn.net/wllyy189/archive/2007/08/19/1750240.aspx

四、使用DispatchAction类执行不同方法

DispatchAction是继承自org.struts.action.Action的抽象类,它会根据request中的parameter来执行相应的方法,通个这个Action类可以将不同的Action集中到一个Action文件中来。还是以上面User为例,之前在UserAction的execute方法中实现了useradd添加用户功能,那我们现在继续在UserAction实现login用户登陆功能。首先需要修改struts-config.xml配置文件的Action的parameter为"action",那么在UserAction里将根据参数action执行方法,注意不要在UserAction里重写execute方法,不然不会执行对应的方法,unspecified是默认执行方法,另外所有执行方法的参数和返回类型必须和execute方法相同,UserAction代码如下:

public class UserAction extends org.apache.struts.actions.DispatchAction {

//默认执行方法
public ActionForward unspecified(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
try {
response.getOutputStream().print(
"unspecified default method");
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

//添加用户
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
UserForm userForm
= (UserForm) form;
ActionMessages errors
= new ActionMessages();
hb.UserDAO dao
= new hb.UserDAO();
String username
= userForm.getUser().getUsername(),password = userForm.getUser().getPassword();
if( username==null || username.trim().length()==0)
{
errors.add(
"username",new ActionMessage("用户名不能为空\n",false));
}
else if( dao.findByUsername(username).size() > 0)
{
errors.add(
"username",new ActionMessage("用户名已经存在\n",false));
}
if( password==null || password.length() == 0)
{
errors.add(
"password",new ActionMessage("密码不能为空\n",false));
}
if( errors.size() > 0 )
{
this.saveErrors(request,errors);
return new ActionForward("/useradd.jsp");
}
userForm.getUser().setRegtime(
new java.util.Date());
dao.merge(userForm.getUser());
return new ActionRedirect("/index.jsp?msg=success");
}

//登陆
public ActionForward login(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
UserForm userForm
= (UserForm) form;
ActionMessages errors
= new ActionMessages();
hb.UserDAO dao
= new hb.UserDAO();
String username
= userForm.getUser().getUsername(),password = userForm.getUser().getPassword();
if( username==null || username.trim().length()==0)
{
errors.add(
"username",new ActionMessage("用户名不能为空\n",false));
}
else if( password==null || password.length() == 0)
{
errors.add(
"password",new ActionMessage("密码不能为空\n",false));
}
else if( dao.login(username, password)==null)
{
errors.add(
"username",new ActionMessage("用户名或密码错误\n",false));
}
if( errors.size() > 0 )
{
this.saveErrors(request,errors);
return new ActionForward("/login.jsp");
}
return new ActionRedirect("/index.jsp?msg=success");
}

}

那jsp页面action的提交地址也要相应的改变,通过/user.do?method=add传递parameter中参数调用相应的方法,struts-config.xml配置文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">

<struts-config>
<data-sources />
<form-beans >
<form-bean name="userForm" type="struts.form.UserForm" />
</form-beans>
<global-exceptions />
<global-forwards >
<forward name="userlist" path="/index.jsp"></forward>
</global-forwards>
<action-mappings >
<action
parameter="action"
name
="userForm"
path
="/user"
scope
="request"
type
="struts.action.UserAction"
validate
="false" />
</action-mappings>
<message-resources parameter="ApplicationResources" />
</struts-config>

Struts除此之外还有LookupDispatchAction、MappingDispatchAction两种类型的Action,这里简单的介绍下:LookupDispatchAction继承自DispatchAction,它的相应方法的执行由 ActionMapping中parameter属性决定。它适合在一个form中有很多按钮,按不同的按钮则执行不同的操作,同时在Action中必须实现getKeyMethodMap方法返回HashMap按钮和调用方法的键值对。MappingDispatchAction同样继承自DispatchAction,它的相应方法的执行由 ActionMapping中parameter名决定,注意这里和LookupDispatchAction不同,它是通过struts-config.xml将多个action-mapping映射到同一个Action类的不同方法上,也就是说在struts-config.xml配置多个Action指向同一个Action类但不同方法上。上面add和login这个方法的配置就应该为:

<action path="/user/add" parameter="add"
name
="userForm" scope="request"
type
="struts.action.UserAction" />
<action path="/user/login" parameter="login"
name
="userForm" scope="request"
type
="struts.action.UserAction" />

五、部署到Linux的Webligic应用服务器

以我公司的Redhat Linux AS4服务器为例,首先需要下载一个Weblogic安装程序,由于bea被oracle收购了,所以去oracle网站http://download.oracle.com/otn/linux/middleware/11g/wls/oepe11_ccjk_wls1031_linux32.bin下载一个linux版安装包,这里提醒大家不要去下载在线安装的,我因为用在线安装出错而重新安装了好几次,安装会默认装好JDK,这样我们创建一个weblogic的虚拟目录就能用了,weblogic安装完成后有一个http://localhost:7001/console的Web控制台,如果安装没有创建一个domain的话我们可以进那里创建一个。我的默认安装主目录是/root/Oracle/Middleware/,默认域网站目录为/root/Oracle/Middleware/user_projects/domains/base_domain/autodeploy,只要我们把打包好的网站上传到该目录即可,启动服务执行/root/Oracle/Middleware/user_projects/domains/base_domain/startWebLogic.sh。

由于使用的是Linux服务器,而开发我们是使用Windows系统,上传发布网站文件共享可使用Samba服务,Linux默认是关闭Samba服务的,使用service smb start命令可开启服务,下面在Linux下简单配置一个匿名用户可读可写的权限,vi /etc/samba/smb.conf修改smb配置文件内容如下:

[global]
workgroup
= FA
netbios name
= Linux
server
string = Linux Samba Server
security
= share

[weblogic]
path
= /root/Oracle/Middleware
writeable
= yes
browseable
= yes
guest ok
= yes

第二步,建立相应目录并授权,使用命令chown -R nobody:nobody /root/Oracle/Middleware为匿名用户和匿名用户组授权/root/Oracle/Middleware目录,service smb restart重起smb服务,windows下使用\\Linux就能访问到共享的Middleware目录,将部署好的Java工程项目拷贝到/root/Oracle/Middleware/user_projects/domains/base_domain/autodeploy目录下,使用http://192.168.0.249:7001/context就能访问到对应网站。这里要注意在weblogic中的路径问题,使用class.getClassLoader().getResource("").getPath()获取资源文件路径得到的不是WEB-INF/classes目录,而是webloic的lib主目录/root/Oracle/Middleware/wlserver_10.3/common/lib,而tomcat里正常。另外在weblogic里部署网站时候一些hibernate类文件也提示没有加载,后来在网站WEB-INF目录下增加weblogic.xml配置文件修改类的加载路径后解决。

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://www.bea.com/ns/weblogic/90">
<charset-params>
<input-charset>
<resource-path>/*</resource-path>
<java-charset-name>UTF-8</java-charset-name>
</input-charset>
</charset-params>
<context-root>Hibernate</context-root>
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
</weblogic-web-app>
标签:Java
  • posted@ 2010-01-06 19:59
  • update@ 2010-01-08 20:00:26
  • 阅读(13812)
  • 评论(0)

相关文章

评论
暂无任何评论。
发表评论
*必填
回复通知我
*必填

博文推荐