京淘项目学习09

1. Redis

1.1 Redis入门案例

1.1.1 导入jar包依赖

 <!--spring整合redis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
        </dependency>

1.1.2 在test包下创建测试类以及相关测试方法

1.运行测试

public class RedisTest {
    /**
     *  如果报错:
     *      1. 防火墙
     *      2. redis配置文件 3处
     *      3. redis启动方式:redis-server redis.conf
     */
    @Test
    public void testString(){
        String host = "192.168.126.129";
        /*
        * 默认端口号:
        * 8066:mycat
        * 3306:mybatis
        * 6379:redis
        * 80:nginx
        * */
        int port = 6379;
        Jedis jedis = new Jedis(host,port);
        jedis.set("redis", "你好Redis");
        System.out.println
                ("获取redis中的数据:"+jedis.get("redis"));
    }

2.判断数据是否存在,如果存在 则删除,不存在 则赋值

@Test
    public void test01(){
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        if(jedis.exists("redis")){
            jedis.del("redis");
            System.out.println("已删除");
        }else{
            jedis.set("hello", "你好Redis");
            System.out.println(jedis.get("hello"));
        }

    }

3.如果数据存在 则不做任何操作,如果数据不存在,则赋值

@Test
    public void test02(){
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        jedis.flushAll();
       // jedis.set("redis", "aaa");
        jedis.setnx("redis", "bbb");
        System.out.println(jedis.get("redis"));

    }

4.添加数据,并且设定超时时间 10s

/*
        存在bug问题:如果在超时时间内发生意外情况,数据会一直存在
            设定超时时间,应该注意原子性(atomic)问题
     */
    @Test
    public void test03() throws InterruptedException {
        Jedis jedis = new Jedis("192.168.126.129", 6379);
//        jedis.set("a", "设定超时时间");
//        jedis.expire("a", 10);
        jedis.setex("a", 10, "设定超时时间");
        Thread.sleep(2000);
        System.out.println("剩余时间:"+jedis.ttl("a")+"秒");

    }

5.如果数据存在,则不修改,反之修改,同时设定超时10s,并且为原子性操作

 @Test
    public void test04(){
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        SetParams setParams = new SetParams();
        setParams.nx().ex(10);
        jedis.set("b", "赋值操作", setParams);
        System.out.println(jedis.get("b")+","+"剩余时间:"+jedis.ttl("b")+"秒");

    }

1.2 Springboot整合redis

1.2.1 配置公共的redis配置文件

redis.host=192.168.126.129
redis.port=6379
在这里插入图片描述

1.2.2 编辑配置类

在这里插入图片描述

@Configuration  //标识该类为配置类 一般和@Bean注解联用
@PropertySource("classpath:/redis.properties")
public class RedisConfig {

    @Value("${redis.host}")
    private String host;

    @Value("${redis.port}")
    private Integer port;
    
    @Bean
    public Jedis jedis(){
        return new Jedis(host,port);
    }

}

1.2.3 启动测试类测试

@SpringBootTest(classes = RedisConfig.class)
public class RedisTest {

    @Autowired
    private Jedis jedis;
    @Test
    public void testRedis(){
        //利用容器动态获取对象之后操作redis
        jedis.set("redis", "整合测试");
        System.out.println(jedis.get("redis"));
    }
}

在这里插入图片描述

1.3 Json对象转化API——ObjectMapper

public class TestObjectMapper {
    /**
     *
     * 1.   通过测试类 实现对象与Json之间的转化
     *
     * */
    @Test
    public void test01() throws JsonProcessingException {
        ItemDesc itemDesc = new ItemDesc();
        itemDesc.setItemId(100L).setItemDesc("转化测试");
        ObjectMapper objectMapper = new ObjectMapper();
        //将对象转化为Json
        String json = objectMapper.writeValueAsString(itemDesc);
        System.out.println(json);
        //将Json转化为对象
        ItemDesc itemDesc2 = objectMapper.readValue(json, ItemDesc.class);
        System.out.println(itemDesc2);
    }


}

在这里插入图片描述

1.4 封装ObjectMapperUtil

public class ObjectMapperUtil {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    //将对象转化为Json
    public static String toJson(Object obj){
        try {
            return MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            //将检查异常,转化为运行时异常 之后被全局异常处理机制捕获处理
            e.printStackTrace();//或者日志打印...
            throw new RuntimeException(e);
        }

    }

