Spring-boot整合redis

  1. 学习redis做的小demo

1.1 demo具体功能

  1. 显示所有数据时,先查询redis是否有缓存,没有缓存则查看数据库,有缓存则显示缓存中的内容

  1. 搜索数据时,先查询redis是否有搜索的key,没有。。。,有。。。同上

  1. 删除和修改商品成功后,要删除redis中所有数据的缓存及所有搜索数据的缓存

纯属个人学习做的小demo,大佬勿喷。

  1. 界面

2.1 数据展示

2.2 搜索数据

2.3 删除/修改

  1. 代码块

3.1 sql

3.2 entity

import lombok.Data;

@Data
public class Shop {
    private int shop_id;
    private String shop_name;
    private double shop_price;
}

3.3 service

import java.util.List;

public interface ShopService {
    List<Shop> getAllShop();

    List<Shop> queryShopByName(String shop_name);

    int deleteShop(int shop_id);

    int updateShop(int shop_id,String shop_name,double shop_price);
}

3.4 mapper

import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface ShopMapper {
    List<Shop> getAllShop();

    List<Shop> queryShopByName(String shop_name);

    int deleteShop(int shop_id);

    int updateShop(int shop_id,String shop_name,double shop_price);
}

3.5 serviceImpl

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

import java.util.List;


@Service
public class ShopServiceImpl implements ShopService {

    @Autowired
    ShopMapper shopMapper;

    @Override
    public List<Shop> getAllShop() {
        return shopMapper.getAllShop();
    }

    @Override
    public List<Shop> queryShopByName(String shop_name) {
        return shopMapper.queryShopByName(shop_name);
    }

    @Override
    public int deleteShop(int shop_id) {
        return shopMapper.deleteShop(shop_id);
    }

    @Override
    public int updateShop(int shop_id, String shop_name, double shop_price) {
        return shopMapper.updateShop(shop_id,shop_name,shop_price);
    }

}

