1. JavaWeb学习笔记六:利用EL表达式和Servlet技术实现商品分类查找
1.1. web工程修改名字
- 先在工程名字上修改
- 在该web工程下的properties中搜web,选择web project setting ,修改Context root 名字。
1.2. web层三个作用
- 接收前端表单数据,封装到实体
- 传递数据到service业务层
- 接收service层返回的结果,并指定跳转的页面。
1.3. 分类查询学习
- 什么是分类搜索
- 实现该搜索的业务流程
1.4. 代码详细实现
- 首先在jsp页面上建立查询的框
<form id="Form1" name="Form1"
action="${pageContext.request.contextPath}/adminSearchProductList"
method="post">
商品名称:<input type="text" name="pname" value="${condition.pname }">
是否热门:<select id="isHot" name="isHot"><!-- 注意name属性,这个name属性用来供web层获取参数的要与bean中的属性相同。 -->
<option value="">不限</option>
<option value="0">否</option>
<option value="1">是</option>
</select>
商品类别:<select id="cid" name="cid">
<option value="">不限</option>
<c:forEach items="${categoryList }" var="category">
<option value="${category.cid }">${category.cname }</option>
</c:forEach>
</select>
<input type="submit" value="搜索">
-
第一步: 要将action提交路径写好,也就是form表单提交到的web层的servlet.
-
第二步: 要创建一个vo包,这个vo包是用来存储Bean对象的,因为数据库中没有相对应的表,因此不是domain包,相当于自己建立了一个域对象,一个容器。本案例里面包含了pname、cid、isHot。
-
第三步: 实现回显即:在查询完毕后查询的值依然能够出现在查询条件框里。这个方法就是通过EL表达式的方式给value赋值,如pname的赋值${condition.pname}不过这个有一个条件,需要在web层将condition对象放到request域中,这样EL表达式才能起作用,EL表达式只是方便使用,不用也行。
request.setAttribute("condition",condition);
-
第四步: 实现选择器的回显,选择器的回显无法使用value赋值的形式,因为选择器有多个值,你不知道赋给哪个值,可以使用jQuery的方法,业务流程是:判断当前页面选择的选项是否等于提交到web层,封存到对象里的值,如果相等,就选择。不相等就不选择。
$(function(){
$("#isHot option[value='${condition.isHot}']").prop("selected",true);
$("#cid option[value='${condition.cid}']").prop("selected",true);
});
-
第五步: 回显完成后,(其实回显最后做)需要完成web层,web层需要先获取参数对象,封存到Condition容器中,然后调用service业务层,然后再将返回的值转发到该页面。
request.setCharacterEncoding("UTF-8");
Map<String,String[]> properties=request.getParameterMap();
Condition condition=new Condition();
try {
BeanUtils.populate(condition, properties);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
AdminProductService service=new AdminProductService();
List<Product> productList=null;
try {
productList=service.findProductListByCondition(condition);
} catch (SQLException e) {
e.printStackTrace();
}
List<Category> categoryList = null;
try {
categoryList = service.findAllCategory();
} catch (SQLException e) {
e.printStackTrace();
}
request.setAttribute("condition", condition);
request.setAttribute("categoryList", categoryList);
request.setAttribute("productList", productList);
request.getRequestDispatcher("/admin/product/list.jsp").forward(request, response);
- 注意本servlet使用了Map<String,String[]> map=request.getParamapteMap()方法获取的参数,然后用BeanUtils工具类封存对象到Condition容器的。
-
第六步: 调用service层,再调用dao层。
public List<Product> findProductListByCondition(Condition condition) throws SQLException {
QueryRunner runner=new QueryRunner(DataSourceUtils.getDataSource());
List<String> list=new ArrayList<String>();
String sql="select * from product where 1=1";
if(condition.getPname()!=null&&!condition.getPname().trim().equals("")) {
sql+=" and pname like ? ";
list.add("%"+condition.getPname().trim()+"%");
}
if(condition.getIsHot()!=null&&!condition.getIsHot().trim().equals("")) {
sql+=" and is_hot=? ";
list.add(condition.getIsHot().trim());
}
if(condition.getCid()!=null&&!condition.getCid().trim().equals("")) {
sql+=" and cid=? ";
list.add(condition.getCid().trim());
}
List<Product> productList=runner.query(sql, new BeanListHandler<Product>(Product.class),list.toArray());
return productList;
}
-
第七步: 分析dao层,dao层最困难的是sql语句的实现,因为不知道客户如何选择查询的,sql语句不能写死,注意第一条sql语句的where 1=1必须写的,因为不写的话,如果用户不选择任何条件,where不就没用了?sql语句就出错了。最后参数的传递也是一个大问题,因为不知道用户选择哪个选项,只有通过执行哪个,将哪个添加到List集合中,然后传递参数时,将List集合转成数组的形式。