A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

同学们,今天我们做了一个商品CRUD小项目,对之前讲过的内容做了回顾。

今日需要掌握的有:
  • 商品CRUD操作
  • 会添加事务
  • 掌握分页(重要)

请同学们按照如上要求,总结今日所学。



36 个回复

倒序浏览
李志勇:
分页:
jsp->Servlet  传参currPage当前页数
Servlet->jsp  传参currPage当前页数 总记录数 总页数 每页记录数   数据list集合  存入域中  
然后通过一系列判断就能实现
<c:forEach var="i" items="${page.list }" varStatus="stutas">
<tr>
<td>${stutas.count }</td>
<td><input type="checkbox" name="ids"></td>
<td>${i.pname }</td>
<td>${i.market_price }</td>
<td>${i.shop_price }</td>
<td><c:if test="${i.is_hot==1 }">是</c:if><c:if test="${i.is_hot==0 }">否</c:if></td>
<td>${i.pdesc }</td>
<td><c:if test="${i.pflag==1 }">未下架</c:if><c:if test="${i.pflag==0 }">已下架</c:if></td>
<td><a href="${pageContext.request.contextPath }/ProductUpdateServlet?id=${i.pid}">修改</a><a

href="#">删除</a></td>
</tr>
</c:forEach>
<tr>
<td colspan="9"align="center">第${page.currPage }/${page.totalPage }页 &nbsp;&nbsp;共有

${page.totalCount }记录&nbsp;&nbsp;
<c:if test="${page.currPage!=1 }">
<a href="${pageContext.request.contextPath }/ProductPageServlet?currPage=1">[首页]</a>
<a href="${pageContext.request.contextPath }/ProductPageServlet?currPage=${page.currPage-1}">[前一

页]</a>
</c:if>
<c:forEach var="i" begin="1" end="${page.totalPage}">
<c:if test="${i==page.currPage }">${i }</c:if>
<c:if test="${i!=page.currPage }"><a href="${pageContext.request.contextPath }/ProductPageServlet?

currPage=${i }">${i }</a></c:if>
</c:forEach>
<c:if test="${page.currPage!=page.totalPage }">
<a href="${pageContext.request.contextPath }/ProductPageServlet?currPage=${page.currPage+1}">[下一

页]</a>
<a href="${pageContext.request.contextPath }/ProductPageServlet?currPage=${page.totalPage}">[尾页]

</a>
</c:if>
</td>
</tr>
回复 使用道具 举报
吴利君
今天学习了页面的增删改查,这些操作都很简单,其中在批量删除的时候要注意事务的管理,使用DBUtils是使用向下传递的方式,而还有一种是线程的方式。然后是在查询的地方可以使用模糊查询,使用like关键字。
然后是分页,这个比较难,在数据量小的时候可以使用逻辑分页,使用一个集合接收数据库传来的所有数据,然后在根据前端传来的当前页,然后来遍历查找自己想要的条数,以及对应的页数的数据,如果数据量大的话,可以使用物理分页,就是在数据库里面进行查询对应的页数的数据,这个需要些相应的数据库语句limit,注意,这个关键字是添加在最后的,而且limit的第一个数据是索引开始,第二个数据是索引的条数。当然,如果是只有一个?的话,那就只是索引条数的数据了!不过我建议使用物理分页,比较简单,代码少。
然后今天的很多js代码,可以使用HBuider来写,然后复制粘贴到jsp中,毕竟HBuider有提示,出错的几率小。
回复 使用道具 举报
2018/6/11        林瑋

今天学的知识点比较少,但是相对也比较重要,逻辑性比较强.就是一个对商品页面的增删改查,其实今天的前半部分算是在复习了因为之前在登入注册就已经学习过増和查了,所以前半部分学习的比较轻松,就是后面的Service到Dao的四个业务调的有点绕.对于增删改查这一块还有一个地方需要注意一下的就是重复提交问题,重复提交就是你刷新该页面它仍会提交,如果是添加的话你一直点刷新他就会一直添加,这样的话就很头疼了,而想要根本的解决这个问题就要用到令牌机制了,它可以生成随机令牌放入表单的隐藏字段中,然后在Servlet中判断session中和表单中一直的令牌,如果一致就添加不一致跳转页面,这样就可以完美的避免重复提交的问题发生了.           另一个就是分页了,分页顾名思义就是我们平时看小说,漫画的时候下面都有的那个分页.而今天要学的就是这个分页,我们要用我们的这个技术把一个商品表给它分页了。分页又分成两种,一种是逻辑分页,一种是物理分页,我今天主要就学习物理分页,逻辑分页就当了解一下就好了。那什么是物理分页呢,什么又是逻辑分页?物理分页就是将一个页面里的数据,分为多页(推荐使用)。逻辑分页呢就是把所有数据都放在一个页面里,不加以页。
        |----------------------        |       
        |1              |   商品一                |        他是使用SQL语句进行控制的分页.
        |2              |   商品二                |        缺点:经常需要和数据可交互.
        |3              |   商品三                |        优点:放置在大的数据量也不会导致内存
        |4              |   商品四                |        溢出.
        |5              |   商品五                |
        |----------------------        |
        [首页][上页][下页][尾页]----------   :这就是物理分页基本格式.
        由于逻辑分页不是重点我就直接略过了哈....
