购物商城shopping连载(6)

本文介绍了一款电商网站的首页实现过程,包括一级分类、热门商品和最新商品的查询及展示。通过Hibernate进行数据库操作,并利用Struts2框架完成前端页面的渲染。

模块1:一级分类

用户成功登陆之后,会跳转到首页,现在我们来制作一级分类。
先看一张商城首页的图:

这里写图片描述

图是从网上找的,那个被红框框住的就是一级分类。
点击一级分类后跳转到一个新的页面,这个页面左边是所有一级分类和二级分类的列表,右边是二级分类的所有商品。
点击一级分类后跳转的页面:

这里写图片描述

左边蓝字是一级分类,黑字是一级分类下的二级分类,右边是所有商品,分页显示。

准备工作

这里阐明一下表关系:
一级分类表对二级分类表是一对多关系
二级分类表对商品表是一对多关系

这里写图片描述

一级分类实体:

//一级分类
@SuppressWarnings("serial")
public class Category implements Serializable {
    private long cid; // id
    private String cname; // 一级分类名称
    // 一级分类中存放二级分类的集合:
    private Set<CategorySecond> categorySeconds = new HashSet<CategorySecond>();
    //省略setter getter方法

一级分类映射文件:

<?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="com.shopping.category.entity.Category" table="category">
        <id name="cid">
            <generator class="native"/>
        </id>

        <property name="cname"/>

        <!-- 配置二级分类的集合 -->
        <set order-by="csid" name="categorySeconds" lazy="false">
            <key column="cid"/>
            <one-to-many class="com.shopping.categorySecond.entity.CategorySecond"/>
        </set>

    </class>
</hibernate-mapping>

二级分类实体:

SuppressWarnings("serial")
public class CategorySecond implements Serializable {
    private long csid; //id
    private String csname; //二级分类名称
    // 所属一级分类.存的是一级分类的对象. 
    private Category category; //一级分类对象
    // 配置商品集合,一对多
    private Set<Product> products = new HashSet<Product>();
    //省略setter getter方法

二级分类映射文件:

<?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="com.shopping.categorySecond.entity.CategorySecond" table="categorysecond">
        <id name="csid">
            <generator class="native"/>
        </id>

        <property name="csname"/>
        <!-- 二级分类与一级分类的guanlian -->
        <many-to-one name="category" lazy="false" class="com.shopping.category.entity.Category" column="cid"></many-to-one>

        <!-- 二级分类与商品的关联 -->
        <set name="products">
            <key column="csid"/>
            <one-to-many class="com.shopping.product.entity.Product"/>
        </set>
    </class>
</hibernate-mapping>

商品实体:

@SuppressWarnings("serial")
public class Product implements Serializable{
    private long pid; //商品id
    private String pname; //商品名称
    private Double market_price; //市场价
    private Double shop_price; //商城价
    private String image; //图片路径
    private String pdesc; //商品描述
    private Integer is_hot;  //是否热门商品
    private Date pdate; //上架时间
    // 二级分类的外键:使用二级分类的对象.
    private CategorySecond categorySecond;
    //省略setter getter方法

商品映射文件:

<?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="com.shopping.product.entity.Product" table="product">
        <id name="pid">
            <generator class="native"/>
        </id>
        <property name="pname"/>
        <property name="market_price"/>
        <property name="shop_price"/>
        <property name="image"/>
        <property name="pdesc"/>
        <property name="is_hot"/>
        <property name="pdate"/>

        <many-to-one name="categorySecond" lazy="false" class="com.shopping.categorySecond.entity.CategorySecond" column="csid"/>
    </class>
</hibernate-mapping>

数据库生成的表结构:

这里写图片描述

一级分类

IndexAction ,重新改造shopping方法,在访问首页的时候就查询所有一级分类

JSP:

<!-- 遍历一级分类 -->
                    <s:iterator value="#session.cList" var="c">
                        <li>
                            <a href="./蔬菜分类.htm"><s:property value="#c.cname"/></a>
                            |
                        </li>
                    </s:iterator>

IndexAction:

@SuppressWarnings("serial")
@Controller
@Scope("prototype")
public class IndexAction extends ActionSupport {

    // 注入一级分类service
    @Autowired
    private CategoryService categoryService;

    // 用户访问首页,跳转到WEB-INF下的JSP首页面
    public String shopping() throws Exception {
        // 首页跳转,查询所有一级分类
        List<Category> cList = categoryService.queryAll();
        /***
         * 可以把查询出来的数据放在值栈或者sesson中<br>
         * 因为一级分类每个页面都有,为了不用每次跳转页面都查询<br>
         * 最好把它放入session中.<br>
         * 主要原因就是每个页面都有一级分类,这是关键.
         */
        if(cList!=null&&cList.size()>0){
            //将一级分类存入session中
            ActionContext.getContext().getSession().put("cList",cList);
        }
        return "index";
    }

}

这里说明下为什么把查询到的一级分类存储在session中,一级分类是很多页面都有的,也就是说,一级分类在head.jsp中,为了避免每次点击商城的超链接都去值栈中查询一级分类,所有把它放在了session中。

由代码可知,上面调用了一个queryAll方法,这是方法是BaseDao中的。CategoryService中继承了BaseDao。所以可以直接用。
现在我们在数据库中存几条测试数据,入下图:

这里写图片描述

访问服务器:
这里写图片描述

由上可以看出,访问商城首页可以取出所有一级分类。

模块2:热门商品查询

首页上热门商品的查询,默认只显示10个
思路:
通过QBC查询,根据上传时间的倒序排序,效果如下图:

这里写图片描述

JSP:

<ul class="tabContent" style="display: block;">

