需求描述
从前端搜索框输入商品搜索关键词,查询数据库是否有对应商品,有则跳转到搜索页并展示
数据传递流程概览与技术简介:
-
【前端>>后端】 从前端获取关键字并查询数据库
-
前端搜索框键入关键词
<form>
表单里用<input>
标签获取输入,<input>
通过name
属性定位 -
控制层
controller
得到搜索关键字,并将之作为参数调用服务层的函数控制层的函数通过
HttpServletRequest
对象的getParameter(String labelName)
方法获取提交的表单中的元素,其中的labelName
参数为表单里<input>
标签的name
数学值 -
服务层
service
的函数再调用数据层的函数服务层里的函数实则就是一个
dao
层函数的封装 -
数据层
dao
函数实际上是sql
语句,查询数据库并获取返回结果其中数据库返回结果类型为java的集合类型
list<myObject>
,其中的myEntity
为自定义的java 类class
,实际上是一些变量的封装,用来存储数据库表中的数据项
-
-
【后端>>前端】 从数据库返回结果到前端展示
-
控制层通过
model
变量将得到的集合变量返回到前端经过上面的层层函数调用后,在控制层得到了类型为java 集合
list<myEntity>
的resulrList
变量,此时在控制层再用model
对象的model.addAttribute("name",object)
方法将resultList
集合变量返回到前端关于
model
变量的更多介绍可见参考链接 -
前端通过
thymeleaf
来展示th:each="sc : ${resultList}
,在对应的html
元素(比如<li>
)便签上添加该代码,其中的resultList
即控制层通过model
返回的变量的名称name
,该语法表示迭代(遍历) 集合resultList
,sc
表示集合中的任意一个元素 (sc
对应上面定义的entity类的一个实例对象,对应数据库表中的一行数据)th:text="${sc.cname}"
可以根据需要输出对应的变量(对应实例对象的一个属性,对应数据库表中的数据项)关于模板引擎
thymeleaf
的更多语法介绍课件参考链接
-
编写顺序一般是从后端往前端的,或者先写 html
页面 (和控制层controller
,确定了服务层的函数接口名称后再从后往前编写代码
代码实现
数据库表 tb_commodity
的创建代码
DROP TABLE IF EXISTS `tb_commodity`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tb_commodity` (
`commodity_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品编号,主键,自动增长',
`second_category_id` int(11) NOT NULL COMMENT '二级类别编号(外键) ',
`brand_id` int(11) NOT NULL COMMENT '品牌编号(外键)',
`cname` varchar(50) NOT NULL COMMENT '商品名称',
`promotional_price` double DEFAULT NULL COMMENT '促销价',
`original_price` double NOT NULL COMMENT '原价',
`description` varchar(500) NOT NULL COMMENT '商品描述',
`img` varchar(30) NOT NULL COMMENT '商品图片名',
`createtime` datetime NOT NULL COMMENT '创建时间',
`type` varchar(50) DEFAULT NULL COMMENT '产品类型',
`product_area` varchar(50) DEFAULT NULL COMMENT '原料产地',
`product_place` varchar(50) DEFAULT NULL COMMENT '产地',
`product_specificat` varchar(50) DEFAULT NULL COMMENT '产品规格',
`expiration_date` varchar(50) DEFAULT NULL COMMENT '保质期',
`usage` varchar(50) DEFAULT NULL COMMENT '食用方法',
`storage_method` varchar(50) DEFAULT NULL COMMENT '存储方法',
`standard_number` varchar(50) DEFAULT NULL COMMENT '产品标准号',
`license_number` varchar(50) DEFAULT NULL COMMENT '生产许可号',
PRIMARY KEY (`commodity_id`),
KEY `second_category_id_7_idx` (`second_category_id`),
KEY `brand_id` (`brand_id`),
CONSTRAINT `brand_id_7` FOREIGN KEY (`brand_id`) REFERENCES `tb_brand` (`brand_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `second_category_id_7` FOREIGN KEY (`second_category_id`) REFERENCES `tb_second_category` (`second_category_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
数据库表对应的实体层 entity
的变量封装
import lombok.Data;
import java.sql.Timestamp;
/*
*商品实体类
*/
@Data
public class CommodityEntity {
private int commodity_id; //主键
private int second_category_id; //外键
private int brand_id; //外键
private String cname;//商品名
private double promotional_price;//促销价
private double original_price;
private String description;
private String img;
private Timestamp createtime;
private String type;
private String product_place;
private String product_area;
private String product_specificat;
private String expiration_date;
private String usage;
private String storage_method;
private String storage_number;
private String license_number;
}
数据层dao
代码
import com.example.demo.entity.CommodityEntity;
import com.example.demo.entity.FlavorEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface CommodityDao {
/*根据输入内容筛选CommodityEntity的对象*/
@Select(value = "select * from demo.tb_commodity where cname REGEXP #{arg0} ")
List<CommodityEntity> search_commodity(String search_input);
}
服务层 service
代码
可以拆开写接口和实现代码文件,也可以直接书写,关于service
层 和 dao
层是否应该分离接口和实现问题,参考链接有关于分离的好处介绍
接口 CommodityService.java
代码
import com.example.demo.entity.CommodityEntity;
import com.example.demo.entity.FlavorEntity;
import java.util.List;
public interface CommodityService {
List<CommodityEntity> search_commodity(String search_input);
}
函数实现 CommodityServiceImpl
代码
import com.example.demo.dao.CommodityDao;
import com.example.demo.entity.CommodityEntity;
import com.example.demo.entity.FlavorEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.service.CommodityService;
import java.util.List;
@Service
public class CommodityServiceImpl implements CommodityService{
@Autowired
private CommodityDao commodityDao;
@Override
public List<CommodityEntity> search_commodity(String search_input){
return commodityDao.search_commodity(search_input);
}
}
控制层 controller
代码
import com.example.demo.entity.CommodityEntity;
import com.example.demo.service.CommodityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;
@Controller
public class CommodityController {
@Autowired
private CommodityService commodityService;
@RequestMapping(value = "/search") //搜索时跳转的路由
public String search(HttpServletRequest request, HttpSession httpSession, Model model){
String search_input = request.getParameter("index_none_header_sysc");//获取搜索框输入
List<CommodityEntity> tmp = commodityService.search_commodity(search_input);//调用对应服务层函数获取返回的搜索结果list集合 tmp
// System.out.println(tmp); //在控制台输出检查是否争取返回
if(tmp != null){//返回不为空。搜索成功
/*将搜索结果集合、集合元素个数(结果商品个数)、搜索关键字添加到model的属性中返回前端页面*/
model.addAttribute("search_result",tmp);//搜索结果商品list
model.addAttribute("result_num",tmp.size());//搜索结果商品数
model.addAttribute("search_key",search_input);//搜索关键词
return "FrontPages/search";//跳转到搜索页search.html
}
else{//搜索失败
model.addAttribute("error_search_fail","没有相关商品");
return "FrontPages/index";
}
}
前端 html
搜索框部分代码
<!--悬浮搜索框-->
<div class="nav white">
<div class="logoBig">
<li><img src="images/logobig1.png" /></li>
</div>
<div class="search-bar pr">
<form action="/search" target=_parent><!--因为该部分代码是作为一个独立html文件在<iframe>中引入的,所以为了将返回页全面显示需要这样设置target-->
<input id="searchInput" name="index_none_header_sysc" type="text" placeholder="搜索" autocomplete="off">
<input id="ai-topsearch" class="submit am-btn" value="搜索" index="1" type="submit">
</form>
</div>
</div>
前端html
搜索结果页search.html
代码
<li style=" width:206px; height:306px" th:each="sc : ${search_result}">
<div class="i-pic limit">
<a href="detail.html"><img th:src="${sc.img}" /></a>
<p class="title fl" th:text="${sc.cname}"></p>
<p class="price fl" th:utext="'<b>¥</b><strong>'+${sc.promotional_price}+'</strong>'">
</p>
</div>
</li>
参考链接
其中[2] [3]中的利用model从控制层传递参数到前端可见我的另一篇博客//to post,不过参考链接里介绍了另一种 通过ModelAndView
对象的方法,ModelAndView
对象是同时设置返回变量和跳转页面,而Model
则是
单独设置返回变量,用return
语句设置跳转页面
[1] thymeleaf语法简介
网友评论