回复 使用道具 举报
常小天
今天的主要内容就是一个商品信息操作的案例。使用的基本都是之前学习过的内容,没有新添加什么知识点,所以今天的总结就只是对这个案例的思路的整理。
本案例需要使用的jar包有mysql驱动包1个、C3P0的包1个、DBUtils的包1个、BeanUtils的包2个、JSTL的包2个。在准备好数据库和表记录后需要一个首页的jsp。还要准备一个product的类。下面根据不同功能来总结一下他们的思路。
查询所以商品。点击首页的连接,发送请求到servlet,在servlet中直接调用service的方法,在调用DAO的方法执行查询的SQL语句,将结果封装成List返回,元素为一个个product。在servlet中将List存进request域中,转发到商品显示的jsp页面,在这个页面中将List从域中取出,遍历并将信息存进列表。
添加商品信息。点击添加按钮,跳转到添加信息的jsp页面,填写完信息后点击提交将信息提交至servlet,在servlet中调用业务层在调用DAO执行SQL语句向数据库中添加一条记录。添加成功后跳转至查询所有商品的servlet,由这个servlet在跳转至商品显示的jsp页面。这里需要处理一个重复提交的问题。方法是使用令牌。在商品信息填写完成后会生成一个id存入商品的隐藏字段中,同时将该id存入session。信息提交至servlet后,servlet分别从session和传入的参数中获得这个id进行比对,比对一致则执行添加操作,不一致则跳转至其他页面不执行添加操作。在获得session中的id并完成赋值后就清除session中的id,这样,当重复提交的时候,表单传入的参数中的id就与servlet从session中获得的id不同,从而避免重复提交。
商品信息的修改。点击修改按钮,提交商品id至servlet,servlet根据id调用业务层调用DAO在数据库中查询到这条信息并返回。Servlet将信息存进域中跳转至修改信息页面,jsp从域中取出信息并填写进表格。信息修改完成后,点击提交,表单信息(包括id)提交至servlet,servlet根据id将信息覆盖到指定id的记录中。
商品信息的删除。点击商品信息栏内的删除按钮,将本条商品id发送至servlet,servlet根据id删除数据库中的该条记录。在商品信息栏中增加一个复选框,并实现全选功能。添加一个删除按钮用于批量删除商品信息。提交信息至servlet,servlet获取包含复选框信息的相应数组。遍历数组并删除每一条信息。
商品的模糊查询。在商品列表页面的文本框内输入信息并点击查询,提交表单信息至servlet,servlet获取文本框的信息后,作为参数传递给DAO方法,使用SQL中的like关键字进行模糊查询,将查询的记录封装进集合并返回。Servlet将集合存进域中并跳转至商品列表页面,jsp获得域中的集合并遍历,将信息填进表格即可。
商品的分页查询。通过limit关键字实现部分查询。Limit后面需要两个参数,第一个是查询开始的地方,即从那一条开始查询,只是索引从0开始这一点需要注意。第二个参数是单次查询的信息数目,即向后查询多少条。前台页面将要跳转的页面页数提交给后台,后台获得页数,并且从数据库查询得到信息总数,设定好每一页显示的信息条数,也就是单次查询的信息数目,借助向上取整函数算出总页数,“要跳转的页数-1*单次查询信息数目”获得limit的第一个参数,然后执行SQL进行查询,将查询结果存进集合并返回。可在业务层将这些信息封装进一个pageBean对象再返回,servlet将pageBean对象存进域中并跳转至商品列表页面,jsp从域中获得pageBean对象并在页面中显示。
回复 使用道具 举报
柯威龙
今天主要学习了对增删改查的操作以及分页.增删改查主要是巩固了之前所学的知识点主要是用MVC
的模式来完成操作.然后今天主要是用js写代码的比较多.然后跳来跳去的比较麻烦.分页的话主要是分为
两种,一种是逻辑分页,一种是物理分页,使用物理分页主要是使用SQL语句来进行查询.在使用的时候有一个关键字
之前没学习过的就是limit.然后传两个参数.逻辑分页的话主要是使用集合来进行接收.但是逻辑分营养液缺点是
容易造成内存溢出,因为是一次性读完.优点是与数据库交互较少.物理分页反之.但是现在主要大部分还是使用物理分页
回复 使用道具 举报
张育辉
案例总结:
        今天学习了,把之前的东西全部结合起来,对表格进行增删改查;
        第一难点 如何避免重复提交的问题:
                问题分析:添加完商品之后,转发到一个页面,刷新该页面.网速很慢,点击提交的按钮,其实已经在提交了但是网速慢,不停的点击提交.
                 解决一:可以用重定向来解决重复提交问题,但是后退,缓存再提交问题还是会出现.       
                 解决二;解决重复提交的根本解决办法:令牌机制(一次性).
                        生成随机的令牌保存在session中.可以调用UUID.randomUUID().toString().replace("-", "");生成一个随机的字符串
                        在表单的提交的时候,将随机的令牌放入到表单的隐藏字段中.
                        在Servlet中获得session中和表单中的令牌是否一致.
                        如果一致执行插入操作,不一致跳转到其他页面.将令牌销毁.
       
   涉及新技术:就是分页查询:
                        分为两种: 1,物理分页:一次只查10条记录,点击下一页,再去查询后10条.使用SQL语句进行控制的分页
                                                                        缺点:经常需要和数据库交互.
                                                                        优点:数据量特别大,不会导致内存的溢出.

                                          2,逻辑分页:一次性将所有数据全都查询出来,根据需要进行截取.List集合进行控制. subList();
                                                                缺点:数据量如果特别大,容易导致内存溢出.
                                                                优点:与数据库交互次数少.
                        一般都是使用物理分页;使用limit关键字,写在语句最后,也就是排在排序后面;
                                                                                格式: limit a,b  a=从哪里开始查(索引为0) b=一次查询几条数据
                                                                               

        封装分页数据的
                        参数的传递:
        前台--->后台:只需要传一个页面的属性值
        后台--->前台:当前页,totalPage(总页数),totalCount(总记录数),每页记录数,根据条件查询到的数据list集合
                考虑到每次都要用域来存数据,比较麻烦,所有把数据封装成一个对象来传递数据,再把对象存入域中;       
                                                        JavaBean:一般都需要5个参数;
                                                        private int currPage; // 当前页数.
                                                        private int totalCount; // 总记录数.
                                                        private int totalPage; // 总页数.
                                                        private int pageSize;// 每页记录数.
                                                        private List<Product> list; // 每页的数据的集合
                把数据全部在业务层完成设置,再进行返回;
                                难点:
                                // 设置总页数:
                                /*int totalPage = 0;
                                if(totalCount % pageSize == 0){
                                        totalPage = totalCount / pageSize;
                                }else{
                                        totalPage = totalCount / pageSize + 1;
                                }*/
                                double tc = totalCount; 把int类型转换成double类型
                                Double num = Math.ceil(tc/pageSize); 调用数学工具类(总数据/一次查询几条页数的)3.1 =4;
                                pageBean.setTotalPage(num.intValue());
