了解SSH的框架对于整个网上商城的Web项目开发有很大作用。
准备
首先需要两种包:一种是struts2的包,一种是hibernate包。一般下载新版本(或稳定版)都可以。如果有不懂得,可以选着一些帮助文档看看,这里就不细说明了。
SSH框架
SSH框架是由Action、Service、Dao、 Vo、页面(这里以JSP为主)所构成,并通过配置文件进行配置,相互协作,实现功能的技术。
首先需要创建包,如下图所示
然后里面对应的是Action、Service、Dao、 Vo的子包
这里我们使用的action是adminaction,在学习网上商城的时候,视频中没有设计用户管理的操作,然后兴趣而发,自己设计了查询所有用户的管理(不一定适用,仅限框架了解)
Vo层
首先要创建的是vo层,vo层内包含的是对象的实体类(这里是用户模块的实体类)。
package cn.itcast.shop.user.vo;
/*
* 用户模块的实体类
* CREATE TABLE `user` (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`phone` varchar(255) DEFAULT NULL,
`addr` varchar(255) DEFAULT NULL,
`state` int(11) DEFAULT NULL,
`code` varchar(64) DEFAULT NULL,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
*/
public class User {
private Integer uid;
private String username;
private String password;
private String name;
private String email;
private String phone;
private String addr;
private Integer state;
private String code;
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
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 getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
实体反射配置
然后需要对其进行反射文件的配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name = "cn.itcast.shop.user.vo.User" table="user">
<id name="uid">
<generator class="native"/>
</id>
<property name="username"/>
<property name="password"/>
<property name="name"/>
<property name="email"/>
<property name="phone"/>
<property name="addr"/>
<property name="state"/>
<property name="code"/>
<!-- 关联关系:与订单的关系 -->
<!-- <set name="orders">
<key column="uid"/>
<one-to-many class="cn.itcast.shop.order.vo.Order"/>
</set> -->
</class>
</hibernate-mapping>
这样实体类就可以在其他包层内进行使用,并可以与数据库建立通过接口进行直接连接,当然还需要在配置文件中进行配置,下面会提到。
Action层
接下来,action层就是一般的数据接收和传递层,action将接受的数据传递给service进行处理package cn.itcast.shop.user.adminaction;
import cn.itcast.shop.user.service.UserService;
import cn.itcast.shop.user.vo.User;
import cn.itcast.shop.utils.PageBean;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
/*
* 后台管理用户的类
*/
public class AdminOrdinaryUserAction extends ActionSupport implements ModelDriven<User>{
//模型驱动使用的对象
private User user = new User();
public User getModel() {
return user;
}
//接收page参数
private Integer page;
public void setPage(Integer page) {
this.page = page;
}
//注入service
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
//带分页查询所有的用户
public String findAll(){
//调用service,查询所有用户,参数为page
PageBean<User> pageBean = userService.findAll(page);
//将数据保存到页面
ActionContext.getContext().getValueStack().set("pageBean", pageBean);
return "findAll";
}
}
Service层
由service将处理的信息传递给dao层进行数据库操作(商品的PageBean是utils包中封装起来的复用的类)
package cn.itcast.shop.user.service;
import java.util.List;
import org.springframework.transaction.annotation.Transactional;
import cn.itcast.shop.user.dao.UserDao;
import cn.itcast.shop.user.vo.User;
import cn.itcast.shop.utils.MailUtils;
import cn.itcast.shop.utils.PageBean;
import cn.itcast.shop.utils.UUIDUtils;
/*
* 用户名模块业务层代码
*/
@Transactional //事务注解
public class UserService {
//注入UserDao
private UserDao userDao;
//后台管理用户的方法
public PageBean<User> findAll(Integer page) {
//创建分页用户集合
PageBean<User> pageBean = new PageBean<User>();
//设置当前页数
pageBean.setPage(page);
//设置每页显示的记录数
int limit = 10 ;
//设置总的记录数
int totalCount = 0;
totalCount = userDao.findCount();
pageBean.setTotalCount(totalCount);
//设置总的页数
int totalPage = 0;
if (totalCount % limit == 0) {
totalPage = totalCount / limit;
}else {
totalPage = totalCount / limit + 1;
}
pageBean.setTotalPage(totalPage);
//设置每页数据的集合
//设置起始页
int begin = (page - 1) * limit;
List<User> list = userDao.findByPage(begin,limit);
pageBean.setList(list);
return pageBean;
}
}
这里面就是对pageBean进行业务处理,将pageBean对象所需内容进行设置,并通过带分页查询数据,将查询到的数据继续设置给pageBean,由pageBean返回到action中。
Dao层
package cn.itcast.shop.user.dao;
import java.util.List;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import cn.itcast.shop.user.vo.User;
import cn.itcast.shop.utils.PageHibernateCallback;
/*
* 用户模块持久层代码
*/
public class UserDao extends HibernateDaoSupport {
//DAO层查询总记录数
public int findCount() {
String hql = "select count(*) from User";
List<Long> list = this.getHibernateTemplate().find(hql);
if (list != null && list.size()>0) {
return list.get(0).intValue();
}
return 0;
}
//DAO层带分页查询用户信息
public List<User> findByPage(int begin, int limit) {
String hql = "from User order by uid desc";
List<User> list = this.getHibernateTemplate().execute(new PageHibernateCallback<User>(hql,null,begin,limit));
if (list != null && list.size()>0) {
return list;
}
return null;
}
}
DAO层类继承了HibernateDaoSupport,这个接口可以实现对数据库的操作,并得到我们需要的结果。
值栈存数据
数据传到了,并通过值栈的方式保存数据
ActionContext.getContext().getValueStack().set("pageBean", pageBean);
然后我们就可以去页面上进行获取值栈数据了。在这之前,需要解决我们的配置问题
applicationContext.xml
<!-- 配置连接池: -->
<!-- 引入外部属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置C3P0连接池: -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- Hibernate的相关信息 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 注入连接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 配置Hibernate的其他的属性 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.connection.autocommit">false</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 配置Hibernate的映射文件 --><!-- 来源于各实体类的映射文件*.hbm.xml -->
<property name="mappingResources">
<list>
<value>cn/itcast/shop/user/vo/User.hbm.xml</value>
</list>
</property>
</bean>
<!-- 配置后台用户管理的Action -->
<bean id="adminOrdinaryUserAction" class="cn.itcast.shop.user.adminaction.AdminOrdinaryUserAction" scope="prototype">
<property name="userService" ref="userService"></property>
</bean>
<!-- Service的配置 ===========================-->
<bean id="userService" class="cn.itcast.shop.user.service.UserService">
<property name="userDao" ref="userDao"/>
</bean>
<!-- Dao的配置 ===========================-->
<bean id="userDao" class="cn.itcast.shop.user.dao.UserDao">
<property name = "sessionFactory" ref="sessionFactory"/>
</bean>
struts.xml配置
<struts>
<constant name="struts.devMode" value="false" />
<package name="shop" extends="struts-default" namespace="/">
<!-- 配置后台用户管理的Action -->
<action name="adminOrdinaryUser_*" class="adminOrdinaryUserAction" method="{1}">
<result name="findAll">/admin/user/list.jsp</result>
</action>
</package>
</struts>
一定要注意,struts中配置的action的class要与applicationContext.xml设置的对应的action里bean标签name相同,否则就会编译失败。
扩展
那么在页面上是如何接受数据的呢?
一般而言,如果只是一个对象的变量,我们可以通过session值保存,而如果是集合数据(复杂类型),我们最好使用值栈的方式,就如上面使用的那样。
通常都需要引入在页面上引入标签库:
<%@ taglib uri="/struts-tags" prefix="s"%>
取值栈数据
<s:iterator var="user" value="pageBean.list" status="status">
<td style="CURSOR: hand; HEIGHT: 22px" align="center" width="18%"><s:property value="#user.username" /></td>
</s:iterator>
取session数据
<s:property value="#session.cart.total"/>
模型驱动取数据
另外在action由于实现了ModelDriven类,模型驱动(即设置为模型的对象类可以直接在页面和服务器间传递数据,并被直接使用
<s:property value="model.total"/>