二十六、商城 - 广告管理-Redis(14)

一、网站前台分析

1.1 网站前台有哪些页面

  1. 网站首页
  2. 商家(店铺)首页
  3. 商品详细页
  4. 商品搜索页
  5. 购物车列表页
  6. 购物选项选择页
  7. 支付页
  8. 用户注册页
  9. 用户登陆页
  10. 用户中心页等

1.2 网站首页广告

  1. 首页海报(轮播图)
  2. 今日推荐
  3. 猜你喜欢
  4. 楼层广告

1.3 数据库表结构分析

tb_content_category 广告分类表

字段类型长度含义
idBigint 主键
nameVarchar255 广告分类名称

tb_content 广告表

字段类型长度含义
idBigint主键
category_idBigint 广告分类ID
titlevarchar200广告标题
urlvarchar500广告链接
picvarchar300图片地址
statusvarchar1状态
sort_orderint1排序

二、运营商后台-广告类型及广告管理

2.1 需求分析

实现广告类型表与广告表的增删改查
广告管理页 显示广告类别名称

2.2 准备工作

2.2.1 构建工程

在这里插入图片描述

构建工程

  1. youlexuan_content_interface
  • 引入依赖 youlexuan_pojo,youlexuan_dao
  • 创建包 com.zql.content.service
  1. youlexuan_content_service (WAR)
  • 引入依赖参见 youlexuan_sellergoods_service
  • 引入 tomcat 插件配置 ,指定tomcat的运行端口为9002
  • 为 youlexuan_content_service 工程添加web.xml
  • 添加spring相关配置文件
  • 创建包 com.zql.content.service.impl
  1. 构建子工程 youlexuan_content_interface
    (1) 在youlexuan_parent 下面构建子工程 youlexuan_content_interface
    在这里插入图片描述
    在这里插入图片描述
    (2)引入依赖 youlexuan_pojo
<dependency>
    <groupId>com.zql</groupId>
    <artifactId>youlexuan_pojo</artifactId>
    <version>1.0</version>
</dependency>

在这里插入图片描述
(3)创建包 com.zql.content.service(看上面总结构图)

  1. 构建子工程 youlexuan_content-service

    (1) 在youlexuan_parent下面构建子工程 youlexuan_content-service(类似上面1/(1)构建)

    (2)拷贝 youlexuan_sellergoods_service下面 pom.xml依赖并做修改

  1. 修改 youlexuan_sellergoods_interface 为 youlexuan_content_interface
  2. 修改tomcat的运行端口为9002
<packaging>war</packaging>
<properties>
    <webVersion>3.0</webVersion>
</properties>
<dependencies>
    <!-- Spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
    </dependency>
    <!-- dubbo相关 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
    </dependency>
    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
    </dependency>
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.zql</groupId>
        <artifactId>youlexuan_common</artifactId>
        <version>1.0</version>
    </dependency>
    <dependency>
        <groupId>com.zql</groupId>
        <artifactId>youlexuan_dao</artifactId>
        <version>1.0</version>
    </dependency>
    <dependency>
        <groupId>com.zql</groupId>
        <artifactId>youlexuan_content_interface</artifactId>
        <version>1.0</version>
    </dependency>

    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
    </dependency>
</dependencies>
<build>
    <plugins>
        <!-- 配置Tomcat插件 -->
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <configuration>
                <path>/</path>
                <port>9002</port>
            </configuration>
        </plugin>
    </plugins>
</build>

(3) 为 youlexuan_content_service 工程添加web.xml

  1. 拷贝 youlexuan_sellergoods_service 下面的webapp / WEB-INF / web.xml
  2. 拷贝 youlexuan_sellergoods_service下面的 spring / applicationContext_service.xml,需要事务也可以拷贝过来,并做下面①②③修改
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 加载spring容器 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring/applicationContext_*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

在这里插入图片描述