回复 使用道具 举报
陈昆明:
38.使用令牌机制后,记得把session中的令牌清除
39.同一表单要想提交到不同的路径下,需要使用js语句,将其中一个路径的action属性进行更改
40.使用QueryRunner进行模糊查询,需要将%和?一起包含后在参数中进行改写
41.分页查询技术:(将后台需要传到前台的参数在业务层进行包装到一个类中,然后将对象传到前台再获取)
        Mysql关键字:limit  --->select * from 表名 limit a,b  --->a代表从哪儿开始,b代表记录数
        Oracle使用SQL语句进行嵌套
        SQL Server使用top关键字
回复 使用道具 举报
一梦 中级黑马 2018-6-12 00:17:01
9#
陈世彪:
再使用product.setPid(UUIDUtils.getUUID());
UUID.randomUUID().toString().replace("-", "")
是获得一个随机的id,使用replace将里面的"-"替换成空字符
将商品列表保存到request域中:
转发到商品列表页面:
解决重复提交的根本解决办法:令牌机制(一次性).
生成随机的令牌保存在session中.
在表单的提交的时候,将随机的令牌放入到表单的隐藏字段中.
在Servlet中获得session中和表单中的令牌是否一致.
如果一致执行插入操作,不一致跳转到其他页面.将令牌销毁.
在查询操作中,使用like模糊查询时
要在给?传参时使用"${}"这样子才不会出错
在进行删除操作时,要使用事务管理
要么同时删除,要么都不删除
setAutoCommit(boolean flag);关闭自动提交
commit();提交
rollback();事务回滚
分页
分页有两种
物理分页:一次只查10条记录,点击下一页,再去查询后10条.使用SQL语句进行控制的分页.
缺点:经常需要和数据库交互.
优点:数据量特别大,不会导致内存的溢出.
逻辑分页:一次性将所有数据全都查询出来,根据需要进行截取.List集合进行控制. subList();
缺点:数据量如果特别大,容易导致内存溢出.
优点:与数据库交互次数少.
现在主页使用物理分页
使用关键字limit
select * from xxx where .. Group by ... Having ... Order by ... limit a,b; -- a:从哪开始  b:查询的记录数.
回复 使用道具 举报
陈叶隆
1. CRUD步骤:
a.接收参数
b.封装数据
c.调用业务层
d.页面跳转

