完成之后的项目结构为:
2.把该加的包复制到项目里
找到项目所在文件夹,把下载的包复制粘贴到lib文件夹里,然后在MyEclipse里面刷新项目。
3.去数据库里建表,数据库我用的是mysql5.1
新建数据库,命名为ssh。
新建表user_info,sql如下:
CREATE TABLE `user_info` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`username` varchar(30) NOT NULL,
`password` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into user_info values(1,'a','a');
4.建立数据库连接,添加hibernate
在MyEclipse中,将视图切换到MyEclipse Database Explorer,新建一个数据库连接
点击“Add JARs”,选择项目中lib文件夹里的mysql-connector-java-5.0.6-bin.jar
接下来,可以点击“Next”选择要添加的数据库,也可以直接Finish。
在左侧双击刚才新增的数据库连接,输入密码,就可以看到ssh下面的user_info表了。
回到MyEclipse默认视图,为项目添加hibernate支持,右键点击项目名称-MyEclipse-Add Hibernate Capabilities
然后点击finish,可能有些包已经存在了,没关系,下面继续。
在src下新建一个package,model.system。
回到数据库视图,右键点击user-info表,选择Hibernate Reverse Engineering
直接点Finish。这里为什么要选identity,请见附录说明。
现在可以看到已经添加好的文件,为了方便,现在开始ssh项目使用navigator视图(右键点项目-Show In-Navigator)。
点开hibernate.cfg.xml看一下,它应该是这样子的:
5.修改web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- spring相关配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml,classpath*:/context/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- 以下3项参数与log4j的配置相关 -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.util.Log4jConfigListener
</listener-class>
</listener>
<!-- end -->
<!-- struts2相关配置 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteF
ilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
6.添加applicationContext.xml
在WEB-INF下新建applicationContext.xml文件
内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!--指明hibernate配置文件的位置
-->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
</bean>
<!--定义DAO
-->
<bean id="userDao" class="dao.system.UserDao">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<!--
配置LoginAction.java类文件 -->
<bean id="LoginAction" class="action.login.LoginAction" scope="prototype">
<property name="userService" ref="userService" />
</bean>
<!-- 配置service层 -->
<bean id="userService" class="service.system.UserService">
<property name="userDao">
<ref bean="userDao"/>
</property>
</bean>
</beans>
7.添加spring支持
右键点击项目-MyEclipse-Add Spring Capabilities
记得选上Spring 3.0 Web Libraries。
点击Finish。
8.添加dao,service和action
结构如下:
UserDao.java内容如下:
package dao.system;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import model.system.UserInfo;
public class UserDao extends HibernateDaoSupport{
public void add(UserInfo m)
{
getHibernateTemplate().save(m);
}
@SuppressWarnings("unchecked")
public List<UserInfo> showAllUsers()
{
return getHibernateTemplate().find("from user");
}
public void update(UserInfo m)
{
getHibernateTemplate().update(m);
}
public void delete(String id)
{
getHibernateTemplate().delete(getHibernateTemplate().get(UserInfo.class, id));
}
public UserInfo getUserById(String id)
{
UserInfo m=(UserInfo)getHibernateTemplate().get(UserInfo.class, id);
return m;
}
//普通用户登录验证
@SuppressWarnings("unchecked")
public boolean checkUser(String userName,String userPassword){
boolean flag = false;
String hql = "from UserInfo as user where user.username = '"+userName+"' and user.password = '"+userPassword+"'";
List<UserInfo> userList = this.getHibernateTemplate().find(hql);
if(userList.size()>0){
flag = true;
}
return flag;
}
}
UserService.java内容如下:
package service.system;
import dao.system.UserDao;
public class UserService{
private UserDao userDao;
public boolean checkUser(String userName,String userPassword)
{
return userDao.checkUser(userName, userPassword);
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
LoginAction.java内容如下:
package action.login;
import com.opensymphony.xwork2.ActionSupport;
import service.system.UserService;
public class LoginAction extends ActionSupport{
private static final long serialVersionUID = 3989633817331294940L;
private String username;
private String password;
private UserService userService = new UserService();
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String execute(){
boolean flag = false;
if (username == null || username.trim().equals("")) {
this.addFieldError("username", "用户名不能为空");
return "fail";
} else if (password == null || password.trim().equals("")) {
this.addFieldError("password", "密码不能为空");
return "fail";
} else {
flag = userService.checkUser(username, password);
if (flag) {
return "success";
} else {
return "fail";
}
}
}
}
9.添加struts支持
右键点击项目-MyEclipse-Add Struts Capabilities
其他的选默认就行,然后Finish。
10.修改struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<!--下述语句是将struts2交给spring管理 -->
<constant name="struts.objectFactory" value="spring" />
<!--将action内容放在package元素下,package元素的name值与extends值可以使用默认值,如下所示 -->
<package name="ssh" extends="struts-default">
<!--例如与用户登录相关的LoginAction,配置如下,其中,class值与applicationContext.xml文件中该action的id值相对应,name值作为标识-->
<action name="loginAction" class="LoginAction">
<!--result元素设置页面跳转值,其中name值为目标页面的字符串标识,如下,登录失败时回到fail.jsp页面,成功时,转向success.jsp页面 -->
<result name="fail">/jsp/login/fail.jsp</result>
<result name="success">/jsp/login/success.jsp</result>
</action>
</package>
</struts>
11.添加页面
累了吧?快成功了,下面继续。
在WebRoot文件夹下面新建一个jsp文件夹,存放页面。
结构如下:
fail.jsp内容如下:
<%@ page language="java" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>Fail</title>
</head>
<body>
登陆失败。<br>
</body>
</html>
success.jsp内容如下:
<%@ page language="java" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>Success</title>
</head>
<body>
登陆成功。<br>
</body>
</html>
修改index.jsp,内容如下:
<%@ page language="java" pageEncoding="utf-8"%>
<!-- 导入struts2标签库 -->
<%@taglib uri="/struts-tags" prefix="s"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<html>
<head>
<title>用户登录</title>
</head>
<body>
<center>
<div id="login">
<s:form action="loginAction" method="post">
<s:textfield label="用户名" name="username"></s:textfield>
<s:password label="密码" name="password"></s:password>
<s:submit value="登录"></s:submit>
</s:form>
</div>
</center>
</body>
</html>
12.新增log4j.properties文件
放在WEB-INF下
内容如下:
#newhappy
log4j.properties start
log4j.rootLogger=DEBUG,myConsole,R
#console appender
log4j.appender.myConsole=org.apache.log4j.ConsoleAppender
log4j.appender.myConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.myConsole.layout.ConversionPattern=%5p [%t] (%F:%L) -%m%n
log4j.appender.myConsole.threshold=INFO
# R is set to be a DailyRollingFileAppender
.
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=D:\workspaces\job\job\WebRoot\WEB-INF\backup.log
log4j.appender.R.DatePattern = '.'yyyy-MM-dd
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n
log4j.appender.R.threshold=INFO
#rolling file appender
#log4j.appender.myLogFile=org.apache.log4j.RollingFileAppender
#log4j.appender.myLogFile.File=mylog.log
#log4j.appender.myLogFile.MaxFileSize=500KB
#log4j.appender.myLogFile.MaxBackupIndex=2
#log4j.appender.myLogFile.layout=org.apache.log4j.PatternLayout
#log4j.appender.myLogFile.layout.ConversionPattern=%d{mmm d,yyyy hh:mm:ss a} : %p [%t] %m%n
#log4j.appender.myLogFile.threshold=ERROR
#newhappy log4j.properties end
log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug
### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug
### log just the SQL
#log4j.logger.org.hibernate.SQL=debug
### log JDBC bind parameters ###
log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug
### log schema export/update ###
log4j.logger.org.hibernate.tool.hbm2ddl=debug
log4j的配置是从网上找的,如果有问题再自己调一下吧。
13.运行调试
配置好tomcat,然后发布,运行一下看看。
报错了?
没关系,因为起初先导入了一些包,后期又分别添加了hibernate,srping和struts,所以可能有包重复了。
解决办法:先关掉MyEclipse,找到项目所在文件夹,把lib里面的包全部删除,换上我们一开始下载的那些包。别忘了把tomcat下webapps/ssh,lib里面的包也全部更换。这样应该就不会报错了。
就知道你懒得一步步搭环境,想要这个ssh小项目的源代码,请往右看->http://115.com/lb/5lbxl190#
ssh.rar
115网盘礼包码:5lbxl190
14.可能出错的地方
本来看上去很简单的过程,我才不告诉你我居然折腾了快两个星期呢。
一开始我没有自己导入包,按照网上的一个教程,全部是用MyEclipse自带的,自动生成的applicationContext.xml文件放在src文件夹下,然后web.xml里面写的是:
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/applicationContext*.xml</param-value>
这样写似乎是无法找到src下的这个配置文件,于是我的struts和spring一直整合不成功,后来看了这个帖子:
http://bbs.csdn.net/topics/380074729?page=1#post-394873936
改成:
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml,classpath*:/context/applicationContext*.xml</param-value>
就好了。
整合过程中可能出现的问题基本是就是这样,要么是包冲突、包重复、包缺失,要么就是配置文件找不到,或者文件路径不对。
15.附录
前面还有一点遗留问题,ID的generator为什么要选identity呢?
我之前找到的一个关于整合SSH的PPT里是这样解答的:
Hibernate中,<id>标签下的可选<generator>子元素是一个Java类的名字,用来为该持久化类的实例生成惟一标示,所有的生成器都实现net.sf.hibernate.id.IdentifierGenerator接口。这是一个非常简单的接口,某些应用程序可以选择提供它们自己的特定实现。当然,Hibernate提供了很多内置的实现。
下面是一些内置主键生成器(Key Generator):
1)assigned
主键由外部程序负责生成,无需Hibernate参与。
让应用程序在save()之前为对象分配一个标示符。
这是 <generator>元素没有指定时的默认生成策略。
2)hilo
通过hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态。
使用一个高/低位算法高效的生成long, short或者int类型的标识符。
给定一个表和字段(默认分别是hibernate_unique_key 和next_hi)作为高位值的来源。
高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
3)seqhilo
与hilo 类似,通过hi/lo 算法实现的主键生成机制,只是主键历史状态保存在Sequence中,适用于支持Sequence的数据库,如Oracle。
使用一个高/低位算法来高效的生成long, short 或者 int类型的标识符,给定一个数据库序列(sequence)的名字。
4)increment
主键按数值顺序递增此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。
这种方式可能产生的问题是:如果当前有多个实例访问同一个数据库,那么由于各个实例各自维护主键状态,不同实例可能生成同样的主键,从而造成主键重复异常因此,如果同一数据库有多个实例访问,此方式必须避免使用。
用于为long,short或者int类型生成唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。在集群下不要使用。
5)identity
采用数据库提供的主键生成机制如DB2 SQL Server MySQL中的主键生成机制。
对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。
返回的标识符是long, short 或者int类型的。
6)sequence
采用数据库提供的sequence机制生成主键如Oralce中的Sequence。
在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence),而在Interbase中使用生成器(generator)。
返回的标识符是long, short或者 int类型的。
7)native
由Hibernate根据底层数据库自行判断,采用identity hilo sequence其中一种作为主键生成方式。
8)uuid.hex
用一个128-bit的UUID算法生成字符串类型的标识符, 这在一个网络中是唯一的(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。
由Hibernate基于128 位唯一值产生算法生成16 进制数值(编码后以长度32 的字符串表示)作为主键例如:5abefd3890cat33llsica3ee43bk222
9)uuid.string
与uuid.hex 类似,只是生成的主键未进行编码(长度16),在某些数据库中可能出现问题(如PostgreSQL)。
10)guid
在MS SQL Server 和 MySQL 中使用数据库生成的GUID字符串。
11)select
通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。
12)foreign
使用另外一个相关联的对象的标识符。通常和<one-to-one>联合起来使用。
一般而言,利用uuid.hex方式生成主键将提供最好的性能和数据库平台适应性。另外由于常用的数据库,如Oracle DB2 SQLServer MySql 等,都提供了易用的主键生成机制(Auto-Increase 字段或者Sequence)。我们可以在数据库提供的主键生成机制上,采用generator-class=native的主键生成方式。不过值得注意的是,一些数据库提供的主键生成机制在效率上未必最佳,大量并发insert数据时可能会引起表之间的互锁。
数据库提供的主键生成机制,往往是通过在一个内部表中保存当前主键状态(如对于自增型主键而言,此内部表中就维护着当前的最大值和递增量),之后每次插入数据会读取这个最大值,然后加上递增量作为新记录的主键,之后再把这个新的最大值更新回内部表中,这样,一次Insert操作可能导致数据库内部多次表读写操作,同时伴随的还有数据的加锁解锁操作,这对性能产生了较大影响因此,对于并发Insert要求较高的系统,推荐采用uuid.hex 作为主键生成机制。
发表评论 取消回复