3.6 mapper.xml。namespace需要修改为自己的包名地址

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wjh.redis.mapper.ShopMapper">
    <resultMap id="ShopMap" type="com.wjh.redis.entity.Shop">
        <id property="shop_id" column="shop_id"/>
        <result property="shop_name" column="shop_name"/>
        <result property="shop_price" column="shop_price"/>
    </resultMap>
    <select id="getAllShop" resultMap="ShopMap">
        select shop_id,shop_name,shop_price from shop;
    </select>

    <select id="queryShopByName" resultType="com.wjh.redis.entity.Shop" parameterType="string">
        select shop_id,shop_name,shop_price from shop where shop_name like CONCAT('%',#{shop_name},'%')
    </select>

    <delete id="deleteShop" parameterType="com.wjh.redis.entity.Shop">
        delete from shop where shop_id=#{shop_id}
    </delete>

    <update id="updateShop" parameterType="com.wjh.redis.entity.Shop">
        update shop set shop_name=#{shop_name},shop_price=#{shop_price} where shop_id=#{shop_id}
    </update>
</mapper>

3.7 redisConfig 在操作所有redis中,关于对象的保存我们得序列化才能正常操作

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * 在操作所有redis中,关于对象的保存我们得序列化才能正常操作
 *
 * 自定义封装RedisTemplate类
 */
@Configuration
public class RedisConfig {
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        //json序列化配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        //String的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        //hash的key也采用了序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        //value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //hash的value序列化采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

3.8 redis工具类

@Component
public class RedisUtils {

 @Resource
    private RedisTemplate<String, Object> redisTemplate;

  /**
     * 普通获取缓存
     *
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

     /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true 成功 false 失败
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

     /**
     * HashGet
     * @param key 键 不能为null
     * @param item 项 不能为null
     * @return 值
     */
    public Object hget(String key,String item){
        return redisTemplate.opsForHash().get(key,item);
    }
    
     /**
     * 向一张hash表中放入数据,如果不存在将创建
     * @param  key 键
     * @param  item 项
     * @param  value 值
     * @return true 成功 false 失败
     */
    public boolean hset(String key,String item,Object value){
        try {
            redisTemplate.opsForHash().put(key,item,value);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

   /**
     * 删除缓存
     *
     * @param key 可以传一个值或多个
     */
    @SuppressWarnings("unchecked")
    public boolean del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
                return true;
            } else {
                redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
            }
        }
        return false;
    }
}

3.9 controller log是当时为了校验打的。可以不写

import com.wjh.redis.entity.Shop;
import com.wjh.redis.redisUtils.RedisUtils;
import com.wjh.redis.service.ShopService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.logging.Logger;

@RestController
public class ShopController {
    private static String name = ShopController.class.getName();
    private static Logger log = Logger.getLogger(name);
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    ShopService shopService;

    //获取所有商品
    @RequestMapping(value = "/getAllShop")
    public List<Shop> queryAllShop() {
        List<Shop> shops = (List<Shop>) redisUtils.get("allShops");
        if (CollectionUtils.isEmpty(shops)) {
            shops = shopService.getAllShop();
            redisUtils.set("allShops", shops);
            System.out.println("shops内容:"+shops);
            log.info("商品数据添加到redis缓存中成功!");
        } else {
            log.info("redis中已存在商品数据");
        }
        return shops;
    }

    //根据名称查找商品
    @RequestMapping(value = "/queryShopByName", method = RequestMethod.GET)
    public List<Shop> queryShopByName(String shop_name) {
        log.info("正在查询redis中是否有该缓存?");
        List<Shop> list = (List<Shop>) redisUtils.hget("myQuery", shop_name);
        if (CollectionUtils.isEmpty(list)) {
            log.info("redis缓存中没有" + shop_name);
            log.info("即将查看数据库");
            list = shopService.queryShopByName(shop_name);
            if(list.size() == 0){
                log.info("数据库暂未此商品");
            }else{
                redisUtils.hset("myQuery", shop_name, list);
                log.info("redis添加" + shop_name + "成功");
            }
        } else {
            log.info("redis缓存中有" + shop_name + ",获取缓存中的内容");
        }
        return list;
    }

    @RequestMapping(value = "/deleteShop")
    public String deleteShop(int shop_id) {
        String message = null;
        shopService.deleteShop(shop_id);
        log.info("删除id为:" + shop_id + "的商品成功");
        boolean redis = redisUtils.del("allShops");
        boolean redis2 = redisUtils.del("myQuery");
        if (redis && redis2) {
            message = "success";
        } else {
            log.warning("删除缓存失败");
            message = "fail";
        }
        return message;
    }

    //会有数据库内容更改了,redis缓存删除失败的情况,如果返回fail,则让用户决定是否重新删除
    @RequestMapping(value = "/restartClearRedisCache")
    public String clearCache() {
        boolean flag = redisUtils.del("allShops");
        boolean flag2 = redisUtils.del("myQuery");
        String message = null;
        if (flag && flag2) {
            message = "success";
            log.info("重新清空redis商品数据缓存成功!");
        } else {
            message = "fail";
            log.warning("重新清空redis商品数据缓存失败!");
        }
        return message;
    }

    @RequestMapping(value = "/updateShop")
    public void updateShop(int shop_id, String shop_name, double shop_price) {
        shopService.updateShop(shop_id, shop_name, shop_price);
        log.info("修改id为:" + shop_id + "的商品成功");
        log.info("需删除商品数据的缓存。");
        redisUtils.del("allShops");
        log.info("删除所有商品缓存成功");
        redisUtils.del("myQuery");
        log.info("删除搜索商品缓存成功");
    }
}

3.10 显示所有商品、删除、修改.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Redis Test</title>
    <script src="https://cdn.staticfile.org/jquery/2.0.0/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css">
</head>
<style>
    .black_overlay {
        display: none; /* 此元素不会被显示*/
        position: absolute;
        top: 0%;
        left: 0%;
        width: 100%;
        height: 100%;
        background-color: black;
        z-index: 1001; /* z-index 属性设置元素的堆叠顺序。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。*/
        -moz-opacity: 0.8;
        opacity: .80; /* opacity 属性设置元素的不透明级别。*/
        filter: alpha(opacity=88);
        /* 所有浏览器都支持 opacity 属性。   注释:IE8 以及更早的版本支持替代的 filter 属性。例如:filter:Alpha(opacity=50)。*/
    }

    .white_content {
        display: none;
        position: absolute;
        top: 25%;
        left: 25%;
        width: 430px;
        height: 550px;
        padding: 20px;
        border: 10px solid orange;
        background-color: white;
        z-index: 1002;
        overflow: auto;
    }
</style>
<body onload="queryShop()">
<script>
    //显示所有商品信息
    function queryShop() {
        $(document).ready(function () {
            var shopData = $("#shopData");
            $.ajax({
                url: "/getAllShop",
                type: "get",
                dataType: "json",
                async: true,
                success: function (result) {
                    var shops = result;
                    shopData.empty();
                    for (var i = 0; i < shops.length; i++) {
                        var shopTemp =
                            '<tr class="shop_td">' +
                            '<td>' + shops[i].shop_id + '</td>' +
                            '<td>' + shops[i].shop_name + '</td>' +
                            '<td>' + shops[i].shop_price + '</td>' +
                            '<td style="width:130px;height:20px;">' +
                            '<button type="button" onclick="deleteShop(' + shops[i].shop_id + ')">删除</button>' +
                            '<button type="button" onclick="updateShopDiv(' + shops[i].shop_id + ')">修改</button>' +
                            '</td>' +
                            '</tr>'
                        shopData.append(shopTemp);
                    }
                }
            });
        });
    }

    function deleteShop(shop_id) {
        var flag = confirm("确定删除id为" + shop_id + "的商品吗?");
        if (flag) {
            $.ajax({
                url: "/deleteShop",
                data: {
                    "shop_id": shop_id
                },
                success: function (data) {
                    console.log("检查redis缓存是否删除成功,打印信息:"+data);
                    if (data == "success") {
                        alert("删除商品数据成功,清空商品缓存数据成功。");
                        queryShop();
                    } else if (data == "fail") {
                        while (true) {
                            var flag = confirm("删除商品数据成功,清空redis商品缓存失败,是否重新清空redis缓存?");
                            if (flag) {
                                $.ajax({
                                    url: "/restartClearRedisCache",
                                    success: function (data) {
                                        if (data == "success") {
                                            alert("重新删除缓存成功");
                                            queryShop();
                                            return false; //在java中相当于 break;
                                        }else{
                                            return true; //在java中相当于 continue;
                                        }
                                    }
                                });
                            }
                        }
                    }
                },
                error: function () {
                    alert("删除商品请求失败!");
                }
            });
        }
    }

    var shopId;

    function updateShopDiv(shop_id) {
        shopId = shop_id;
        document.getElementById('light').style.display = 'block';
        document.getElementById('fade').style.display = 'block';
        $(".shop_id")[0].innerHTML = "商品id:" + shop_id;
    }

    function updateShop() {
        var shop_name = $(".newShop_name").val();
        var shop_price = $(".newShop_price").val();
        if (shop_name == "") {
            alert("商品名称不能为空");
        } else if (shop_price == "") {
            alert("商品价格不能为空");
        } else {
            $.ajax({
                url: "/updateShop",
                data: {
                    "shop_id": shopId,
                    "shop_name": shop_name,
                    "shop_price": shop_price
                },
                success: function () {
                    alert("修改商品成功,删除redis中商品数据缓存");
                    document.getElementById('light').style.display = 'none';
                    document.getElementById('fade').style.display = 'none';
                    queryShop();
                },
                error: function () {
                    alert("修改商品请求失败!");
                }
            });
        }
    }

    function queryShopByName() {
        var shop_name = $("#shop_name").val();
        if (shop_name == "") {
            alert("搜索框不能为空!");
        } else {
            window.open("queryShop.html?" + shop_name);
        }
    }

</script>
<div style="text-align: center">
    <p style="font-size: 30px">商品列表</p>
</div>
<div style="text-align: center">
    <input style="width: 300px;height: 30px;" type="text" id="shop_name" placeholder="输入要搜索的商品名称或关键词"
           onkeydown="if(event.key=='Enter')queryShopByName()"/>
    <button style="width: 80px;height: 30px;" class="btn_search" id="search" onclick="queryShopByName()">搜索</button>
</div>
<br>
<div class="container">
    <div class="row clearfix">
        <div class="col-md-12 column">
            <table class="table table-hover table-striped">
                <thead>
                <tr>
                    <th style="font-size: 15px">商品ID</th>
                    <th style="font-size: 15px">商品名称</th>
                    <th style="font-size: 15px">商品价格¥</th>
                    <th style="font-size: 15px">操作</th>
                </tr>
                </thead>
                <tbody id="shopData">

                </tbody>
            </table>
        </div>
    </div>
</div>
<!--更改绑定手机号DIV-->
<div id="light" class="white_content" style="text-align: center;margin-left: 270px">
    <div style="text-align: center">
        <p style="font-size: 30px">修改商品</p>
        <p style="font-size: 15px" class="shop_id"></p>
        <br>
        <p style="font-size: 20px">商品名称:&nbsp<input style="width: 230px;height: 30px;" type="text"
                                                    class="newShop_name" placeholder="input new shopName"/></p>
        <br><br>
        <p style="font-size: 20px">商品价格&nbsp<input style="width: 230px;height: 30px;" type="text"
                                                   class="newShop_price" placeholder="input new shopPrice"/></p>
        <br><br>
        <button style="margin-top: 70px;width: 80px;height: 45px" onclick="updateShop()">修改</button>
        &nbsp;&nbsp;&nbsp;&nbsp;
        <button style="margin-top: 70px;width: 80px;height: 45px"
                onclick="document.getElementById('light').style.display='none';document.getElementById('fade').style.display='none'">
            取消
        </button>
        </br>
    </div>
</div>
<div id="fade" class="black_overlay"></div>
</body>
</html>

3.11 搜索数据.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>搜索结果</title>
    <script src="https://cdn.staticfile.org/jquery/2.0.0/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<script>
    var url = decodeURI(location.href);
    //截取url中?后面登录的用户名
    var num = url.indexOf("?");
    var shop_name = url.substr(num + 1);
    console.log(shop_name);
    function queryShopByShopName() {
        var i;
        $(document).ready(function () {
            var shop = $("#shop")
            var shopTemp = '';
            $.ajax({
                url: "/queryShopByName",
                type: "get",
                dataType: "json",
                data: {
                    "shop_name": shop_name
                },
                async: true,
                success: function (result) {
                    var shops = result;
                    shop.empty();
                    for (i = 0; i < shops.length; i++) {
                        shopTemp =
                            '<tr>' +
                            '<td id="shop_id">' + shops[i].shop_id + '</td>' +
                            '<td id="shop_name">' + shops[i].shop_name + '</td>' +
                            '<td id="shop_price">' + shops[i].shop_price + '</td>' +
                            '</tr>'
                        shop.append(shopTemp);
                    }
                    $(".resultNums")[0].innerHTML = "搜索结果数:"+i;
                }
            });
        });
    }
</script>
<body onload="queryShopByShopName()">
<div style="text-align: center">
    <p style="font-size: 30px">搜索结果</p>
</div>
<div class="container">
    <div class="row clearfix">
        <div class="col-md-12 column">
            <table class="table table-hover table-striped">
                <thead>
                <p class="resultNums" style="font-size: 20px;color: green"></p>
                <tr>
                    <th style="font-size: 15px;">商品ID</th>
                    <th style="font-size: 15px;">商品价格¥</th>
                    <th style="font-size: 15px;">商品价格</th>
                </tr>
                </thead>
                <tbody id="shop">

                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值