*重复提交的问题:
    i)添加完商品之后,转发到一个页面,刷新该页面.
    ii)网速很慢,点击提交的按钮,其实已经在提交了但是网速慢,不停的点击提交.
解决重复提交的根本解决办法:令牌机制(一次性).
// 判断是否是重复提交:
        String token1 = (String)request.getSession().getAttribute("token");
                        String token2 = request.getParameter("token");
                        // 清空session中的令牌:
                        request.getSession().removeAttribute("token");
                        if(!token2.equals(token1)){
                        request.setAttribute("msg", "亲!您已经提交过!请不要重复提交了!");
request.getRequestDispatcher("/jsp/msg.jsp").forward(request, response);
                                return;                        }

2. 商品分页显示:
* MYSQL进行分页: 使用limit关键字.
    select * from xxx where .. Group by ... Having ... Order by ... limit a,b;
        begin = (currPage - 1) * pageSize;
* 参数的传递:
     前台--->后台:currPage
         后台--->前台:currPage,totalPage(总页数),totalCount(总记录数),pageSize,List集合.
        *使用ScalarHandler封装单值结果.
回复 使用道具 举报
今天主要学习
1.(商品数据的CRUD操作)从数据库中读取数据,对数据在页面中对数据进行增删改查,还有数据超过10条,
2.进行自动分页显示,
{ 序号的stau 自动生成第一列的序号}
{ colspan 合并单元格}
UUID的产生随机的字符串





步骤分析
1.创建数据库表
2.创建工程导jar包(7个包)
  mysql驱动
  c3p0的bao
  dbitil包
  jst的两个包
  beanutil  2个包
3、创建包结构
4.创建一个首页



从数据库进行获取数据显示到浏览器中(思路)
(jsp设置一个链接(进入商品列表),访问Servlet,Servlet就进行数据的库的读取,放在request域中(设置list集合),在jsp文件中对list进行遍历,)



注意事项;
重复提交的问题
1、转发添加完商品 刷新页面(重复执行添加操作) 1.可以换成重定向页面/
2、网速慢的,重复点击提交,(会出现重复提交)

根本的解决办法;(令牌机制,一次性)
机制原理;
1.生成随机的令牌sessiom
2.通过UUID随机产生一个字符串(作为暗号)(在jsp中商品页设置一个隐藏token  然后Session域中也设置一个token)
3.然后进行核对暗号



修改的页面的一行数据
(2部分,1.通过前台,查找到后台的id   2.通过id通过update进行修改)



分页:
1.逻辑分页;一次把所有的数据查出来   优点:与数据库交互少     缺点:会出现内存溢出
2.物理分页;一次查询一部分      优点:不会出现内存溢出    缺点:经常与数据库交互
前台-->后台;传一个页数。
后台-->前台 :1.当前页 2.总页数3.数据总数4.list集合  (将这些数据封装到javaBean)


select * from product limit  a,b;
limit a,b   (a表示从第几条开始  b表示查询几条)
limit 0,10   (1-10的数据)
回复 使用道具 举报
本帖最后由 AsusCoder 于 2018-6-15 00:41 编辑

曾耀峰


通过这几天学习MVC形式开发web功能,有一个原则可以确定,就是必须先处理后台数据,然后获取处理完的后台数据,到前端显示
后台的数据结果。
      今天案例出现频率很高的一个获取当前工程路径的代码:${pageContext.request.contextPath}指向了当前的工程路径