注意:我们目前有两个服务工程,当两个工程同时启动时会发生端口冲突,因为连接dubbo注册中心的端口默认是20880。所以我们需要配置一下youlexuan_content_service工程的dubbo端口

(4) 创建包 com.zql.content.service.impl(见上面总结构图)

2.2.2 将前面生成代码拷入工程

附加操作 👇🏾👇🏾

在这里插入图片描述

下载生成代码 资源 并解压拷贝(或用IDEA打开直接对应拷贝)

在 youlexuan_manager_web下的pom.xml中引入 youlexuan_content_interface

<dependency>
    <groupId>com.zql</groupId>
    <artifactId>youlexuan_content_interface</artifactId>
    <version>1.0</version>
</dependency>

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

修改youlexuan_manager_web下面的 resources / spring / springmvc.xml扫描包路径

在这里插入图片描述

测试运行广告分类管理 和广告管理页面

在这里插入图片描述

  1. 整体安装工程 youlexuan_parent
  2. 开启 content_service
  3. 开启 sellerGoods_service
  4. 开启 manager_web
  5. 访问 http://localhost:9101/login.html

在这里插入图片描述

广告图片没有找到解决 👉🏾👉🏾 七、广告图片未找到

重启 manager_web,访问如下所示 (测试crud都OK):

在这里插入图片描述

2.3 广告管理

2.3.1 广告管理类别名称,状态,图片 显示

  1. 在youlexuan_manager_web 下的 js /controller / contentController.js 引入contentCategoryService

在这里插入图片描述

  1. 在youlexuan_manager_web 下的 js /controller / contentController.js 中增加方法
//广告管理显示广告类别
$scope.contentCategory = [];

$scope.status = ['禁用','启用'];

$scope.findAllContentCategory= function () {

	contentCategoryService.findAll().success(function (response) {

		for (var i=0; i < response.length; i++) {

			$scope.contentCategory[response[i].id]= response[i].name;
		}

   });
}
  1. 修改 content.html

在这里插入图片描述

在这里插入图片描述

最终显示:

在这里插入图片描述

2.3.2 编辑窗口广告状态框显示

修改新建广告 按钮,弹出新增框前,初始化广告状态为1 ng-click="entity={status:'1'}"

在这里插入图片描述

在这里插入图片描述

修改为如下所示:

在这里插入图片描述

2.3.3 编辑窗口状态广告类别显示

//加载广告分类列表
$scope.contentCategoryList = response;
<tr>
	<td>广告类别</td>
	<td><select class="form-control" ng-model="entity.categoryId" ng-options="item.id as item.name for item in contentCategoryList"></select></td>
</tr>

在这里插入图片描述

在这里插入图片描述

2.3.4 编辑窗口图片显示

<tr>
  <td>图片绝对路径</td>
  <td><input type="file" id="file">
      <button ng-click="uploadFile()">上传</button>
      <img src="{{entity.pic}}" height="100px" width="200px">
  </td>
</tr>

在这里插入图片描述

2.3.5 广告图片上传

拷贝 youlexuan_shop_web 下面到 youlexuan_manager_web

  1. 拷贝 resources / conf 到 youlexuan_manager_web下面对应位置

在这里插入图片描述

  1. 拷贝 youlexuan_shop_web 中的ContentCategoryController.java 到 youlexuan_manager_web 对应位置

在这里插入图片描述

  1. 修改 youlexuan_manager_web 下面 springmvc.xml,如下添加
<context:property-placeholder location="classpath:conf/application.properties"></context:property-placeholder>

<!-- 配置文件上传多媒体解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
   <property name="defaultEncoding" value="UTF-8"></property>
   <!-- 设定文件上传的最大值5MB,5*1024*1024 -->
   <property name="maxUploadSize" value="5000242880"></property>
</bean>

在这里插入图片描述

  1. 拷贝 youlexuan_shop_web 下的 uploadService.js 到youlexuan_manager对应下面

