本章学习目录
一,jsp浏览器界面的布局
实现如图的搜索框 (具体功能,输入一个可以进行搜索,多个也可以进项搜索,不输入则查询全部)(页内传送:jsp层 )
< form method = " post" action = " goods.do?operate=queryGoods" >
商品名称:< input type = " text" name = " g_name" placeholder = " 关键字" >
商品单价:< input type = " text" name = " g_price1" placeholder = " 起始价格" > < input type = " text" name = " g_price2" placeholder = " 结束价格" >
上架时间:< input type = " date" name = " g_date1" placeholder = " 起始时间" > < input type = " date" name = " g_date2" placeholder = " 结束时间" >
< button> 搜索</ button>
</ form>
这里可能就有人要问了为什么是action="goods.do?operate=queryGoods"
因为当我未输入数据打开浏览器时,它显示的就是查询全部商品,即搜索功能里包含了显示全部商品的功能 所以我们直接在queryGoods
内部动手 通过servlet层接收:(先不进行转换,后面将会讲到原因)
String g_name= request. getParameter ( "g_name" ) ;
String g_price1= request. getParameter ( "g_price1" ) ;
String g_price2= request. getParameter ( "g_price2" ) ;
String g_date1= request. getParameter ( "g_date1" ) ;
String g_date2= request. getParameter ( "g_date2" ) ;
考虑到通过form
表单接收到的数据,都要使用,所以我们要新建立一个视图层GoodsView
二,视图层GoodsView
考虑到是流程讲解,所以太长的GoodsView
简单说明一下(后面会有全流程),给这五个数据生成get,set方法,空构造,还有这五个参数的构造方法
(页内传送:视图层 )
public class GoodsView {
private String g_name;
private Double g_price1;
private Double g_price2;
private Date g_date1;
private Date g_date2;
}
视图层作用 :这里可以理解为dao
层能够得到界面得到的数据(即得到用户提交的信息),并当成条件,进行查询,从而返回商品信息所以接下来我们完善servlet
层
三,通过网页查看输入的数据
这里思考一下,当我们不输入数据的时候,按下搜索得到的对应的数据是什么呢?是null
?还是""
这里带大家通过网页查看 一下究竟,还可以打印(有必要的话自行去做) jsp浏览器界面制作好了,可以发布了之后,进入界面选中F12
,出现右边的栏目,然后点击我们的搜索框 第三步完成后出现了如图,滑动到底部, 很明显为""
四,servlet层
GoodsView goodsView= new GoodsView ( ) ;
这里我们将我们得到的界面提交的信息分为两种。一是""(即为没有输入),二是用户查询的具体内容 下来思考一个问题,很关键 ! 我们界面提交的信息有字符串String
,浮点型双精度Double
,日期类型Date
很明显我们的""
(即没有输入)不能被后两者接收到,但是null
可以 所以这里我们考虑到如果接收到""
就将其设置成null
,收到具体内容就转换,以便于后面的操作 这里将得到的数据进行判断是否为""
后,是!设置为null
,否!就将该数据进行转化,将最后的结果赋值于goodsView
String g_name= request. getParameter ( "g_name" ) ;
goodsView. setG_name ( "" . equals ( g_name) ? null : g_name) ;
String g_price1= request. getParameter ( "g_price1" ) ;
goodsView. setG_price1 ( "" . equals ( g_price1) ? null : Double . valueOf ( g_price1) ) ;
String g_price2= request. getParameter ( "g_price2" ) ;
goodsView. setG_price2 ( "" . equals ( g_price2) ? null : Double . parseDouble ( g_price2) ) ;
String g_date1= request. getParameter ( "g_date1" ) ;
SimpleDateFormat sim= new SimpleDateFormat ( "yyyy-MM-dd" ) ;
goodsView. setG_date1 ( "" . equals ( g_date1) ? null : sim. parse ( g_date1) ) ;
String g_date2= request. getParameter ( "g_date2" ) ;
goodsView. setG_date2 ( "" . equals ( g_date2) ? null : sim. parse ( g_date2) ) ;
然后调用service层 得到商品集合(服务层不讲,后面会有总体流程)(页内传送:servlet层 service层 ) 再将得到的商品集合请求转发到showgoods 界面(之前做的不用动)
五,SQL动态查询的dao层
要满足不输入搜索,是查询全部 单个搜索,多个一起搜索,是根据提供条件查询 这里我们就要用到字符串拼接了 由于String
类是字符串常量 ,是不可更改 的常量。 而StringBuffer
是字符串变量 ,它的对象是可以扩充 和修改 的,所以用它
StringBuffer sql= new StringBuffer ( "select * from tbl_goods" ) ;
List params= new ArrayList ( ) ;
后面的其他内容根据对应条件拼接 其它内容有个共同的条件就是满足至少有一个存在
if ( goodsView. getG_name ( ) != null || goodsView. getG_price1 ( ) != null || goodsView. getG_price2 ( ) != null || goodsView. getG_date1 ( ) != null || goodsView. getG_date2 ( ) != null ) {
只要进入大条件就要用到where
,思考一下,为什么要跟个1=1
原因很简单!你永远不知道下面的是哪个要用,此时他们的因为条件之间and
是必须的,所以拼凑一个不影响结果的恒成立条件 1=1
大条件下哪个不为空(即null)就就扩充 对应的sql语句 (这里注意sql语句单词间的空格也要留出来) 考虑到我们要用我们的基于反射的DBUtil工具,所以我们的三个参数String sql,Class<T> cla,Object...params
要齐全 这里sql
有了,cla
有了,差一个设置?占位符 的params
,思考一下我们该怎么动态得到对一个的params
这里我们采取List
集合的存储,大条件下哪个不为空就扩充语句并添加元素,再运用toArray()方法
将ArrayList
对象转换成数组
sql. append ( " where 1=1" ) ;
if ( goodsView. getG_name ( ) != null ) {
sql. append ( " and g_name like concat('%',?,'%')" ) ;
params. add ( goodsView. getG_name ( ) ) ;
}
if ( goodsView. getG_price1 ( ) != null ) {
sql. append ( " and g_price>=?" ) ;
params. add ( goodsView. getG_price1 ( ) ) ;
}
if ( goodsView. getG_price2 ( ) != null ) {
sql. append ( " and g_price<=?" ) ;
params. add ( goodsView. getG_price2 ( ) ) ;
}
if ( goodsView. getG_date1 ( ) != null ) {
sql. append ( " and g_date>=?" ) ;
params. add ( goodsView. getG_date1 ( ) ) ;
}
if ( goodsView. getG_date2 ( ) != null ) {
sql. append ( " and g_date<=?" ) ;
params. add ( goodsView. getG_date2 ( ) ) ;
}
接下来就直接使用工具类中的基于反射的查询方法,并返回值 这里的StringBuffer
得到的对象sql
要用toString()方法
,,得到的List集合要用toArray()方法
return super . excuteQuery ( sql. toString ( ) , Goods . class , params. toArray ( ) ) ;
小技巧 :可以在最后的返回前打印sql,以防sql出错导致查询不成功这样搜索的整个操作就完成了(页内传送:dao层 )
六,搜索篇整体流程
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
< html>
< head>
< title> 展示商品</ title>
< style>
table {
border : 1px solid orange;
width : 600px;
border-collapse : collapse;
}
th,td {
border : 1px solid orange;
height : 50px;
line-height : 50px;
text-align : center;
}
</ style>
</ head>
< body>
< form method = " post" action = " goods.do?operate=queryGoods" >
商品名称:< input type = " text" name = " g_name" placeholder = " 关键字" >
商品单价:< input type = " text" name = " g_price1" placeholder = " 起始价格" > < input type = " text" name = " g_price2" placeholder = " 结束价格" >
上架时间:< input type = " date" name = " g_date1" placeholder = " 起始时间" > < input type = " date" name = " g_date2" placeholder = " 结束时间" >
< button> 搜索</ button>
</ form>
< table>
< thead>
< tr>
< th> 商品编号</ th>
< th> 商品名称</ th>
< th> 商品单价</ th>
< th> 上架时间</ th>
< th> 操作</ th>
</ tr>
</ thead>
< tbody>
< c: forEach items = " ${requestScope.goodsList}" var = " good" >
< tr>
< td> ${good.g_id}</ td>
< td> ${good.g_name}</ td>
< td> ${good.g_price}</ td>
< td> < fmt: formatDate value = " ${good.g_date}" pattern = " yyyy-MM-dd" /> </ td>
< td>
< a href = " goods.do?g_id=${good.g_id}&operate=queryGoodsById" > 修改</ a>
< a href = " goods.do?g_id=${good.g_id}&operate=delGoodsById" > 删除</ a>
</ td>
</ tr>
</ c: forEach>
< tr>
< td colspan = " 5" >
< a href = " insertGoods.jsp" > 添加商品</ a>
</ td>
</ tr>
</ tbody>
</ table>
</ body>
</ html>
package cn. jazhong. view ;
import java. util. Date ;
public class GoodsView {
private String g_name;
private Double g_price1;
private Double g_price2;
private Date g_date1;
private Date g_date2;
public GoodsView ( ) {
}
public GoodsView ( String g_name, Double g_price1, Double g_price2, Date g_date1, Date g_date2) {
this . g_name = g_name;
this . g_price1 = g_price1;
this . g_price2 = g_price2;
this . g_date1 = g_date1;
this . g_date2 = g_date2;
}
public String getG_name ( ) {
return g_name;
}
public void setG_name ( String g_name) {
this . g_name = g_name;
}
public Double getG_price1 ( ) {
return g_price1;
}
public void setG_price1 ( Double g_price1) {
this . g_price1 = g_price1;
}
public Double getG_price2 ( ) {
return g_price2;
}
public void setG_price2 ( Double g_price2) {
this . g_price2 = g_price2;
}
public Date getG_date1 ( ) {
return g_date1;
}
public void setG_date1 ( Date g_date1) {
this . g_date1 = g_date1;
}
public Date getG_date2 ( ) {
return g_date2;
}
public void setG_date2 ( Date g_date2) {
this . g_date2 = g_date2;
}
}
private GoodsService goodsService= new GoodsServiceImpl ( ) ;
protected void queryGoods ( HttpServletRequest request, HttpServletResponse response) throws ServletException , IOException {
try {
GoodsView goodsView= new GoodsView ( ) ;
String g_name= request. getParameter ( "g_name" ) ;
goodsView. setG_name ( "" . equals ( g_name) ? null : g_name) ;
String g_price1= request. getParameter ( "g_price1" ) ;
goodsView. setG_price1 ( "" . equals ( g_price1) ? null : Double . valueOf ( g_price1) ) ;
String g_price2= request. getParameter ( "g_price2" ) ;
goodsView. setG_price2 ( "" . equals ( g_price2) ? null : Double . parseDouble ( g_price2) ) ;
String g_date1= request. getParameter ( "g_date1" ) ;
SimpleDateFormat sim= new SimpleDateFormat ( "yyyy-MM-dd" ) ;
goodsView. setG_date1 ( "" . equals ( g_date1) ? null : sim. parse ( g_date1) ) ;
String g_date2= request. getParameter ( "g_date2" ) ;
goodsView. setG_date2 ( "" . equals ( g_date2) ? null : sim. parse ( g_date2) ) ;
List < Goods > goodsList= goodsService. queryAll ( goodsView) ;
request. setAttribute ( "goodsList" , goodsList) ;
request. getRequestDispatcher ( "showgoods.jsp" ) . forward ( request, response) ;
} catch ( ParseException e) {
e. printStackTrace ( ) ;
}
}
private GoodsDao goodsDao= new GoodsDaoImpl ( ) ;
@Override
public List < Goods > queryAll ( GoodsView goodsView) {
return goodsDao. selectAll ( goodsView) ;
}
@Override
public List < Goods > selectAll ( GoodsView goodsView) {
StringBuffer sql= new StringBuffer ( "select * from tbl_goods" ) ;
List params= new ArrayList ( ) ;
if ( goodsView. getG_name ( ) != null || goodsView. getG_price1 ( ) != null || goodsView. getG_price2 ( ) != null || goodsView. getG_date1 ( ) != null || goodsView. getG_date2 ( ) != null ) {
sql. append ( " where 1=1" ) ;
System . out. println ( goodsView. getG_name ( ) ) ;
if ( goodsView. getG_name ( ) != null ) {
sql. append ( " and g_name like concat('%',?,'%')" ) ;
params. add ( goodsView. getG_name ( ) ) ;
}
if ( goodsView. getG_price1 ( ) != null ) {
sql. append ( " and g_price>=?" ) ;
params. add ( goodsView. getG_price1 ( ) ) ;
}
if ( goodsView. getG_price2 ( ) != null ) {
sql. append ( " and g_price<=?" ) ;
params. add ( goodsView. getG_price2 ( ) ) ;
}
if ( goodsView. getG_date1 ( ) != null ) {
sql. append ( " and g_date>=?" ) ;
params. add ( goodsView. getG_date1 ( ) ) ;
}
if ( goodsView. getG_date2 ( ) != null ) {
sql. append ( " and g_date<=?" ) ;
params. add ( goodsView. getG_date2 ( ) ) ;
}
}
System . out. println ( sql) ;
return super . excuteQuery ( sql. toString ( ) , Goods . class , params. toArray ( ) ) ;
}