名称。比如:localhost:8080/day0610
这个形式的路径避免把绝对路径写死,便于后面的项目迁移。
比如,运用在前端的jQuery引入项目路径,可以写:
<script src='${pageContext.request.contextPath}/js/jquery1.8.3.js'>
</script>
这样子做的话,当以后前端部分的代码要迁移时,在正确迁移的情况下不必修改路径

一.分页查询——物理分页思路:
1.首先点击首页的"分页查询"链接,访问到DividePageServlet,get方式上传当前首页currPage=0的参数。
2.创建一个PageBean 里面的成员属性有:
1)currPage:当前页面
2)pageSize:每页显示多少条记录
3)totalRecordNum:总记录数
4)totalPage:总页数
5)List<Product>:商品数据集合

3.接下来DividePageServlet的工作就是填充PageBean里面的属性。
1)新建一个PageBean对象。
2)由于分页查询的sql语句是使用关键字limit:select * from product limit [begin],[size];
begin:表示从哪一条查起
size:应该查多少条
3)可以算出:
begin = (currPage-1)*10:第1页 从0条开始;第2页从 从10条开始;第3页,从20条开始...
size = PageSize 可以写死final 10条;
4)上面的两个参数算完以后,  
(1)获取总记录数totalRecordNum:
调用int count = PageService.getCount();
PageService调用PageDao.getCount();
使用sql语句select count(*) from product;
要使用new ScalarBeanHandler结果集,返回单一查询结果

(2)获取List<Product>集合:
调用List<Product> list = PageService.findAll(begin,size);
PageService调用PageDao.findAll(begin,size);
PageDao创建List<Product> findAll(begin,size)方法
方法里使用查询所有的sql语句,使用new BeanListHandler结果集,返回一个List<Product> list;

5)获取总页数totalPage
Math.ceil(totalRecordNum/size);
注意整形转换成Double型,再转回int型

6)至此,已经获取PageBean对象的所有属性。存放到request对象中,然后转发到商品分页页面product_divide.jsp页面


7)前端jsp展示分页的数据效果:
前面步骤已经存储了pageBean在session。接下来在dividePage_list.jsp中获取pageBean就能做了
jsp前端代码:
<p>
分页条: <a href='/day0610/DividePageServelt?currPage=1'>【首页】</a>
<c:if test="${pageBean.currPage!=1}">
  <a href='/day0610/DividePageServelt?currPage=${pageBean.currPage-1}'>[上一页]</a>
</c:if>
<c:forEach begin="1" end="${pageBean.totalPageNum}" var="status">
  <a href='/day0610/DividePageServelt?currPage=${status}'>[${status}]</a>
</c:forEach>
  <c:if test="${pageBean.currPage!=pageBean.totalPageNum}">
     <a href='/day0610/DividePageServelt?currPage=${pageBean.currPage+1}'>[下一页]</a>
  </c:if>
         <a href='/day0610/DividePageServelt?currPage=${pageBean.totalPageNum}'>【尾页】</a>
         ${pageBean.currPage}/${pageBean.totalPageNum}页&nbsp;共${pageBean.totalRecordNum}条记录
</p>

二、商品的添加改查功能:
1.添加商品:
1).新建一个处理添加商品的Servlet:AddProductServlet,新建一个商品添加页面addProduct.jsp。里面加一个商品添加商品种类的表单.
2).表单提交到AddProductServlet后,使用request.getParamterMap()得到一个含有所有参数的map集合
3).这里使用BeanUtils直接封装表单Product对象:BeanUtils.populate(product,map);
4).给封装后的Product对象设置一个32位随机字符串的pid属性,使用Java自带UUIDUtils.因为初始生成含有'-'号,使用replace()方法将"-"替代为"";
5).将对象传入Service->dao:使用update进行更新操作。由于对象有10个属性。可以建立一个参数数组Object[] params存储对象的成员值
6).关于重复提交的本质原因是没有对当前页面进行刷新。这里使用令牌(token)的形式对没有刷新页面的提交进行处理。原理和验证码一次性使用一样
在客户端jsp代码中获得一个UUID形式的token。分别存放在客户端的request请求域对象中,和服务端的session中。当有刷新提交访问到服务端,从服务端获取到这个
token。然后移除该session。只要有访问服务端,request域对象的token和session的token是一样的。当第二次再重复提交。第一次的Session中的token被
移除了。拿到的是null的session。