在这里插入图片描述

  1. 拷贝下面代码到 youlexuan_manager_web下的 contentController.js 内,并做修改
//上传图片
$scope.uploadFile = function () {

    uploadService.uploadFile().success(function (response) {

        if(response.success){  //如果上传成功,就取出url

            $scope.entity.pic = response.message;//设置文件地址
        }else{

            alert(response.message);
        }

    }).error(function () {

        alert("上传发生错误");

    })

};

在这里插入图片描述

记得引入 uploadService 👇🏾👇🏾

在这里插入图片描述

  1. 在 content.html 中引入 uploadService ,如下 js
 <script type="text/javascript" src="../js/service/uploadService.js"></script>

在这里插入图片描述

最终显示 :重新启动 manager_web,刷新网页显示

在这里插入图片描述

上传成功如下(下载 👉🏾图片素材可多添几张) 👇🏾👇🏾

在这里插入图片描述

三、网站首页-广告展示

3.1 需求分析

修改首页,当其轮播广告图根据后台设置的广告列表动态产生。

3.2 准备工作

3.2.1 工程搭建

创建war子模块 youlexuan_portal_web ,此工程为网站前台的入口,参照其它war模块编写配置文件。不需要添加SpringSecurity框架

(1)导入下面依赖到 pom.xml中

<packaging>war</packaging>
<properties>
    <webVersion>3.0</webVersion>
</properties>
<dependencies>
    <!-- Spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
    </dependency>
    <!-- dubbo相关 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
    </dependency>
    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
    </dependency>
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>com.zql</groupId>
        <artifactId>youlexuan_content_interface</artifactId>
        <version>1.0</version>
    </dependency>

    <!-- 增加pagehelper类、mybatis类,因为Service使用了,不导入会报序列化错 -->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
    </dependency>

</dependencies>
<build>
    <plugins>
        <!-- 配置Tomcat插件 -->
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <configuration>
                <path>/</path>
                <port>9103</port>
            </configuration>
        </plugin>
    </plugins>
</build>

(2)创建 web.xml

在这里插入图片描述
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/springmvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/spring-*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
</web-app>

(3)resources 下面创建 spring / springmvc.xml

导入 springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
		http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <context:component-scan base-package="com.zql"/>

    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes" value="application/json"/>
                <property name="features">
                    <array>
                        <value>WriteMapNullValue</value>
                        <value>WriteDateUseDateFormat</value>
                    </array>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- 引用dubbo 服务 -->
    <dubbo:application name="youlexuan_portal_web" />
    <dubbo:registry address="zookeeper://192.168.188.180:2181"/>
    <dubbo:annotation package="com.zql" />
</beans>

3.2.2 前端

(1)拷贝资源:(资源 \ 静态原型 \ 网站前台 )目录下的index.html以及相关目录拷贝到youlexuan_portal_web \webapp 下面

在这里插入图片描述
在这里插入图片描述
(2)在youlexuan_shop_web \webapp \ js文件夹拷贝 base.js 和 base_pagination.js 到 youlexuan_portal_web \webapp \ js下面,并在下面创建service 和controller文件夹

在这里插入图片描述

启动 sellerGoods-service,content_service,portal_web(根据前面创建即可)

在这里插入图片描述

访问: http://localhost:9103/index.html

在这里插入图片描述

3.3 后端代码

3.3.1 服务接口层

在youlexuan_content_interface 工程 ContentService 接口增加方法定义

/**
 * 根据广告类型ID查询列表
 * @param
 * @return
 */
public List<TbContent> findByCategoryId(Long categoryId);

3.3.2 服务实现层

在youlexuan_content_service工程 ContentServiceImpl类增加方法

