美文网首页
spring boot +thymeleaf 详细的前后端数据打

spring boot +thymeleaf 详细的前后端数据打

作者: Aurochsy | 来源:发表于2019-07-17 22:55 被阅读0次

需求描述

从前端搜索框输入商品搜索关键词,查询数据库是否有对应商品,有则跳转到搜索页并展示

数据传递流程概览与技术简介:

  • 【前端>>后端】 从前端获取关键字并查询数据库

    • 前端搜索框键入关键词

      <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语法简介

[2] controller传递数据到thymeleaf的两种方式

[3] thymeleaf获取后台model值

[4] 为什么dao层和service层要使用接口

相关文章

网友评论

      本文标题:spring boot +thymeleaf 详细的前后端数据打

      本文链接:https://www.haomeiwen.com/subject/vishlctx.html