2.模糊查询查找商品:
查寻含有关键字的商品名称,在sql操作中,使用like "%a%"模糊查询来查
1)post方式提交pname到处理模糊查询的FindLikeServlet中。先进行中文编码的处理
2)新建一个ProductBean对象。
3)调用ProductService中的List<Product> list=findLike(pname)功能,Dao也创建该方法
4)在Dao的findLike(pname)中,sql语句是"select * from product order by pdate where pname like ?",
后面的参数是"%"+pname+"%"。返回的结果是BeanList;
5)把DAO返回的List<Product> list传递到Servlet中,赋值给productBean.list;
6)productBean存放到session.覆盖原来的seesion
7)
---------mark一下 明天再补全-----------------
3.删除商品
1)对于每一项记录建立一个删除链接,链接指向处理删除功能的Servlet:delRecServlet:<a href="${}">

4.修改商品:
思路:
1)点击每项的修改链接时候,使用get的方式上传该对象到servlet中。
问题来了?如何获取一个对象?上传后接收的只能是数组



----------------完善------------------
1.添加/删除/修改/删除所选等操作,添加一个msg信号。在js接收msg。
因为是一次性信号,所以使用reuqest域对象存储信号:
添加成功:"msg","msgAddSuccess"
修改成功:"msg","msgUpdateSuccess"
删除成功:"msg","msgDeleteSuccess"
查询失败:"msg","msgLikeFindError"

回复 使用道具 举报
施炎生
今日总结:
一、        获取数据库商品信息:
通过service.findall方法得到数据扔到list集合中,把集合存到request域中,再转发到商品列表jsp中展示出来。
二、        添加商品
(1)通过添加按钮的onclick事件跳转到添加商品的jsp,输入各种商品信息,提交表单跳转到addServlet,获取参数到map集合中,用BeanUtils.populate封装数据,老一套添加完数据,重定向(只能重定向,如果使用转发,因为地址栏没变,当刷新页面时会继续添加)到获取商品信息的Servlet展示出所有商品。
(2)解决重复提交的根本解决办法:令牌机制(一次性).
生成随机的令牌保存在session中.
在表单的提交的时候,将随机的令牌放入到表单的隐藏字段中.
    在Servlet中获得session中和表单中的令牌是否一致.
    如果一致执行插入操作,不一致跳转到其他页面.将令牌销毁.
三、修改商品
<a href="${pageContext.request.contextPath }/QueryServlet?pid=${p.pid}">;如上,在路径最后加上 ?pid=${p.pid}可以把要修改的商品pid传到查询Servlet中获得该商品信息,保存到request域中,再通过EL表达式取出显示到修改界面的JSP中,修改完再提交到相应Servlet中update数据。

代码BUG:
Map<String,String[]>map=request.getParameterMap();写成了Map<String,String[]> map=new HashMap<>();接收参数语句错误导致添加完商品页面显示的是空字符串。
在request域内存值,却使用了重定向,导致跳转后无法取到值。
回复 使用道具 举报
李思贤:今天学习了对商品的增删改查操作和分页:
在写代码前需要创建好数据库和导包(7个包),分别是 :
msysql驱动包,c3p0的包,dbutils的包,beanUtils的包:两个.,JSTL的包:两个

1查询所有功能
创建一个首页,超链接到查询所有商品的Servlet中.....,查询所有数据放在一个list集合中存入request域中,转发在页面列表页面显示(JSTL遍历)

2添加功能
在Productile_list.jsp中在表上加一行:放入查询(submit)添加按钮(跳转到addProduct.jsp),
Button没有跳转功能,要定义一个点击事件,跳入addProduct.jsp中 在建一个表格()填写提交的商品信息)在提交到ProductAddServlet中,
用map接收表单中的数据,还有两个表单中没有的数据要封装进去,
product.setPid(UUIDUtils.getUUID());  //这里注意是Pid!!!!
                        product.setPdate(new Date());
然后插入数据库,转发到ProductFindAllServlet中,不要直接转发到Product_list中,那样list读不到信息,没有商品信息.

添加完我们就要解决重复提交的问题了,运用令牌机制:
解决重复提交的根本解决办法:令牌机制(一次性).
    1在addProduct.jsp中生成随机的令牌保存在session中.
    2也这个令牌放入到表单的隐藏字段中.
    3在Servlet中获得session中和表单中的令牌是否一致.
    4如果一致执行插入操作,不一致跳转到其他页面.将令牌销毁.
代码实现:
                        // 判断是否是重复提交:
                        String token1 = (String)request.getSession().getAttribute("token");
                        String token2 = request.getParameter("token");
                        // 清空session中的令牌:
                        request.getSession().removeAttribute("token");
                        if(!token2.equals(token1)){
                                request.setAttribute("msg", "亲!您已经提交过!请不要重复提交了!");
                                request.getRequestDispatcher("/jsp/msg.jsp").forward(request, response);
                                return;
                        }