//根据广告类型ID查询列表
public List<TbContent> findByCategoryId(Long categoryId){

	//根据广告分类ID查询广告列表
	TbContentExample tbContentExample = new TbContentExample();

	Criteria criteria = tbContentExample.createCriteria();

	criteria.andCategoryIdEqualTo(categoryId);

	criteria.andStatusEqualTo("1");//开启状态

	tbContentExample.setOrderByClause("sort_order");排序

	return contentMapper.selectByExample(tbContentExample);

}

3.3.3 控制层

在youlexuan_portal_web创建控制器类 ContentController

package com.zql.portal.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.zql.content.service.ContentService;
import com.zql.pojo.TbContent;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @Author:Daniel
 * @Version 1.0
 */

@RestController
@RequestMapping("/content")
public class ContentController {

    @Reference
    private ContentService contentService;
    //根据广告分类ID查询广告列表
    @RequestMapping("/findByCategoryId")
    public List<TbContent> findByCategoryId(Long categoryId){

        return contentService.findByCategoryId(categoryId);
    }
}

3.4 前端代码

3.4.1 服务层

在youlexuan_portal_web工程创建contentService.js

app.service("contentService",function($http){
    //根据分类ID查询广告列表
    this.findByCategoryId=function(categoryId){
        return $http.get("content/findByCategoryId.do?categoryId="+categoryId);
    }
});

3.4.2 控制层

在youlexuan_portal_web创建 contentController.js

//广告控制层(运营商后台)
app.controller("contentController",function($scope,contentService){

    $scope.findByCategoryId=function(categoryId){
        contentService.findByCategoryId(categoryId).success(
            function(response){
               $scope.list=response;
            }
        );
    }
});

3.4.3 页面

(1)修改youlexuan_portal_web工程的 index.html 引入JS,并在body上添加指令

<script type="text/javascript" src="plugins/angularjs/angular.min.js">  </script>
<script type="text/javascript" src="js/base.js">  </script>
<script type="text/javascript" src="js/service/contentService.js">  </script>
<script type="text/javascript" src="js/controller/contentController.js">  </script>
<body ng-app="youlexuan" ng-controller="contentController" ng-init="findByCategoryId(1)">

在这里插入图片描述

(2)修改首页轮播图(部分代码及截图)

<!--banner轮播-->
<div id="myCarousel" data-ride="carousel" data-interval="2000" class="sui-carousel slide">
  <ol class="carousel-indicators">
    <li data-target="#myCarousel"  data-slide-to="0" class="{{$index==0?'active':''}}" ng-repeat="item in list"></li>
  </ol>

  <div class="carousel-inner">
    <div class="{{$index==0?'active':''}} item" ng-repeat="item in list">
    <a href="{{item.url}}">
    	<img src="{{item.pic}}" style="width:730px;height:454px" />
      </a>
    </div>
  </div><a href="#myCarousel" data-slide="prev" class="carousel-control left"></a><a href="#myCarousel" data-slide="next" class="carousel-control right"></a>
</div>

在这里插入图片描述

最终显示: http://localhost:9103/index.html 即可看到首页效果

在这里插入图片描述

四、SpringDataRedis 简介

在这里插入图片描述

4.1 项目常见问题思考

我们目前的系统已经实现了广告后台管理和广告前台展示,但是对于首页每天有大量的人访问,对数据库造成很大的访问压力,甚至是瘫痪。那如何解决呢?

通常的做法有两种:

  1. 一种是数据缓存;
  2. 一种是网页静态化。

今天讨论第一种解决方案。

4.2 Redis

redis是一款开源的Key-Value数据库,运行在内存中,由ANSI C编写。企业开发通常采用Redis来实现缓存。同类的产品还有Memcache 、MongoDB等。

4.3 Jedis

Jedis是Redis官方推出的一款面向Java的客户端,提供了很多接口供Java语言调用。可以在Redis官网下载,当然还有一些开源爱好者提供的客户端,如Jredis、SRP等等,推荐使用Jedis。

4.4 Spring Data Redis

Spring-data-redis是spring大家族的一部分,提供了在spring应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅,并对spring 3.1 cache进行了实现。

