[Mybatis desde la entrada hasta el tutorial de combate real] Capítulo 7 Explicación detallada de Mybatis Query Cache

Siete, caché de consultas de Mybatis

    Almacenamiento en caché: almacena temporalmente datos en medios de almacenamiento (memoria, archivos).El propósito del almacenamiento en caché en bases de datos relacionales es reducir la presión sobre la base de datos.
    
    Los datos de la base de datos en realidad se almacenan en el disco duro.Si nuestro programa necesita usar datos, necesita leer datos del disco con frecuencia, lo que es ineficiente y ejerce mucha presión sobre la base de datos. Podemos almacenar en caché los datos consultados, lo que reduce la operación frecuente de los datos del disco, mejora la eficiencia de las consultas y reduce la presión del servidor.
    
    Mybatis proporciona almacenamiento en caché de consultas para reducir la presión de la base de datos y mejorar el rendimiento de la base de datos. Sin embargo, en el desarrollo de proyectos reales, el mecanismo de almacenamiento en caché de Mybatis rara vez se usa. Ahora, el mecanismo de almacenamiento en caché principal es redis.

7.1 ¿Qué es la caché de consultas?

  • MyBatis proporciona caché de consultas para reducir la presión de la base de datos y mejorar el rendimiento de la base de datos;

  • MyBatis proporciona caché de primer nivel y caché de segundo nivel;

  • El caché de primer nivel es el caché en el nivel SqlSession. Al operar la base de datos, es necesario construir un objeto SqlSession y hay una estructura de datos (HashMap) en el objeto para almacenar datos en caché. El área de datos de caché (HashMap) entre diferentes SqlSessions no se afecta entre sí;

  • La caché de segundo nivel es una caché de nivel de asignador. Múltiples SqlSessions operan la instrucción SQL del mismo asignador. Múltiples SqlSessions pueden compartir la caché de segundo nivel, y la caché de segundo nivel está entre SqlSessions;

7.2 Caché de nivel 1

7.2.1 Principio de funcionamiento de la caché de nivel 1

  • La primera vez que consulta los datos con id 1, primero vaya al caché de primer nivel para averiguar si hay datos con id 1, si no, consulte los datos de la base de datos y almacene los datos en el caché de primer nivel;

  • La segunda vez para consultar los datos con id 1, primero vaya al caché de primer nivel para averiguar si hay datos con id 1, si hay datos en el caché, obtenga los datos directamente del caché y ya no consulte el base de datos;

  • Si SqlSession realiza una operación de confirmación (insertar, actualizar, eliminar), borrará el caché de primer nivel en SqlSession. El propósito de esto es almacenar los datos más recientes en el caché y evitar lecturas sucias;

7.2.2 Clases de entidad

public class Person {

    private Integer id;
    private String personName;
    private Integer personAge;
    private String personAddress;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getPersonName() {
        return personName;
    }

    public void setPersonName(String personName) {
        this.personName = personName;
    }

    public Integer getPersonAge() {
        return personAge;
    }

    public void setPersonAge(Integer personAge) {
        this.personAge = personAge;
    }

    public String getPersonAddress() {
        return personAddress;
    }

    public void setPersonAddress(String personAddress) {
        this.personAddress = personAddress;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", personName='" + personName + '\'' +
                ", personAge=" + personAge +
                ", personAddress='" + personAddress + '\'' +
                '}';
    }
}

7.2.3 interfaz del mapeador

public interface PersonMapper {

    Person selectById(Integer id);

    List<Person> select();
}

7.2.4 archivo de mapeador

<?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.newcapec.mapper.PersonMapper">

    <select id="selectById" parameterType="java.lang.Integer" resultType="com.newcapec.entity.Person">
        select id,person_name,person_age,person_address from person where id=#{id}
    </select>

    <select id="select" resultType="com.newcapec.entity.Person">
        select id,person_name,person_age,person_address from person
    </select>
</mapper>

7.2.5 Pruebas

public class CacheTest {

    @Test
    public void testSqlSessionCache() {
        SqlSession sqlSession = MybatisUtil.getSession();
        PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);

        System.out.println("----------第一次使用id为1的person数据-----------");
        Person p1 = personMapper.selectById(1);
        System.out.println(p1);

        /**
         * 一级缓存自带缓存,不可不用的,缓存介质为内存
         * commit()提交方法可以请求缓存
         */
        //sqlSession.commit();

        System.out.println("----------第二次使用id为1的person数据-----------");
        Person p2 = personMapper.selectById(1);
        System.out.println(p2);

        sqlSession.close();
    }
}

7.3 Caché de segundo nivel