3修改商品功能
首先我们在Product_list.jsp中某商品后面的点击修改按键,需要先跳转到一个ProductEditServlet中,要获得该商品所有属性回显到一个editProduct.jsp页面中(和添加页面类似),在这个页面中修改商品信息后再点击提交按钮提交给updateServlet中

在Product_list.jsp想要让Servlet中接收到该商品信息,需要传个id过去
<a href="${ pageContext.request.contextPath }/ProductEditServlet?pid=${ p.pid }">修改</a>
下一步就可以在Servlet中接收参数,...找到该数据传到editProduct.jsp页面(拿addProduct改),
在这个jsp中把刚才拿到的product中的数据用EL表达式写在页面中,最后提交前要注意加一个隐藏标签,放入pid,不然跳转到UpdateServlet中接收不到pid信息啊.
在UpdateServlet中 以map形式接收传来的参数,和添加类似...修改成功转发到ProductFindAllServlet,就完成了.

4删除功能

同样在列表页面点击删除,跳转到Servlet中,调用业务层就行,想要点击出现弹框就要定义一个onclick事件,同时要传pid,因为pid只在循环内部,所以在onclick事件中就要传过去,
<a href="#" onclick="del(${ p.pid })">删除</a>

function del(pid) {
        var flag = window.confirm("你确定删除这条记录吗?");
        if(flag==true){
        window.location.href="${ pageContext.request.contextPath }/jsp/ProdectDeleteServlet?pid="+pid;
                           }
                           }


多条商品一起删除,先在表格上加上CheckBox,这里复习了用JQ的JS完成全选.引入JS文件,(
<script type="text/javascript" src="${ pageContext.request.contextPath }/js/jquery-1.8.3.js"></script>)只要页面一加载,就让上面的复选框绑定一个事件,用JQ一行搞定:
$(function(){
                $("#selectAll").click(function(){
                        $("input[name='ids']").prop("checked",this.checked);
                });
        });




提交之前在CheckBox中 value=${ p.pid }
这里涉及到表单提交,加个form 提交到ProductDeleteAllServlet
接收传来的ids数组,直接调用业务层,
在业务层中开启事物,



Connection conn = JDBCUtils.getConnection();
                try {
                        conn.setAutoCommit(false);
                        ProductDao productDao = new ProductDao();
                        for (String id : ids) {
                                productDao.delete(conn, id);
                        }
                        DbUtils.commitAndClose(conn);
                } catch (Exception e) {
                        try {
                                DbUtils.rollbackAndClose(conn);
                        } catch (SQLException e1) {
                                // TODO Auto-generated catch block
                                e1.printStackTrace();
                        }
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }

这里重写了delete方法,.....就可以实现多条商品信息的删除.

分页见下次吧...
回复 使用道具 举报
汪志阳:
今天主要是商品CRUD操作,在操作中添加事务,以及最后分页操作代码.主要讲讲写代码过程中遇到的bug吧.刚开始将今天的项目另外建一个包在昨天的项目文件夹下面,后面不知道是兼容性问题(考试文件是3.0)还是怎么的
导致创建Servlet创建不会自动在web.html中配置相应的信息,后来只能从新建项目.发现拷贝整个Servlet文件系统不会帮你自动生成配置文件,新药自己在当前项目下建才能自动配置.
增加商品的案例问题:String sql =个数 "insert into product values(?,?,?,?,?,?,?,?,?,?)";这个问号的个数是和数据库的字段一致的,并不是和jsp中显示的页面一致.然后就是令牌机制:
这个机制主要是在表单input中插入随机生成的字符串数字(可以看做表单的属性,并不会随着session的remove改变),和session中保存的作比较,session每次最后都要删除,这样意味着
浏览器中我们返回或者网络延迟,是浏览器保存的数据,并不是我们服务器的再次响应.比较这两个令牌的表单的应该放在前面,否则会出现空指针异常现象.
修改案例:主要是运用商品的id去找到对应的商品,然后根据id设置value,显示保存的数据进行修改,在案例中因为路径的问题爆发出很多小问题.
最后想问下超哥:对像这种代码很多,早上学习的,课堂上没有预留时间及时敲代码的,堆积到了晚上一起来敲代码的,因为间隔太久,整体思路记得但是代码在哪里实现都忘记得差不多了,对于是在想不起来的案例
我们是应该再去看视频理思路(有点费时间),还是看当天的文件里面的代码理解思路,还是先照着代码敲一遍再去理解记忆,有点印象后面再独立敲出来?求解.
回复 使用道具 举报
张裕
6月11日 非常恐怖的一天 今天的代码多到让人头大 找富婆的欲望越发强烈起来