spring-data-redis针对jedis提供了如下功能:

  1. 连接池自动管理,提供了一个高度封装的“RedisTemplate”类
  2. 针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口
ValueOperations:简单K-V操作

SetOperations:set类型数据操作

ZSetOperations:zset类型数据操作

HashOperations:针对map类型的数据操作

ListOperations:针对list类型的数据操作

4.5 Spring Data Redis入门小Demo

4.5.1准备工作

新建一台虚拟机安装Redis环境
(具体安装步骤参见 (六、Redis的安装和图形工具的连接))

(1)构建Maven工程 spring-data-redis

在这里插入图片描述
在这里插入图片描述
(2)引入Spring相关依赖、引入JUnit依赖
(3)引入Jedis和SpringDataRedis依赖

<properties>
   <spring.version>4.2.4.RELEASE</spring.version>
   <junit.version>4.12</junit.version>
</properties>
<dependencies>
   <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-test</artifactId>
       <version>${spring.version}</version>
   </dependency>
   <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <version>${junit.version}</version>
   </dependency>

   <!-- 缓存 -->
   <dependency>
       <groupId>redis.clients</groupId>
       <artifactId>jedis</artifactId>
       <version>2.8.1</version>
   </dependency>
   <dependency>
       <groupId>org.springframework.data</groupId>
       <artifactId>spring-data-redis</artifactId>
       <version>1.7.2.RELEASE</version>
   </dependency>
</dependencies>

(4)在src/main/resources下创建properties文件夹,建立redis_config.properties

redis.host=192.168.188.180
redis.port=6379
redis.pass=
redis.database=0
redis.maxIdle=300
redis.maxWait=3000
redis.testOnBorrow=true
redis.total=100

(5)在src/main/resources下创建spring文件夹 ,创建applicationContext_redis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 加载属性文件-->
    <context:property-placeholder location="classpath:properties/redis_config.properties"/>

    <!-- 配置redis连接池相关属性-->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="${redis.maxIdle}"/>
        <property name="maxWaitMillis" value="${redis.maxWait}"/>
        <property name="testOnBorrow" value="${redis.testOnBorrow}"/>
        <property name="maxTotal" value="${redis.total}"/>
    </bean>

    <!-- 配置redis连接工厂-->
    <bean id="RedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
        <property name="hostName" value="${redis.host}"/>
        <property name="port" value="${redis.port}"/>
        <property name="password" value="${redis.pass}"/>
        <property name="database" value="${redis.database}"/>
        <!--连接池的属性 -->
        <property name="poolConfig" ref="poolConfig"/>
    </bean>

    <!-- RedisTemplate-->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="RedisConnectionFactory"/>
    </bean>
</beans>
  • maxIdle :最大空闲数
  • maxWaitMillis:连接时的最大等待毫秒数
  • testOnBorrow:在提取一个jedis实例时,是否提前进行验证操作;如果为true,则得到的jedis实例均是可用的;

(6) 在 test / java 下创建 RedisTest.java 进行测试(搭建好测试看下面)

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @Author:Daniel
 * @Version 1.0
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/applicationContext-redis.xml")
public class RedisTest {

    @Autowired
    private RedisTemplate redisTemplate;

}

4.5.2 值类型操作

	//值类型操作
	@Test
	public void TestValue(){
	
	   redisTemplate.boundValueOps("age").set(23);
	}
	
	@Test
	public void getValue(){
	
	    int age = (int)redisTemplate.boundValueOps("age").get();
	
	    System.out.println(age);
	}
	
	@Test
	public void deleteValue(){
	
	    redisTemplate.delete("age");
	}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.5.3 Set 类型操作

	//Set 类型操作
    @Test
    public void TestSet(){

        redisTemplate.boundSetOps("nameSet").add("Daniel");

        redisTemplate.boundSetOps("nameSet").add("Amy");

        redisTemplate.boundSetOps("nameSet").add("Stella");

        redisTemplate.boundSetOps("nameset").add("Andy");

        redisTemplate.boundSetOps("nameSet").add("Nancy");


    }


    @Test
    public void getSet(){

        Set me = redisTemplate.boundSetOps("nameSet").members();

        System.out.println(me);
    }


    //删除某一个值
    @Test
    public void deleteSet(){

        redisTemplate.boundSetOps("nameSet").remove("Daniel");

    }

    //删除整个集合
    @Test
    public void deleSet(){

        redisTemplate.delete("nameSet");

    }