                                    <!-- 热门商品 -->
                                    <s:iterator value="hList" var="h">
                                    <li>
                                        <a target="_blank">
                                            <img src="${ pageContext.request.contextPath }/<s:property value="#h.image"/>" 
                                             style="display: block;" /></a>
                                    </li>
                                    </s:iterator>
                                </ul>

IndexAction:

    // 查询热门商品
        List<Product> hList = productService.queryHotProduct();
        if (hList != null && hList.size() > 0) {
            //保存到值栈中
            ActionContext.getContext().getValueStack().set("hList", hList);
        }

由上代码调用了一个queryHotProduct()

ProductService:

public interface ProductService extends BaseDao<Product>{

    /***
     * 商城首页查询热门商品
     * @return
     */
    List<Product> queryHotProduct();

}

ProductServiceImpl:

@Transactional
@Service
public class ProductServiceImpl extends BaseDaoImpl<Product> implements
        ProductService {

    @SuppressWarnings("unchecked")
    @Override
    public List<Product> queryHotProduct() {
        Criteria criteria = sessionFactory.getCurrentSession().createCriteria(
                Product.class);
        criteria.setFirstResult(0);
        criteria.setMaxResults(10);
        // 查询热门的商品,条件is_host = 1
        criteria.add(Restrictions.eq("is_hot", 1));
        // 倒序排序输出:
        criteria.addOrder(Order.desc("pdate"));
        List<Product> pList = criteria.list();
        System.out.println("热门商品个数:"+pList.size());
        return pList;
    }

}

数据库中product中的数据,博主亲自录入的,录不动了就先这么多

这里写图片描述

通过上图可以看到,image的路径是product/1/…
product是一个在项目WebRoot下的文件夹

这里写图片描述

图片都保存在product文件夹中
重启服务器,访问首页:

这里写图片描述

模块3:最新商品

同理和最热商品一样。
只是不用设置查询条件.
JSP:

<!-- 遍历最新商品 -->
                    <s:iterator value="nList" var="n">
                    <li><a target="_blank"><img
                            src="${ pageContext.request.contextPath }/<s:property value="#n.image"/>"
                            style="display: block;"/>
                    </a></li>

                    </s:iterator>

IndexAction:

// 查询最新商品
        List<Product> nList = productService.queryNewProduct();
        if (nList != null && nList.size() > 0) {
            // 保存到值栈中
            ActionContext.getContext().getValueStack().set("nList", nList);
        }

queryNewProduct()方法在service中。
service层:

    /***
     * 查询最新商品
     * @return
     */
    List<Product> queryNewProduct();

service层实现类:

@Override
    public List<Product> queryNewProduct() {
        Criteria criteria = sessionFactory.getCurrentSession().createCriteria(
                Product.class);
        criteria.setFirstResult(0);
        criteria.setMaxResults(10);
        // 倒序排序输出:
        criteria.addOrder(Order.desc("pdate"));
        List<Product> nList = criteria.list();
        return nList;
    }

重启服务器,访问页面

这里写图片描述

这里提一下整体IndexAction上的代码

package com.shopping.index.action;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.shopping.category.entity.Category;
import com.shopping.category.service.CategoryService;
import com.shopping.product.entity.Product;
import com.shopping.product.service.ProductService;

@SuppressWarnings("serial")
@Controller
@Scope("prototype")
public class IndexAction extends ActionSupport {

    // 注入一级分类service
    @Autowired
    private CategoryService categoryService;

    // 注入商品service
    @Autowired
    private ProductService productService;

    // 用户访问首页,跳转到WEB-INF下的JSP首页面
    public String shopping() throws Exception {
        // 首页跳转,查询所有一级分类
        List<Category> cList = categoryService.queryAll();
        if (cList != null && cList.size() > 0) {
            // 将一级分类存入session中
            ActionContext.getContext().getSession().put("cList", cList);
        }
        // 查询热门商品
        List<Product> hList = productService.queryHotProduct();
        if (hList != null && hList.size() > 0) {
            // 保存到值栈中
            ActionContext.getContext().getValueStack().set("hList", hList);
        }
        // 查询最新商品
        List<Product> nList = productService.queryNewProduct();
        if (nList != null && nList.size() > 0) {
            // 保存到值栈中
            ActionContext.getContext().getValueStack().set("nList", nList);
        }
        return "index";
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值