shop第三天

前端模板doT.js简介与安装

doT.js是什么?

是一个前端模板引擎。模板用于提取公共部分,变化的部分通过传入的数据,进行替换。

为什么使用前端模板引擎?

手动拼接字符串-复杂

手动拼接字符串页面响应速度比较慢,js模板加快页面响应速度

手动拼接字符串不安全

使用doT.js能够提高开发速度

为什么选择doT.js模板?

如何使用?

引入doT.js(doT.js不依赖于jQuery往往和jQuery结合,提高开发速度)

编写模板

调用模板

    Demo.html

   

       

       

       

   

   

       

       

       


       

       

           

               

                   

                   

               

           

           

       

编号 姓名



       

       

            {{ for(var i=0;i

               

  • {{=it[i]}}
  •             {{ } }}

           


           

                {{ for(var i=0;i


                        {{=it[i].id}}

                        {{=it[i].name}}


                {{ } }}

           



           

            //模拟通过ajax从后台得到的数据

            vardata=["1","2","3"];

            // 获取模板

            vartemp=doT.template($("#temp_01").text());

            // 填充数据

            $("#content_01").html(temp(data));


            //模拟通过ajax从后台得到的数据

        vardata2=[{"id":1,"name":"zhangsan"},{"id":2,"name":"lisi"},{"id":3,"name":"wangwu"}];

            // 获取模板

            vartemp2=doT.template($("#temp_02").text());

            // 填充数据

            $("#content_02").html(temp2(data2));

           

       

    测试结果

    商品列表-分页查询

    Service服务层

    GoodsCategoryService.java

    /**

    * 商品分类-查询所有商品分类

    * @return

    */

    ListselectCategoryList();

    GoodsCategoryServiceImpl.java

    /**

    * 商品分类-查询所有商品分类

    * @return

    */

    @Override

    publicListselectCategoryList() {

    returngoodsCategoryMapper.selectByExample(newGoodsCategoryExample());

    }

    BrandService.java

    /**

    * 查询所有商品品牌

    * @return

    */

    ListselectBrandList();

    BrandServiceImpl.java

    /**

    * 查询所有商品品牌

    * @return

    */

    @Override

    publicListselectBrandList() {

    returnbrandMapper.selectByExample(newBrandExample());

    }

    Controller控制层

    GoodsController.java

    /**

    * 商品-列表-页面跳转

    *

    * @return

    */

    @RequestMapping("list")

    publicStringGoodsList(Modelmodel) {

    //返回所有商品分类

    ListgcList=goodsCategoryService.selectCategoryList();

    model.addAttribute("gcList",gcList);

    //返回所有商品品牌

    ListbrandList=brandService.selectBrandList();

    model.addAttribute("brandList",brandList);

    return"goods/goods-list";

    }

    ftl页面

    goods-list.ftl

    删除页面无用的代码

    处理分类列表和品牌列表,修改form表单中的域名称与对象属性一一对应

    所有分类

    <#listgcListasgc>

    ${gc.name}

    class="form-control">

    所有品牌

    <#listbrandListasbrand>

    ${brand.name}

    添加每页显示*条,处理搜索词和筛选,修改form表单中的域名称与对象属性一一对应

    每页显示

    class="form-control">

    10

    20

    50

    100

    关键词

    id="button-filter search-order"class="btn btn-primary">

       筛选

    修改BaseResult.java添加成功返回分页对象的方法

    //成功返回的对象-带分页对象

    public static BaseResult success(PageInfo pageInfo) {

        BaseResult result = new BaseResult();

        result.setCode(BaseResultEnum.SUCCESS.getCode());

        result.setMessage(BaseResultEnum.SUCCESS.getMessage());

        result.setPageInfo(pageInfo);

        return result;

    }

    Service服务层

    GoodsService.java

    /**

    * 商品-列表-分页查询

    * @param goods

    * @param pageNum

    * @param pageSize

    * @return

    */

    BaseResult selectGoodsListByPage(Goods goods,Integer pageNum,Integer pageSize);

    GoodsServiceImpl.java

    /**

    * 商品-列表-分页查询

    * @param goods

    * @param pageNum

    * @param pageSize

    * @return

    */

    @Override

    public BaseResult selectGoodsListByPage(Goods goods, Integer pageNum, Integer pageSize) {

      //构建分页对象

      PageHelper.startPage(pageNum,pageSize);

      //创建查询对象

      GoodsExample example = new GoodsExample();

      GoodsExample.Criteria criteria = example.createCriteria();

      //设置查询条件

      //分类参数

      if (null!=goods.getCatId()&&0!=goods.getCatId()){

          criteria.andCatIdEqualTo(goods.getCatId());

      }

      //品牌参数

      if (null!=goods.getBrandId()&&0!=goods.getBrandId()){

          criteria.andBrandIdEqualTo(goods.getBrandId());

      }

      //关键词

      if (!StringUtils.isEmpty(goods.getGoodsName())){

          criteria.andGoodsNameLike("%"+goods.getGoodsName()+"%");

      }

      //查询

      List list = goodsMapper.selectByExample(example);

      //将查询结果设置至分页对象

      if (!CollectionUtils.isEmpty(list)){

          PageInfo pageInfo = new PageInfo<>(list);

          return BaseResult.success(pageInfo);

      }

      return BaseResult.error();

    }

    Controller层

    /**

    * 商品-列表-分页查询

    * @param goods

    * @param pageNum

    * @param pageSize

    * @return

    */

    @RequestMapping("listForPage")

    @ResponseBody

    public BaseResult selectGoodsListByPage(Goods goods,Integer pageNum,Integer pageSize){

      return goodsService.selectGoodsListByPage(goods,pageNum,pageSize);

    }

    ftl页面

    head.ftl引入doT.min.js文件(项目对应包下引入doT.min.js文件)

    在分类、品牌、每页显示、筛选上添加onchange="ajax_get_table(1);"

    进入goods-list.ftl页面提交分页查询

    $(document).ready(function () {

        // ajax 加载商品列表

        ajax_get_table(1);

    });

    //ajax抓取页面 page为当前第几页

    function ajax_get_table(page) {

        $.ajax({

            url: "${ctx}/goods/listForPage",

            type: "POST",

            data: {

                catId: $("#catId").val(),

                brandId: $("#brandId").val(),

                goodsName: $("#goodsName").val(),

                pageNum: page,

                pageSize: $("#pageSize").val()

            },

            dataType: "JSON",

            success: function (result) {

                if (200 == result.code) {

                    if (result.pageInfo.list.length > 0) {

                        //获取商品列表模板

                        var goodsTemp = doT.template($("#goodsTemplate").text());

                        //填充数据

                        $("#goodsContent").html(goodsTemp(result.pageInfo.list));

                        //获取分页模板

                        var pageTemp = doT.template($("#pageTemplate").text());

                        //填充数据

                        $("#pageContent").html(pageTemp(result.pageInfo));

                    } else {

                        layer.msg("该分类或品牌暂无商品信息!");

                    }

                } else {

                    layer.msg("该分类或品牌暂无商品信息!");

                }

            },

            error: function (result) {

                console.log(result)

            }

        });

    }

    使用doT.js模板处理goods-list.ftl商品列表信息和分页

    goods-list.ftl最终修改部分结果如下

       

           

               

                   

                   

                       

                       

                       

                       

                       

                       

                       

                       

                       

                   

                   

                   

                   

               

                       

                            ID

                       

                            商品名称

                       

                            货号

                       

                            分类

                       

                            价格

                       

                            库存

                       

                            排序

                       

    操作

           

           

                  value="00ea0d70ce1e0760a8bf5d90b5e30971_699560bd02bf6cad1be4e51b170eb190"

                  type="hidden">

       

           

           

               

                   

                     

               

           

       

    商城项目中集成Redis实现缓存

    shop-manager引入依赖

    pom.xml

      org.springframework.boot

      spring-boot-starter-data-redis

      org.apache.commons

      commons-pool2

    application.yml

    # Redis配置

      redis:

        timeout: 10000ms                        # 连接超时时间

        host: 192.168.10.100                  # Redis服务器地址

        port: 6379                              # Redis服务器端口

        database: 0                            # 选择哪个库,默认0库

        lettuce:

          pool:

            max-active: 1024                    # 最大连接数,默认 8

            max-wait: 10000ms                  # 最大连接阻塞等待时间,单位毫秒,默认 -1

            max-idle: 200                      # 最大空闲连接,默认 8

            min-idle: 5                          # 最小空闲连接,默认 0

    # Redis Key

    # 商品分类列表 Key

    goods.category.list.key: goods:category:list:goodsCategoryList

    RedisConfig.java

    package com.xxxx.manager.config;

    import org.springframework.context.annotation.Bean;

    import org.springframework.context.annotation.Configuration;

    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;

    import org.springframework.data.redis.core.RedisTemplate;

    import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;

    import org.springframework.data.redis.serializer.StringRedisSerializer;

    /**

    * Redis配置类

    *

    * @author zhoubin

    * @since 1.0.0

    */

    @Configuration

    public class RedisConfig {

    @Bean

    public RedisTemplate redisTemplate(LettuceConnectionFactory redisConnectionFactory){

    RedisTemplate redisTemplate = new RedisTemplate<>();

    //为string类型key设置序列器

    redisTemplate.setKeySerializer(new StringRedisSerializer());

    //为string类型value设置序列器

    redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

    //为hash类型key设置序列器

    redisTemplate.setHashKeySerializer(new StringRedisSerializer());

    //为hash类型value设置序列器

    redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

    redisTemplate.setConnectionFactory(redisConnectionFactory);

    return redisTemplate;

    }

    }

    shop-common添加Json工具类

    JsonUtil.java

    package com.xxxx.common.util;

    import com.fasterxml.jackson.core.JsonParseException;

    import com.fasterxml.jackson.core.JsonProcessingException;

    import com.fasterxml.jackson.databind.JavaType;

    import com.fasterxml.jackson.databind.JsonMappingException;

    import com.fasterxml.jackson.databind.ObjectMapper;

    import java.io.IOException;

    import java.util.List;

    /**

    * @see(功能介绍) : Json转换工具类

    * @version(版本号) : 1.0

    * @author(创建人) : zhoubin

    */

    public class JsonUtil {

        private static ObjectMapper objectMapper = new ObjectMapper();

        /**

        * 将对象转换成json字符串

        *

        * @param obj

        * @return

        */

        public static String object2JsonStr(Object obj) {

            try {

                return objectMapper.writeValueAsString(obj);

            } catch (JsonProcessingException e) {

                //打印异常信息

                e.printStackTrace();

            }

            return null;

        }

        /**

        * 将字符串转换为对象

        *

        * @param 泛型

        */

        public static T jsonStr2Object(String jsonStr, Class clazz) {

            try {

                return objectMapper.readValue(jsonStr.getBytes("UTF-8"), clazz);

            } catch (JsonParseException e) {

                e.printStackTrace();

            } catch (JsonMappingException e) {

                e.printStackTrace();

            } catch (IOException e) {

                e.printStackTrace();

            }

            return null;

        }

        /**

        * 将json数据转换成pojo对象list

        *

    Title: jsonToList

        *

    Description:

        *

        * @param jsonStr

        * @param beanType

        * @return

        */

        public static List jsonToList(String jsonStr, Class beanType) {

            JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, beanType);

            try {

                List list = objectMapper.readValue(jsonStr, javaType);

                return list;

            } catch (Exception e) {

                e.printStackTrace();

            }

            return null;

        }

    }

    Service层实现Redis缓存

    商品列表查询

    GoodsServiceImpl.java

    /**

    * 商品-列表-分页查询

    *

    * @param goods

    * @param pageNum

    * @param pageSize

    * @return

    */

    @Override

    public BaseResult selectGoodsListByPage(Goods goods, Integer pageNum, Integer pageSize) {

      //构建分页对象

      PageHelper.startPage(pageNum, pageSize);

      //创建查询对象

      GoodsExample example = new GoodsExample();

      GoodsExample.Criteria criteria = example.createCriteria();

      //商品列表RedisKey

        /*

          分析:

          此功能查询分为七种(所有条件都包含分页参数):

              a. 无条件查询

              b. 根据分类查询

              c. 根据品牌查询

              d. 根据关键词查询

              e. 根据分类_品牌查询

              f. 根据分类_关键词查询

              g. 根据品牌_关键词查询

          无条件查询key

              goods:list:pageNum_:pageSize_:catId_:brandId_:goodsName_

          条件查询key

              goods:pageNum_:pageSize_:catId_123:brandId_:goodsName_(根据分类查询)

              goods:pageNum_:pageSize_:catId_:brandId_123:goodsName_(根据品牌查询)

              goods:pageNum_:pageSize_:catId_:brandId_:goodsName_华为(根据关键词查询)

              goods:pageNum_:pageSize_:catId_123:brandId_123:goodsName_(根据分类_品牌查询)

              goods:pageNum_:pageSize_:catId_123:brandId_:goodsName_华为(根据分类_关键词查询)

              goods:pageNum_:pageSize_:catId_:brandId_123:goodsName_华为(根据品牌_关键词查询)

              */

      String goodsKeyArr[] = new String[]{"goods:pageNum_" + pageNum + ":pageSize_" + pageSize + ":",

            "catId_:",

            "brandId_:",

            "goodsName_:"};

      //设置查询条件

      //分类参数

      if (null != goods.getCatId() && 0 != goods.getCatId()) {

          criteria.andCatIdEqualTo(goods.getCatId());

          goodsKeyArr[1] = "catId_" + goods.getCatId() + ":";

      }

      //品牌参数

      if (null != goods.getBrandId() && 0 != goods.getBrandId()) {

          criteria.andBrandIdEqualTo(goods.getBrandId());

          goodsKeyArr[2] = "brandId" + goods.getBrandId() + ":";

      }

      //关键词

      if (!StringUtils.isEmpty(goods.getGoodsName())) {

          criteria.andGoodsNameLike("%" + goods.getGoodsName() + "%");

          goodsKeyArr[3] = "goodsName_" + goods.getGoodsName() + ":";

      }

      ValueOperations valueOperations = redisTemplate.opsForValue();

      //拼接Redis key

      String goodsListKey = Arrays.stream(goodsKeyArr).collect(Collectors.joining());

      //查询缓存,如果缓存中存在数据,直接返回 

      String pageInfoGoodsJson = valueOperations.get(goodsListKey);

      if (!StringUtils.isEmpty(pageInfoGoodsJson)) {

          return BaseResult.success(JsonUtil.jsonStr2Object(pageInfoGoodsJson, PageInfo.class));

      }

      //查询

      List list = goodsMapper.selectByExample(example);

      //将查询结果设置至分页对象

      if (!CollectionUtils.isEmpty(list)) {

          PageInfo pageInfo = new PageInfo<>(list);

          //放入缓存

          valueOperations.set(goodsListKey, JsonUtil.object2JsonStr(pageInfo));

          return BaseResult.success(pageInfo);

      } else {

          //没有数据,将空数据缓存,设置失效时间60s

          valueOperations.set(goodsListKey, JsonUtil.object2JsonStr(new PageInfo<>(new ArrayList())), 60,

                TimeUnit.SECONDS);

      }

      return BaseResult.error();

    }

    商品分类查询

    GoodsCategoryServiceImpl.java

    /**

    * 商品分类-列表

    *

    * @return

    */

    @Override

    public List selectCategoryListForView() {

      ValueOperations valueOperations = redisTemplate.opsForValue();

      //查询缓存,如果缓存中有数据,直接返回

      String gcListJson = valueOperations.get(goodsCategoryListKey);

      if (!StringUtils.isEmpty(gcListJson)){

          return JsonUtil.jsonToList(gcListJson,GoodsCategoryVo.class);

      }

      //创建查询对象

        GoodsCategoryExample example = new GoodsCategoryExample();

        //查询所有的商品分类list

        List list = goodsCategoryMapper.selectByExample(example);

        //将List转成List

        List gcvList = list.stream().map(e -> {

            GoodsCategoryVo gcv = new GoodsCategoryVo();

            BeanUtils.copyProperties(e, gcv);

            return gcv;

        }).collect(Collectors.toList());

        /**

      * 将List转成Map>

      * 按parentId分组,key为parentId,value为parentId对应的List

    */

        Map> map =

            gcvList.stream().collect(Collectors.groupingBy(GoodsCategoryVo::getParentId));

        /**

      * 循环,将childrenList赋值

    */

        gcvList.forEach(e -> e.setChildrenList(map.get(e.getId())));

        /**

          * 拦截器,返回Level为1的List,也就是顶级分类

    */

        List gcvList01 = gcvList.stream().filter(e -> 1 == e.getLevel()).collect(Collectors.toList());

      //放入缓存

      valueOperations.set(goodsCategoryListKey, JsonUtil.object2JsonStr(gcvList01));

      return gcvList01;

    }

    测试Redis缓存

    GoodsServiceTest.java

    package com.xxxx.manager;

    import com.xxxx.common.result.BaseResult;

    import com.xxxx.common.util.JsonUtil;

    import com.xxxx.manager.pojo.Goods;

    import com.xxxx.manager.service.GoodsService;

    import org.junit.jupiter.api.Test;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.boot.test.context.SpringBootTest;

    /**

    * 商品测试

    *

    * @author zhoubin

    * @since 1.0.0

    */

    @SpringBootTest(classes = ManagerApplication.class)

    public class GoodsServiceTest {

      @Autowired

      private GoodsService goodsService;

      @Test

      public void testGoodsRedis(){

          Goods goods = new Goods();

          goods.setGoodsName("华为");

          BaseResult baseResult = goodsService.selectGoodsListByPage(goods, 1, 10);

          System.out.println(JsonUtil.object2JsonStr(baseResult.getPageInfo()));

      }

    }

    缓存更新

    新增或者修改或者删除成功以后,删除Redis缓存的信息

    /**

    * 商品新增-保存

    *

    * @param goods

    * @return

    */

    @Override

    public BaseResult saveGoods(Goods goods) {

      BaseResult baseResult = BaseResult.error();

      //如果goodsId不为空直接返回错误

      if (null != goods.getGoodsId()) {

          return baseResult;

      }

      //goodsName必填

      if (StringUtils.isEmpty(goods.getGoodsName())) {

          return baseResult;

      }

      // 写操作中,清除Redis缓存数据,再次查询时新的数据将会放入缓存

      redisTemplate.delete(redisTemplate.keys("goods*"));

      //如果有详情,先转义

      if (!StringUtils.isEmpty(goods.getGoodsContent())) {

          goods.setGoodsContent(HtmlUtils.htmlEscape(goods.getGoodsContent(), "UTF-8"));

      }

      int result = goodsMapper.insertSelective(goods);

      //如果成功返回信息里加入插入商品的主键

      if (result > 0) {

          baseResult = BaseResult.success();

          baseResult.setMessage(String.valueOf(goods.getGoodsId()));

      }

      return baseResult;

    }

    /**

    * 商品分类-新增分类-保存

    *

    * @param goodsCategory

    * @return

    */

    @Override

    public int categorySave(GoodsCategory goodsCategory) {

      //写操作中,清除Redis中的数据,再次查询时将新数据放入缓存中

      redisTemplate.delete(redisTemplate.keys("goods*"));

      return goodsCategoryMapper.insertSelective(goodsCategory);

    }

    你可能感兴趣的:(shop第三天)