在这里插入图片描述
在这里插入图片描述

4.5.4 List类型操作

创建测试类TestList

(1)右压栈

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

/**
 * @Author:Daniel
 * @Version 1.0
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/applicationContext-redis.xml")
public class TestList {

        @Autowired
        private RedisTemplate redisTemplate;
        //右压栈:后添加的对象排在后边
        @Test
         public void  rightList(){

        redisTemplate.boundListOps("nameList").rightPush("Daniel");
        redisTemplate.boundListOps("nameList").rightPush("hollw");
        redisTemplate.boundListOps("nameList").rightPush("Jenny");
        redisTemplate.boundListOps("nameList").rightPush("Wendy");

    }


    //显示右压栈集合
    @Test
    public void rightGetList(){

        List nameList = redisTemplate.boundListOps("nameList").range(1, 10);

        System.out.println(nameList);
    }


    //左压栈:后添加的对象排在前边
    @Test
    public void leftList(){

            redisTemplate.boundListOps("aeg").leftPush("文树");
            redisTemplate.boundListOps("aeg").leftPush("上湾");
            redisTemplate.boundListOps("aeg").leftPush("下湾");
            redisTemplate.boundListOps("aeg").leftPush("街道");


    }

    //显示左压栈集合
    @Test
    public void leftGetList(){

        List aeg = redisTemplate.boundListOps("aeg").range(0, 10);

        System.out.println(aeg);
    }

    //(3)根据索引查询元素
    @Test
    public void listByIndex(){

        String aeg = (String)redisTemplate.boundListOps("aeg").index(2);

        System.out.println(aeg);
    }

    //(4)移除某个元素的值
    @Test
    public void removeB(){
            
        // 第一个参数 要删除元素的个数 (0全部删除) 第二个参数 元素值
        redisTemplate.boundListOps("aeg").remove(1,"Daniel");

    }

}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

4.5.5 Hash 类型操作

创建测试类 TestHash

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;
import java.util.Set;

/**
 * @Author:Daniel
 * @Version 1.0
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/applicationContext-redis.xml")
public class estHash {

    @Autowired
    private RedisTemplate redisTemplate;

    //存入值
    @Test
    public void setValue(){

        redisTemplate.boundHashOps("namHash").put("a","Daniel");
        redisTemplate.boundHashOps("namHash").put("b","Wendy");
        redisTemplate.boundHashOps("namHash").put("c","Kendra");
        redisTemplate.boundHashOps("namHash").put("d","GuoGuo");
        redisTemplate.boundHashOps("namHash").put("e","Jhowll");

    }

    //提取所有的KEY
    @Test
    public void  getKey(){

        Set namHash = redisTemplate.boundHashOps("namHash").keys();

        System.out.println(namHash);
    }

    //提取所有的值
    @Test
    public void getValue(){

        List namHash = redisTemplate.boundHashOps("namHash").values();

        System.out.println(namHash);

    }

    //(4)根据KEY提取值
    @Test
    public void getValueByKey(){

        String o = (String)redisTemplate.boundHashOps("namHash").get("d");

        System.out.println(o);
    }

    //(5)根据KEY移除值
    @Test
    public void removeValueByKey(){

        redisTemplate.boundHashOps("namHash").delete("c");
    }
}

(1)存入值
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

案例结构

在这里插入图片描述

上述所有案例至 redis 源码

五、网站首页-缓存广告数据

5.1 需求分析

现在我们首页的广告每次都是从数据库读取,这样当网站访问量达到高峰时段,对数据库压力很大,并且影响执行效率。我们需要将这部分广告数据缓存起来。

5.2 读取缓存

5.2.1 公共组件层

因为缓存对于我们整个的系统来说是通用功能。广告需要用,其它数据可能也会用到,所以我们将配置放在公共组件层(youlexuan_common)中较为合理。

(1)youlexuan_common 引入依赖

<!-- 缓存 -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
</dependency>

(2)创建配置文件

资源 中的 redis_config.properties 和applicationContext-redis.xml 拷贝至youlexuan-common
注意:applicationContext-redis.xml 不需要再加载属性配置文件。

在这里插入图片描述

(3)youlexuan_content_service 依赖 youlexuan_common(注:pom中应该已有)

5.2.2后端服务实现层

修改 youlexuan_content_service的 ContentServiceImpl

@Autowired
private RedisTemplate redisTemplate;

//根据广告类型ID查询列表
public List<TbContent> findByCategoryId(Long categoryId){

	List<TbContent> contentList = (List<TbContent>)redisTemplate.boundHashOps("content").get(categoryId);

	if(contentList != null){

		return contentList;
	}
	//根据广告分类ID查询广告列表
	TbContentExample tbContentExample = new TbContentExample();

	Criteria criteria = tbContentExample.createCriteria();

	criteria.andCategoryIdEqualTo(categoryId);

	criteria.andStatusEqualTo("1");//开启状态

	tbContentExample.setOrderByClause("sort_order");排序

	contentList = contentMapper.selectByExample(tbContentExample);

	redisTemplate.boundHashOps("content").put(categoryId,contentList);//存入缓存

	return contentList;

}

在这里插入图片描述
在这里插入图片描述

5.3 更新缓存

当广告数据发生变更时,需要将缓存数据清除,这样再次查询才能获取最新的数据

5.3.1 新增广告后清除缓存

修改youlexuan_content_service工程ContentServiceImpl.java 的add方法

/**
 * 增加
 */
