2006-Beijing Amoy Day12

1. Caso de entrada de Redis

1.1 Uso común de Redis

1.1.1 aprendizaje setex

/**
     * 2.需求:
     *      1.向redis中插入数据  k-v
     *      2.为key设定超时时间  60秒后失效.
     *      3.线程sleep 3秒
     *      4.获取key的剩余的存活时间.
     *
     *   问题描述: 数据一定会被删除吗??????
     *   问题说明: 如果使用redis 并且需要添加超时时间时 一般需要满足原子性要求.
     *   原子性:   操作时要么成功 要么失败.但是必须同时完成.
     */
    @Test
    public void test02() throws InterruptedException {
    
    
        Jedis jedis = new Jedis("192.168.126.129",6379);
        jedis.setex("宝可梦", 60, "小火龙 妙蛙种子");
        System.out.println(jedis.get("宝可梦"));

       /* Jedis jedis = new Jedis("192.168.126.129",6379);
        jedis.set("宝可梦", "小火龙 妙蛙种子");
        int a = 1/0;    //可能会出异常
        jedis.expire("宝可梦", 60);
        Thread.sleep(3000);
        System.out.println(jedis.ttl("宝可梦"));*/
    }

1.1.2 setnx

/**
     * 3.需求如果发现key已经存在时 不修改数据.如果key不存在时才会修改数据.
     *
     */
    @Test
    public void test03() throws InterruptedException {
    
    
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        jedis.setnx("aaaa", "测试nx的方法");
        /*if(jedis.exists("aaa")){
            System.out.println("key已经存在 不做修改");
        }else {
            jedis.set("aaa", "测试数据");
        }*/
        System.out.println(jedis.get("aaaa"));
    }

1.1.3 establecer operación atómica de tiempo de espera

 /**
     * 需求:
     *  1.要求用户赋值时,如果数据存在则不赋值.  setnx
     *  2.要求在赋值操作时,必须设定超时的时间 并且要求满足原子性 setex
     */
    @Test
    public void test04() throws InterruptedException {
    
    
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        SetParams setParams = new SetParams();
        setParams.nx().ex(20);
        jedis.set("bbbb", "实现业务操作AAAA", setParams);
        System.out.println(jedis.get("bbbb"));


    }

1.1.4 Ejercicio de recopilación de listas

  @Test
    public void testList() throws InterruptedException {
    
    
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        jedis.lpush("list", "1","2","3");
        System.out.println(jedis.rpop("list"));
    }

1.1.5 Control de transacciones de Redis

 @Test
    public void testTx() throws InterruptedException {
    
    
        Jedis jedis = new Jedis("192.168.126.129", 6379);
        //1.开启事务
        Transaction transaction = jedis.multi();
        try {
    
    
            transaction.set("aa", "aa");
            //提交事务
            transaction.exec();
        }catch (Exception e){
    
    
            e.printStackTrace();
            //回滚事务
            transaction.discard();
        }
    }

2. Mecanismo de bloqueo distribuido por lógica empresarial de Spike

6988: 1 pieza de 1 teléfono móvil 20 muestra que la compra se realizó correctamente y se pagó 1 yuan ...
Preguntas:
1. Hay varios servidores Tomcat
2. Solo hay una base de datos
3. Habrá un fenómeno de alta concurrencia.
Cómo lograr una compra de pánico ...

2.1 Operación de bloqueo convencional

2.1.1 Razones de la sobreventa

Inserte la descripción de la imagen aquí

2.1.2 El problema de los bloqueos de sincronización

Descripción: el bloqueo de sincronización solo puede resolver problemas internos de tomcat y no puede resolver múltiples problemas de concurrencia de tomcat
Inserte la descripción de la imagen aquí

2.1.3 Mecanismo de bloqueo distribuido