    //将Json转化为对象    用户指定什么样的类型,返回什么样的对象——使用泛型
    public static <T> T toObj(String json,Class<T> target){
        try {
          return MAPPER.readValue(json, target);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

    }
}

在这里插入图片描述

  • 调用封装工具类,实现对象转Json,Json转对象
public class TestObjectMapper {

    /**
    *   调用封装工具类,实现对象转Json,Json转对象
    * */
    @Test
    public void testObject(){
        ItemDesc itemDesc = new ItemDesc().setItemId(100L).setItemDesc("aaa");
        String json = ObjectMapperUtil.toJson(itemDesc);
        System.out.println(json);
        ItemDesc itemDesc1 = ObjectMapperUtil.toObj(json, ItemDesc.class);
        System.out.println(itemDesc1);
    }
}

在这里插入图片描述

2. 商品分类缓存的实现

在这里插入图片描述

2.1 在controller层改写控制方法

    @RequestMapping("list")
    public List<EasyUITree> findItemCatLost(Long id){
       /*
        long parentId = (id==null?0:id);
        return itemCatService.findItemCatList(parentId);
        */
        long parentId = (id==null?0:id);
        return itemCatService.findItemCatCache(parentId);
    }

在这里插入图片描述

2.2 在service层编译具体代码实现

/**
     * 缓存处理业务逻辑:
     *  1.第一次查询先查缓存
     *  2.结果:
     *      有结果:说明用户不是第一次查,直接从缓存中获取数据
     *      无结果: 说明用户是第一次查询,先查询数据库,保存到缓存中
     *  3.Redis.set(key,value):
     *      key:parentId
     *      value:
     * @param parentId
     * @return
     */
@Override
    public List<EasyUITree> findItemCatCache(long parentId) {
        Long startTime = System.currentTimeMillis();
        String key = "ITEM_CAT_PARENTID::"+parentId;
        List<EasyUITree> treeList = new ArrayList<>();
        if(jedis.exists(key)){
            //数据存在
            String json = jedis.get(key);
            treeList = ObjectMapperUtil.toObj(json, treeList.getClass());
            Long endTime = System.currentTimeMillis();
            System.out.println("查询缓存的时间:"+(endTime-startTime)+"毫秒");

        }else {
            //表示数据不存在,需要查询数据库
            treeList = findItemCatList(parentId);
            //将结果保存到缓存中
            String json = ObjectMapperUtil.toJson(treeList);
            jedis.set(key,json);
            Long endTime = System.currentTimeMillis();
            System.out.println("查询数据库的时间:"+(endTime-startTime)+"毫秒");
        }
        return treeList;
    }

在这里插入图片描述

3. AOP实现商品分类缓存

3.1 为什么使用AOP?

  • 将缓存代码直接写到业务中,只对某个业务有效,如果其他业务需要缓存,则需要重新编译
  • 如果将缓存代码直接写死在业务层,如果后期代码需要更新,代码耦合性太高,不便于扩展

3.2 AOP作用

1.面向切面编程,一种设计思想,是对面向对象编程的补充和完善。
2.在不改变原有代码的条件下,对方法进行额外的功能扩展。
3.AOP构造要素= 切入点表达式+通知方法

3.3 常见切入点表达式

1.Bean(“bean的Id”) – 默认是类变量名首字母小写
2.within(“包名.类名”)
3.execution(“返回值类型 包名.类名.方法名(参数列表)”)
4.annotation(“包名.注解名")

3.4 通知方法

  1. before 目标方法执行前执行

  2. afterReturning 目标方法成功执行后执行

  3. afterThrowing 目标方法异常执行时执行

  4. after 程序最后执行
    上述四大通知类型一般用来记录程序的执行状态,为监控系统提供数据的支持,只监控不处理

  5. around 目标方法执行前后都要执行
    环绕通知是通知类型中功能最强大的,可以控制目标方法是否执行(控制业务是否操作)

3.5 AOP简单案例

  • 恢复controller
    在这里插入图片描述
  • service层设置属性
    在这里插入图片描述
  • 编写AOP入门方法
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_Solider

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

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

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

打赏作者

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

抵扣说明:

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

余额充值