@Override
public void add(TbContent content) {

	//清除缓存
	redisTemplate.boundHashOps("content").delete(content.getCategoryId());

	contentMapper.insert(content);		
}

在这里插入图片描述

5.3.2 修改广告后清除缓存

考虑到用户可能会修改广告的分类,这样需要把原分类的缓存和新分类的缓存都清除掉。

/**
 * 修改
 */
@Override
public void update(TbContent content){

	//查询修改前的分类Id
	Long categoryId = contentMapper.selectByPrimaryKey(content.getId()).getCategoryId();

	redisTemplate.boundHashOps("content").delete(categoryId);

	contentMapper.updateByPrimaryKey(content);

	//如果分类ID发生了修改,清除修改后的分类ID的缓存
	if(categoryId.longValue() != content.getCategoryId().longValue()){

		redisTemplate.boundHashOps("content").delete(content.getCategoryId());
	}
}

在这里插入图片描述

5.3.3 删除广告后清除缓存

/**
 * 批量删除
 */
@Override
public void delete(Long[] ids) {
	for(Long id:ids){
		//清除缓存
		Long categoryId = contentMapper.selectByPrimaryKey(id).getCategoryId();//广告分类ID

		redisTemplate.boundHashOps("content").delete(categoryId);

		contentMapper.deleteByPrimaryKey(id);
	}
	
}

在这里插入图片描述
(1) 测试:清除 redis 工具缓存

在这里插入图片描述

(2)安装 youlexuan_common,启动 content_service,portal_web

浏览器访问: http://localhost:9103/index.html 已存入下列redis中了,再次访问变得相对快了很多!

在这里插入图片描述

当前 youlexuan 所有完整代码

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Daniel521-Spark

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值