Idea:
1. La cerradura debe ser operada por un tercero y la cerradura debe ser pública.
2. Principio: Si se está usando la cerradura, otros usuarios no pueden operarla.
3. Estrategia: El usuario guarda una llave en redis, si hay una llave en redis Significa que alguien está usando esta cerradura y otros usuarios no pueden operar. Si no hay una llave en redis, significa que puedo usar esta cerradura.
4. Riesgo: Cómo resolver el problema del interbloqueo. Establecer el tiempo de espera.
Inserte la descripción de la imagen aquí

3. SpringBoot integra Redis

3.1 Edite el archivo de configuración redis.pro

Nota: Dado que otros proyectos utilizan esta configuración, debe escribirse en jt-common.
Inserte la descripción de la imagen aquí

3.2 Editar clase de configuración

Descripción: Edite la clase de configuración de redis. Entregue el objeto Jedis al contenedor Spring para su administración.

@Configuration
@PropertySource("classpath:/properties/redis.properties")
public class JedisConfig {
    
    

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

    @Bean
    public Jedis jedis(){
    
    

        return new Jedis(host,port);
    }
}

3.3 Introducción a ObjectMapper de conversión de objetos y JSON

3.3.1 Conversión de objeto simple

/**
     * 测试简单对象的转化
     */
    @Test
    public void test01() throws JsonProcessingException {
    
    
        ObjectMapper objectMapper = new ObjectMapper();
        ItemDesc itemDesc = new ItemDesc();
        itemDesc.setItemId(100L).setItemDesc("商品详情信息")
                .setCreated(new Date()).setUpdated(new Date());
        //对象转化为json
        String json = objectMapper.writeValueAsString(itemDesc);
        System.out.println(json);

        //json转化为对象
        ItemDesc itemDesc2 = objectMapper.readValue(json, ItemDesc.class);
        System.out.println(itemDesc2.getItemDesc());
    }

3.3.2 Conversión de objetos de colección

 /**
     * 测试集合对象的转化
     */
    @Test
    public void test02() throws JsonProcessingException {
    
    
        ObjectMapper objectMapper = new ObjectMapper();
        ItemDesc itemDesc = new ItemDesc();
        itemDesc.setItemId(100L).setItemDesc("商品详情信息1")
                .setCreated(new Date()).setUpdated(new Date());
        ItemDesc itemDesc2 = new ItemDesc();
        itemDesc2.setItemId(100L).setItemDesc("商品详情信息2")
                .setCreated(new Date()).setUpdated(new Date());
        List<ItemDesc> lists = new ArrayList<>();
        lists.add(itemDesc);
        lists.add(itemDesc2);
        //[{key:value},{}]
        String json = objectMapper.writeValueAsString(lists);
        System.out.println(json);

        //将json串转化为对象
        List<ItemDesc> list2 = objectMapper.readValue(json, lists.getClass());
        System.out.println(list2);
    }

3.4 Editar API de herramienta

package com.jt.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jt.pojo.ItemDesc;
import org.springframework.util.StringUtils;

public class ObjectMapperUtil {
    
    

    /**
     * 1.将用户传递的数据转化为json串
     * 2.将用户传递的json串转化为对象
     */
    private static final ObjectMapper MAPPER = new ObjectMapper();