7.3.1 Principio de funcionamiento de la caché L2

  • SqlSession1 para consultar los datos cuya identificación es 1 y almacenar los datos en el caché secundario después de la consulta;

  • SqlSession2 para consultar los datos cuya identificación es 1, para averiguar si hay datos en el caché, si los hay, obtenga directamente los datos del caché;

  • Si SqlSession3 ejecuta sql bajo el mismo asignador, ejecuta el envío de confirmación y borra los datos en el área de caché secundaria debajo del asignador;

  • La diferencia entre la memoria caché de segundo nivel y la memoria caché de primer nivel es que el alcance de la memoria caché de segundo nivel es mayor y varias SqlSessions pueden compartir el área de memoria caché de segundo nivel de Mapper;

  • Cada mapeador tiene un área de caché de segundo nivel, dividida por espacio de nombres;

  • Si los espacios de nombres de los dos mapeadores son iguales, los dos mapeadores ejecutan consultas SQL y los datos se almacenarán en la misma área de caché secundaria;

7.3.2 Habilitar caché L2

Configure en el archivo de configuración principal de mybatis: cacheEnabled

elementos de configuración describir prestación valores predeterminados
cacheEnabled Configuraciones globales de encendido/apagado para todos los cachés bajo este archivo de configuración verdadero Falso verdadero
<!-- 全局参数设置 -->
<settings>
    <!-- 开启二级缓存-->
    <setting name="cacheEnabled" value="true"/>
</settings>

Abra el segundo caché en el archivo de asignación y el SQL en mapper.xml se almacenará en su área de caché HashMap después de que se complete la ejecución del SQL.

<mapper namespace="com.newcapec.mapper.PersonMapper">
    <!-- 配置当前mapper文件中所有查询语句都放入二级缓存中 -->
    <cache/>
    
    <select>
        ...
    </select>
</mapper>

7.3.3 Clases de entidad

    La clase de entidad que almacena datos en el caché de segundo nivel debe implementar la interfaz serializable java.io.Serializable.

public class Person implements Serializable {
    
}

7.3.4 Prueba de caché L2

@Test
public void testMapperCache(){
    /**
     * 二级缓存,可插拔式缓存,缓存介质:内存+磁盘
     */

    SqlSession sqlSession1 = MybatisUtil.getSession();
    PersonMapper personMapper1 = sqlSession1.getMapper(PersonMapper.class);
    System.out.println("-------------第一次查询--------------");
    Person p1 = personMapper1.selectById(2);
    System.out.println(p1);
    sqlSession1.close();

    System.out.println("----------------sqlSession1关闭,建立sqlSession2连接-------------------");

    SqlSession sqlSession2 = MybatisUtil.getSession();
    PersonMapper personMapper2 = sqlSession2.getMapper(PersonMapper.class);
    System.out.println("-------------第二次查询--------------");
    Person p2 = personMapper2.selectById(2);
    System.out.println(p2);
    sqlSession2.close();
}

7.3.5 Configuración de useCache

    Establecer useCache="false" en la declaración puede deshabilitar el caché de segundo nivel de la declaración de selección actual, es decir, cada consulta enviará sql a la consulta. El valor predeterminado es verdadero, es decir, el SQL usa la memoria caché de segundo nivel.

<?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.newcapec.mapper.PersonMapper">

    <!-- 配置当前mapper文件中所有查询语句都放入二级缓存中 -->
    <cache/>

    <select id="selectById" parameterType="java.lang.Integer" resultType="com.newcapec.entity.Person" useCache="true">
        select id,person_name,person_age,person_address from person where id=#{id}
    </select>

    <!-- select标签中的useCache属性: 决定了当前sql是否使用二级缓存,默认为true -->
    <select id="select" resultType="com.newcapec.entity.Person" useCache="false">
        select id,person_name,person_age,person_address from person
    </select>
</mapper>

prueba:

@Test
public void testMapperCache2() {
    SqlSession sqlSession1 = MybatisUtil.getSession();
    PersonMapper personMapper1 = sqlSession1.getMapper(PersonMapper.class);
    System.out.println("-------------第一次查询--------------");
    List<Person> list1 = personMapper1.select();
    System.out.println(list1);
    sqlSession1.close();

    System.out.println("----------------sqlSession1关闭,建立sqlSession2连接-------------------");

    SqlSession sqlSession2 = MybatisUtil.getSession();
    PersonMapper personMapper2 = sqlSession2.getMapper(PersonMapper.class);
    System.out.println("-------------第二次查询--------------");
    List<Person> list2 = personMapper2.select();
    System.out.println(list2);
    sqlSession2.close();
}

Supongo que te gusta

Origin blog.csdn.net/ligonglanyuan/article/details/124419889
Recomendado
Clasificación