• 展示所有商品案例


    案例一:展示所有商品

    需求:
        点击首页上的超链接,在页面上展示所有的商品信息

    步骤分析:

    alter database hjh character set utf8 collate utf8_bin;设置数据库编码,以避免中文乱码。
    1.数据库和表
            create database hjh;  
            use hjh;
            create table product (
               pid varchar (96),
               pname varchar (150),
               market_price double ,
               shop_price double ,
               pimage varchar (600),
               pdate date ,
               pdesc varchar (765)
            ); 
    INSERT INTO `product` VALUES('1','小米 4c 标准版','1399','1299','products/xiaomi.jpg','2019-11-02','小米 4c 标准版 全网通 白色 移动联通电信4G手机 双卡双待');
    INSERT INTO `product` VALUES('2','华为 Ascend Mate7','2699','2599','products/huawei.jpg','2019-11-02','华为 Ascend Mate7 月光银 移动4G手机 双卡双待双通6英寸高清大屏,纤薄机身,智能超八核,按压式指纹识别!!选择下方“移动老用户4G飞享合约”,无需换号,还有话费每月返还!');
    INSERT INTO `product`  VALUES('3','vivo X5Pro','2399','2298','products/vivo.jpg','2019-11-02','移动联通双4G手机 3G运存版 极光白【购机送蓝牙耳机+蓝牙自拍杆】新升级3G运行内存·双2.5D弧面玻璃·眼球识别技术');
    INSERT INTO `product`  VALUES('4','努比亚(nubia)My 布拉格','1899','1799','products/nubia.jpg','2019-11-02','努比亚(nubia)My 布拉格 银白 移动联通4G手机 双卡双待【嗨11,下单立减100】金属机身,快速充电!布拉格相机全新体验!');
    INSERT INTO `product`  VALUES('5','华为 麦芒4','2599','2499','products/huawei4.jpg','2019-11-02','华为 麦芒4 晨曦金 全网通版4G手机 双卡双待金属机身 2.5D弧面屏 指纹解锁 光学防抖');
    INSERT INTO `product`  VALUES('6','vivo X5M','1899','1799','products/vivox5m.jpg','2019-11-02','vivo X5M 移动4G手机 双卡双待 香槟金【购机送蓝牙耳机+蓝牙自拍杆】5.0英寸大屏显示·八核双卡双待·Hi-Fi移动KTV');
    INSERT INTO `product`  VALUES('7','Apple iPhone 6 (A1586)','4399','4288','products/iphone6.jpg','2019-11-02','Apple iPhone 6 (A1586) 16GB 金色 移动联通电信4G手机长期省才是真的省!点击购机送费版,月月送话费,月月享优惠,畅享4G网络,就在联通4G!');
    2.新建一个项目
    3.导入jar包
        驱动 dbutils c3p0 jstl beanutils
    4.包结构
        utils工具类:datasourceutils
        导入c3p0配置文件
    5.新建一个首页index.jsp    
        添加一个超链接
    6.点击超链接 发送一个servlet上(FindAllServlet)
    7.FindAllServlet:
        调用service,查询所有的商品 返回值:list
        将list放入request域中,请求转发 prodouct_list.jsp

     案例如下:

      productDao.java

    package com.hjh.dao;
    
    import java.sql.SQLException;
    import java.util.List;
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import com.hjh.domain.Product;
    import com.hjh.utils.DataSourceUtils;
    
    public class ProductDao {
    
        //查询所有商品
        public List<Product> findAll() throws SQLException {
            QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSourse());
            String sql = "select * from product";
            return qr.query(sql, new BeanListHandler<>(Product.class));
        }
    }

      product.java

    package com.hjh.domain;
    
    import java.util.Date;
    
    public class Product {
        private String pid;
        private String pname;
        private double market_price;
        private double shop_price;
        private String pimage;
        private Date pdate;
        private String pdesc;
        
        public Product() {}
        public Product(String pid, String pname, double market_price, double shop_price, String pimage, Date pdate,
                String pdesc) {
            this.pid = pid;
            this.pname = pname;
            this.market_price = market_price;
            this.shop_price = shop_price;
            this.pimage = pimage;
            this.pdate = pdate;
            this.pdesc = pdesc;
        }
        
        public String getPid() {
            return pid;
        }
        public void setPid(String pid) {
            this.pid = pid;
        }
        public String getPname() {
            return pname;
        }
        public void setPname(String pname) {
            this.pname = pname;
        }
        public double getMarket_price() {
            return market_price;
        }
        public void setMarket_price(double market_price) {
            this.market_price = market_price;
        }
        public double getShop_price() {
            return shop_price;
        }
        public void setShop_price(double shop_price) {
            this.shop_price = shop_price;
        }
        public String getPimage() {
            return pimage;
        }
        public void setPimage(String pimage) {
            this.pimage = pimage;
        }
        public Date getPdate() {
            return pdate;
        }
        public void setPdate(Date pdate) {
            this.pdate = pdate;
        }
        public String getPdesc() {
            return pdesc;
        }
        public void setPdesc(String pdesc) {
            this.pdesc = pdesc;
        }    
    }

      productService.java

    package com.hjh.service;
    
    import java.sql.SQLException;
    import java.util.List;
    import com.hjh.dao.ProductDao;
    import com.hjh.domain.Product;
    
    public class ProductService {
        //查询所有商品
        public List<Product> findAll() throws SQLException {
            return new ProductDao().findAll();
        }
    }

      FindAllServlet.java

    package com.hjh.servlet;
    
    import java.io.IOException;
    import java.sql.SQLException;
    import java.util.List;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import com.hjh.domain.Product;
    import com.hjh.service.ProductService;
    
    //展示所有的商品
    public class FindAllServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //调用service,查询所有的商品,返回list
            List<Product> plist =null;
            try {
                plist = new ProductService().findAll();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            
            //将list放入request域中
            request.setAttribute("list",plist );
            
            //请求转发
            request.getRequestDispatcher("/product_list.jsp").forward(request,response);    
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

      DataSourceUtils.java

    package com.hjh.utils;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import javax.sql.DataSource;
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    
    public class DataSourceUtils {
        //建立连接池ds
        private static ComboPooledDataSource ds =     new ComboPooledDataSource();
        //将connection绑定在当前线程中
        private static ThreadLocal<Connection> tl = new ThreadLocal<>();
        
        //获取数据源
        public static DataSource getDataSourse() {
            return ds;
        }
        
        //获取连接,从当前线程中获取
        public static Connection getConnection() throws Exception {
            Connection conn = tl.get();
            if(conn==null) {
                //第一次获取,创建一个连接和当前线程绑定在一起
                conn =ds.getConnection();
                //绑定
                tl.set(conn);
            }
            return conn;
        }
        
        //获取连接,开启事务
        public static void startTransaction() throws Exception {
            getConnection().setAutoCommit(false);
        }
        
        //事务提交|解除绑定
        public static void commitAndClose() {
            try {
                Connection conn = getConnection();
                //提交事务
                conn.commit();
                //解除绑定
                tl.remove();    
                //释放资源
                closeConnection(conn);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        //事务回滚
            public static void rollbackAndClose() {
                try {
                    Connection conn = getConnection();
                    //提交事务
                    conn.rollback();
                    //释放资源
                    closeConnection(conn);
                    //解除绑定
                    tl.remove();    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }    
        
        
        
        //释放资源connection
        public static void closeConnection(Connection conn) {
            try {
                if(conn!=null) {
                    conn.close();
                    //并和当前线程解绑
                    tl.remove();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            conn = null;
        }
        //释放资源Statement
            public static void closeStatement(Statement st) {
                try {
                    if(st!=null) {
                        st.close();
                    }else {
                        st = null;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }    
            /**释放资源closePreparedStatement*/
            public static void closePreparedStatement(PreparedStatement ps) {
                try {
                    if(ps!=null) {
                        ps.close();
                    }else {
                        ps = null;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }        
        //释放资源Connection ,Statement 
        public static void close2Resourse(Connection conn,Statement st) {
            closeStatement(st);
            closeConnection(conn);
        }
        /**释放资源closeResourse(conn,ps)*/
        public static void close2Resourse(Connection conn,PreparedStatement ps) {
            closePreparedStatement(ps);
            closeConnection(conn);
        }
        /**释放资源closeResourse(rs)*/
        public static void closeResourse(ResultSet rs) {
            try {
                if(rs!=null) {
                    rs.close();
                }else {
                    rs = null;
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }    
    }

      c3p0-config.xml

    <c3p0-config>
        <!-- 默认配置,如果没有指定则使用这个配置 -->
        <default-config>
            <!-- 基本配置 -->
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost/hjh?characterEncoding=UTF-8 </property>
            <property name="user">root</property>
            <property name="password">root</property>
        
            <!--扩展配置-->
            <property name="checkoutTimeout">30000</property>
            <property name="idleConnectionTestPeriod">30</property>
            <property name="initialPoolSize">10</property>
            <property name="maxIdleTime">30</property>
            <property name="maxPoolSize">100</property>
            <property name="minPoolSize">10</property>
            <property name="maxStatements">200</property>
        </default-config> 
        
        
        <!-- 命名的配置 -->
        <named-config name="XXX">
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/xxxx</property>
            <property name="user">root</property>
            <property name="password">1234</property>
            
            
            <!-- 如果池中数据连接不够时一次增长多少个 -->
            <property name="acquireIncrement">5</property>
            <property name="initialPoolSize">20</property>
            <property name="minPoolSize">10</property>
            <property name="maxPoolSize">40</property>
            <property name="maxStatements">20</property>
            <property name="maxStatementsPerConnection">5</property>
        </named-config>
    </c3p0-config> 

      web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
      <servlet>
        <servlet-name>FindAllServlet</servlet-name>
        <servlet-class>com.hjh.servlet.FindAllServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>FindAllServlet</servlet-name>
        <url-pattern>/findAll</url-pattern>
      </servlet-mapping>
    </web-app>

      index.jsp

    <%@ page language="java" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>展示所有商品</title>
    </head>
    <body>
        <h2><a href="${pageContext.request.contextPath }/findAll">展示所有商品</a></h2>
    </body>
    </html>

      product_list.jsp

    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>商品展示</title>
    </head>
    <body>
        <table border="1" align="center" width="88%">
            <tr>
                <th>pid</th>
                <th>商品图片</th>
                <th>商品名称</th>
                <th>市场价</th>
                <th>商城价</th>
                <th>日期</th>
                <th>商品描述</th>
            </tr>
            <c:forEach items="${list}" var="plist">
                <tr>
                    <td width="8%">${plist.pid}</td>
                    <td width="8%">
                        <img alt="手机" src="${pageContext.request.contextPath }/${plist.pimage}" width="80%">
                    </td>
                    <td width="8%">${plist.pname}</td>
                    <td width="8%">${plist.market_price}</td>
                    <td width="8%">${plist.shop_price}</td>
                    <td width="8%">${plist.pdate}</td>
                    <td>${plist.pdesc}</td>
                    <td width="8%">修改|删除</td>
                </tr>
            </c:forEach>
        </table>
    </body>
    </html>

       数据库数据显示如下:

     

      点击展示所有商品的超链接,页面显示如下:

      在调试代码时,主要遇到3个异常:

        ①异常信息如下。这是因为在导jar的时候,少导了一个jar包:mysql-connector-java-5.1.47.jar;导入jar之后buildpath一下,问题就解决了

      ②这个异常问题出现在<c:forEach>标签的items中,没有用EL表达式,直接上了一个list字符串,正确写法应该是items="${list}",用于取request中放置的list集合。

       ③商品的图片没有展示出来。查找原因,发现这是因为在初始化数据库的时候,给pimage定义的是a路径,项目中实际路径是b路径,2个路径不一致导致图片加载出错

    案例2-添加商品
    需求:
        在index.jsp添加一个超链接,跳转到一个页面,用来填写商品信息,点击保存按钮,将商品保存到数据库中
    步骤分析:
        1.在index.jsp添加一个超链接 
            跳转到add.jsp
        2.add.jsp放入一个表单
        3.表单提交到 AddProductServlet
            封装数据
            调用service完成保存操作
            跳转到FindAllServlet
            (请求转发和重定向)
    有表单使用的时候若使用请求转发会出现重复提交
        方案1:重定向
        方案2:令牌机制
        扩展:令牌机制
            在添加页面上随机生成一个字符串,
                放入session中一份,放入表单中一份
                提交的时候在后台获取两个码
                然后移除session中码(只使用一次)
                然后判断两个码是否一致,
                若不一致就是重复提交了

    案例3-修改商品信息:

    需求:
        在product-list.jsp每一个商品后面都有修改操作.点击修改操作,到了一个edit.jsp(将原来的数据展示出来),最后保存就可以了
    步骤分析
        先查询后修改
        查询步骤分析:
            点击修改连接的时候
                <a href="/day14/getProductById?pid=sss">修改</a>
            getProductById
                获取pid
                通过pid获取到商品 返回值product
                将product放入request域中 请求转发到edit.jsp
        //////////////
        修改步骤分析:
            edit.jsp已经将商品的所有信息展示出来
                需要将商品的id通过隐藏域放入表单中
                点击保存,跳转到editProductServlet
            editProductServlet:
                1.封装数据
                2.调用servcie完成修改更新操作
                3.页面跳转到 FindAllServlet(重定向)

    案例4-删除商品

    需求:
        在列表页面上,点击一个商品的删除操作,弹出一个提示,点击确定的时候,商品当前商品
    步骤分析:
        先给删除添加事件
            单击事件 弹出提示
                confirm()
            点击确定再去删除商品
                location.href="/day14/deleteProductById?pid=xxx" 相当于超链接
        deleteProductById
            1.获取商品id
            2.调用service完成删除操作
            3.页面重定向 FindAllServlet

    扩展:删除多个商品:

    需求:
        在每个商品前面添加复选框,勾选需要删除的商品,添加一个按钮(删除选中),点击之后删除选中的商品
    步骤分析:
        给每一个商品添加复选框(全选全不选),同时添加name属性 值为"pid",value为当前商品的pid
        点击删除选中,需要将勾选上的商品的id提交到后台
            request.getParameterValues("pid")
            必须把所有的商品的放入一个表单中,
                需要在按钮添加事件 
                    需要先获取表单,
                    调用表单的submit()
        
        delCheckedServlet
            1.获取所有要删除的商品的id      String[] ids
            2.调用servcie完成操作
            3.页面重定向 FindAllServlet

    扩展:案例5-多条件查询

    需求:
        在product_list.jsp页面上添加一个表单,输入商品名称 和 关键词,点击确定,将符合条件的商品展示在当前页面上
    步骤分析:
        在product_list.jsp页面上添加一个表单,添加一个查询按钮
        提交的路径 findProductByCondition
            1.获取两个条件
            2.调用service完成查询 返回值:list
            3.将list放入request域中,请求转发
        productDao
            基本sql:select * from product where 1=1
            若商品名称不为空 and pname like ...
            若商品名不为空 and pdesc like ...

    案例6-分页展示商品

    需求:
        将商品进行分页展示
    技术分析:
        分页
    ///////////////////////////
    分页:
        将数据按照页码划分,提高用户的体验度.
    分类:
        物理分页:(开发中经常使用)
            一次只去数据库中查询当前页需要的数据.
        逻辑分页:
            一次性将所有数据查询出来,放入内存(集合),每次查询只需要去内存中截取
    mysql中分页:
        limit 
        格式1:
            select ....  limit m,n;
            从索引为m条开始向后查找n条数据
            就是从第m+1条 到 第m+n条  []
        格式2:
            select .... limit n;
            等价于:select .... limit 0,n;
            
        每页显示3条数据 
            第一页         limit 0,3
            第二页         limit 3,3
            第三页         limit 6,3
            第n页         limit (n-1)*3,3
        
        扩展:
            oracle中 rownum
            sqlserver中 top
        每一页需要的数据有
            当前页内容    limit查询 
            当前页码    从前台传递过去
            每页显示的条数 固定
            总条数        count(*)
            总页数        总条数/每页显示的条数 Math.ceil(double)
        以后开发中一般会将这5个参数封装一个javabean(PageBean)
            private List<T> list;//当前页内容         查询
            private int currPage;//当前页码          传递
            private int pageSize;//每页显示的条数    固定
            private int totalCount;//总条数            查询
            private int totalPage;//总页数            计算
    步骤分析:
        最终结果:
            [首页][上一页][下一页][尾页]
            [首页][上一页]x x x[下一页][尾页]
            
        1.创建一个页面 product_page.jsp
            有上面的内容
            还需要有当前页的数据
        2.在首页上有一个超链接,点击超链接将第一页查询出来
            <a href="/day14/showProductsByPage?currPage=1">分页展示商品</a>
        3.showProductsByPage
            获取第几页
            调用service 完成查询操作,返回值:pagebean
            将pagebean放入request域中,请求转发product_page.jsp
            
        4.service.showProductsByPage
            返回值pagebean
            查询当前页的数据
            查询出总条数
        ////////////////////////////////////
        在页面上展示
            1.展示当前也数据 
                通过<c:forEach items="${pb.list}">
            2.添加首页 上一页 ....的超链接
            3.判断是否是第一页.若是第一页 不展示首页和上一页
            4.判断是否是最后一页 若是最后一页 不展示尾页和下一页
            5.展示所有页码
                <c:forEach begin='1' end="${pb.totalPage}">
            6.判断是否是当前页
                若是当前页 不加超链接
                若不是当前页 添加超链接
                
        扩展:页面多的时候 采用前五后四的方式
            只需要控制begin和end
            begin 判断当前页-5>0?当前页-5:1
            end 判断 当前页+4>总页数?总页数:当前页+4
  • 相关阅读:
    P2184 贪婪大陆
    codeforces-1348-D Phoenix and Science
    联系我
    留言板
    友链
    java集合ArrayList按指定字段排序
    linux下设置oracle开机自启动
    微信公众号开发参考教程
    java生成快递单并调用打印机打印
    java生成128A条形码
  • 原文地址:https://www.cnblogs.com/hejh/p/11118688.html
Copyright © 2020-2023  润新知