     //1.将用户传递的数据转化为json串
    public static String toJSON(Object object){
    
    

        if(object == null) {
    
    
            throw new RuntimeException("传递的数据为null.请检查");
        }

        try {
    
    
            String json = MAPPER.writeValueAsString(object);
            return json;
        } catch (JsonProcessingException e) {
    
    
            //将检查异常,转化为运行时异常
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    //需求: 要求用户传递什么样的类型,我返回什么样的对象  泛型的知识
    public static <T> T toObj(String json,Class<T> target){
    
    
        if(StringUtils.isEmpty(json) || target ==null){
    
    
            throw new RuntimeException("参数不能为null");
        }
        try {
    
    
           return  MAPPER.readValue(json, target);
        } catch (JsonProcessingException e) {
    
    
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}

3.5 Implementación de caché de la clasificación de productos básicos

3.5.1 Pasos de implementación

1. Defina la clave en Redis. La clave debe ser única y no puede repetirse. Clave de acceso = "ITEM_CAT_PARENTID :: 70"
2. Según la clave, vaya a redis para consultar. No hay datos
. 3. Si no hay datos, consulte la base de datos para obtener el registro y guardar los datos en Es conveniente para su uso posterior en redis
4. Hay datos que indican que el usuario puede devolver directamente los datos en caché si no es la primera consulta.

3.5.2 Editar ItemCatController

Inserte la descripción de la imagen aquí

3.5.3 Editar ItemCatService

@Override
    public List<EasyUITree> findItemCatListCache(Long parentId) {
    
    
        //0.定义公共的返回值对象
        List<EasyUITree> treeList = new ArrayList<>();
        //1.定义key
        String key = "ITEM_CAT_PARENTID::"+parentId;
        //2.检索redis服务器,是否含有该key

        //记录时间
        Long startTime = System.currentTimeMillis();
        if(jedis.exists(key)){
    
    
            //数据存在
            String json = jedis.get(key);
            Long endTime = System.currentTimeMillis();
            //需要将json串转化为对象
            treeList = ObjectMapperUtil.toObj(json,treeList.getClass());
            System.out.println("从redis中获取数据 耗时:"+(endTime-startTime)+"毫秒");
        }else{
    
    
            //3.数据不存在  查询数据库
            treeList = findItemCatList(parentId);
            Long endTime = System.currentTimeMillis();
            //3.将数据保存到缓存中
            String json = ObjectMapperUtil.toJSON(treeList);
            jedis.set(key, json);
            System.out.println("查询数据库 耗时:"+(endTime-startTime)+"毫秒");
        }
        return treeList;
    }

3.5.4 La diferencia de velocidad de usar Redis

Inserte la descripción de la imagen aquí

4. AOP implementa el almacenamiento en caché de Redis

4.1 Cómo entender AOP

Nombre: Programación orientada a aspectos
Función: Reduce el acoplamiento del código en el sistema y expande la función del método original sin cambiar el código original.
Fórmula: AOP = expresión de punto de entrada + método de notificación

4.2 Tipos de notificación

1. El método de destino de notificación previa se ejecuta antes de la ejecución
2. El método de destino de notificación posterior se ejecuta después de la ejecución
3. La notificación de excepción se ejecuta cuando se lanza una excepción durante la ejecución del método de destino
4. Las
características de notificación de notificación final que deben ejecutarse en cualquier momento : lo anterior Los cuatro tipos de notificación no pueden interferir con la ejecución del método de destino. Generalmente se utilizan para registrar el estado de ejecución del programa .

5. Rodee el método de notificación que debe ejecutarse antes y después de la ejecución del método de destino. Este método puede controlar si se ejecuta el método de destino. JoinPoint.proceed (); La función es poderosa.

4.3 Expresión de pointcut

La comprensión: la expresión punto de entrada es un juicio de programa (SI) está entrando en una notificación
irá a ejecutar cuando se ejecuta el programa, ** cumplido con el punto de notificación método de expresión de entrada ** lograr la expansión de los negocios:. El papel
de Especies (Escritura):
1. bean (nombre de bean ID de bean) solo puede interceptar un objeto de bean específico solo puede coincidir con un objeto
lg: bean ("itemServiceImpl")
2. dentro de (nombre de paquete. Nombre de clase) dentro de (" com.jt.service. * ”) puede coincidir con varios objetos. El
principio de coincidencia de grano grueso se corresponde con la clase

	  3. execution(返回值类型 包名.类名.方法名(参数列表))   最为强大的用法
	  lg : execution(* com.jt.service..*.*(..))
	  		返回值类型任意  com.jt.service包下的所有的类的所有的方法都会被拦截.
	  4.@annotation(包名.注解名称)  按照注解匹配.

Supongo que te gusta

Origin blog.csdn.net/qq_16804847/article/details/109044611
Recomendado
Clasificación