今天主要是回顾了一些以前的知识点 整合在一起做了一大堆大堆堆案例 形容也不知道怎么形容 不懂说什么
要说的话感觉又太多说不完 主要说一些注意点吧 多注意空指针异常和编码乱码就好了
复选框删除要用到事务管理 要嘛全部删成功 要嘛全部失败
添加商品为了防止F5无限添加 可以设置一个令牌? 然而我全是用的重定向 就是皮 不用令牌

新的东西就是商品分页的功能吧
分为了        物理分页(查询频繁 但是不会导致内存溢出)
        逻辑分页(查询一次 但是可能会导致内存溢出) 挺好用的

数据库分页语句
        MySQL: 关键字limit
                select * from xxx ...Limit begin,pageSize;
        Oracle: 使用SQL语句嵌套
        SQL Server: 关键字top

分页查询主要是传当前的页面数到Servlet中
根据页数返回一个JavaBean对象到页面中
        对象中需要有         当前页数(Integer)
                        查询到的数据条数(Integer)
                        页面页数(Integer)
                        每页有几条数据(Integer)
                        查到的数据List<另外的JavaBean>

主要还是要多练 不说了 60岁的女朋友叫我了
回复 使用道具 举报
刘文峰
商品的增删改查:以前就学过的知识,今天算是重新复习了一遍.不过也学了一个新的知识点令牌,用来防止重复提交的问题,使用工具类UUID.randoUUID().tostring()可以得到一个随机字符串,将他放在表单中的一个隐藏字段中,提交表单时可以做后台接收数据判断是否重复,就可以解决重复提交的问题,和验证码的思路差不多.
今天还学了分页:分页分为两种,一个市物理分页:一次从数据库中查询多条记录显示一页,换页时则继续从数据库中查询记录然后显示;另一个是逻辑分页:一次从数据库中查询所有记录,然后分页.
不同数据库对分页的关键字也不同:
Mysql : limit  后面跟两个参数begin,pageSize begin表示从哪条记录开始查询,pageSize表示一次查询的记录的数量.
Oracle: 没有关键字,使用sql语句嵌套
SQL server:   top关键字
使用mysql物理分页:
前台需要向发送要查询的第几页的页数;
后台向前台响应当前所在页数,总页数,总记录数,查询到的记录封装成的集合,可以将这些数据封装成一个javabean(先建一个javabean)响应给jsp. Jsp就可以将分页后的数据显示.
回复 使用道具 举报
16weisong
今天主要学习了商品的CRUD,基本都是以前学习的知识的引用,新学到的一个是令牌机制防止重复提交和分页查询.其中比较难的是分页查询,其实是因为分页查询需要封装的数据比较多,敲起来比较麻烦点,只需把要返回的数据理清楚即可掌握
回复 使用道具 举报
詹源


(重点)
页面刷新重复提交

解决方法:令牌机制..(一次性)
生成随机令牌存在于session中
代码:
String token = UUIDUtils.getUUID();//生成随机字符串
session.setAttribute("token",token);//存到session中.在表单隐藏域中存储了一份,

ID放在隐藏域中

分页功能的实现

物理分页:一次只查10条记录,点击下一页,再去查询后10条.使用SQL语句进行控制的分页
        缺点:经常需要和数据库交互
        优点:当数据量过大,不会导致内存溢出
逻辑分页:一次性将所有数据全部查询出来,根据需要进行截取.List集合进行控制
        缺点:数据量如果过大,容易导致内存溢出;
        优点:与数据库交互次数较少;

不同的数据库对分页的语句也是不一样的;
        MYSQL进行分页:使用limit关键字
                select * from xxx where .. Group by ... Having ... Order by ...Limit a,b;--a:从哪开始.b:查询记录个数
                根据页数计算 limit后面的两个参数
                        currPage  begin   pageSize
                           1            0              10
                           2            10              10
                           3            20               10
                        begin = (currPage-1) * pageSize
                参数的传递:
                        前台---后台:currPage
                        后台---前台:currPage,totalPage(总页数),totalCount(总记录数),pageSize,List集合
                       
                       
        Oracle进行分页:使用SQL语句嵌套;
        SQL Server 数据库进行分页:使用top关键字
pageBean:就是一个背包;
回复 使用道具 举报
郑阳阳
今天学习了商品增删改查,条件查询,分页和批量删除.
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马