MyBatis de la entrada al suelo: el uso de la caché

Este es el undécimo artículo de la serie mybatis . Si no ha leído las sugerencias anteriores, primero vaya a la cuenta pública [Java Tsukuba Fox] para ver el texto anterior, que es conveniente para comprender y comprender.

¿Qué es el almacenamiento en caché?

La caché es un lugar donde se almacenan los datos (llamado: caché). Cuando un programa quiere leer datos, primero los obtendrá de la caché y los devolverá directamente. De lo contrario, los obtendrá de otros dispositivos de almacenamiento. Lo más importante acerca de la caché es obtenerla de la caché. La velocidad de adquisición de datos internos es muy rápida, y la velocidad de acceso a los datos se puede acelerar a través de la caché. Por ejemplo, cuando obtenemos datos de db, se necesita tiempo para transmitir datos a través de la red, el servidor de db tarda en leer datos del disco, etc. Si estos datos se colocan directamente en la memoria correspondiente a la jvm, el acceso será mucho mas rápido.

Caché en mybatis

Mybatis se divide en caché de primer nivel y caché de segundo nivel.

  • El caché de primer nivel es el caché de nivel SqlSession. Cuando se opera la base de datos, es necesario construir un objeto sqlSession. Hay una estructura de datos (HashMap) en el objeto para almacenar datos de caché. El área de datos de caché (HashMap) entre diferentes sesiones sql no no se afectan entre sí. de.
  • La caché de segundo nivel es una caché de nivel de asignador. Varias SqlSessions operan en la misma declaración SQL de Mapper. Múltiples SqlSessions pueden compartir la caché de segundo nivel. La caché de segundo nivel se encuentra entre SqlSessions.

Caché de nivel 1

La caché de primer nivel es una caché de nivel SqlSession. Cada SqlSession tiene su propia caché de nivel uno separada. Las cachés de nivel uno entre varias SqlSessions están aisladas entre sí y no se afectan entre sí. La caché de primer nivel en mybatis se activa automáticamente por defecto.

El principio de funcionamiento de la caché de primer nivel: en la misma SqlSession para ejecutar la misma consulta varias veces, cada vez que se ejecuta, se buscará en la caché de primer nivel primero, si hay en la caché, volverá directamente, Si no hay datos relevantes en la caché de primer nivel, Mybatis irá a la base de datos para buscar y luego colocará los datos encontrados en la caché de primer nivel. Cuando se ejecute la misma consulta por segunda vez, encontrará que ya existe en la caché y volverá directamente. El medio de almacenamiento de la caché de primer nivel es la memoria, y se usa un HashMap para almacenar datos, por lo que la velocidad de acceso es muy rápida.

Caso de caché de primer nivel

Secuencia de comandos sql de caso
DROP DATABASE IF EXISTS `mybatisdemo`;
CREATE DATABASE `mybatisdemo`;
USE `mybatisdemo`;
DROP TABLE IF EXISTS user;
CREATE TABLE user(
  id int AUTO_INCREMENT PRIMARY KEY COMMENT '用户id',
  name VARCHAR(32) NOT NULL DEFAULT '' COMMENT '用户名',
  age SMALLINT NOT NULL DEFAULT 1 COMMENT '年龄'
) COMMENT '用户表';
INSERT INTO t_user VALUES (1,'Java冢狐',18),(2,'Java',100),(3,'冢狐',23);
Lo siguiente es para consultar la información del usuario y devolver una lista
<select id="getList1" resultType="com.zhonghu.chat12.demo9.model.UserModel" parameterType="map">
    SELECT id,name,age FROM user
    <where>
        <if test="id!=null">
            AND id = #{id}
        </if>
        <if test="name!=null and name.toString()!=''">
            AND name = #{name}
        </if>
        <if test="age!=null">
            AND age = #{age}
        </if>
    </where>
</select>
Método de interfaz de mapeador correspondiente
List<UserModel> getList1(Map<String, Object> paramMap);
Caso de prueba
com.zhonghu.chat12.demo9.Demo9Test#level1CacheTest1
/**
 * 一级缓存测试
 *
 * @throws IOException
 */
@Test
public void level1CacheTest1() throws IOException {
    String mybatisConfig = "demo9/mybatis-config.xml";
    this.before(mybatisConfig);
    try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //第一次查询
        List<UserModel> userModelList1 = mapper.getList1(null);
        log.info("{}", userModelList1);
        //第二次查询
        List<UserModel> userModelList2 = mapper.getList1(null);
        log.info("{}", userModelList2);
        log.info("{}", userModelList1 == userModelList2);
    }
}

El código anterior se ejecuta dos veces en la misma SqlSession para obtener información de la lista de usuarios, y los resultados de las dos consultas se colocan en userModelList1 y userModelList2 respectivamente. El código final también determinará si las dos colecciones son iguales. Ejecútelo y veamos si accederemos a él .Varios db.

Ejecutar salida
01:15.312 [main] DEBUG c.j.c.d.mapper.UserMapper.getList1 - ==>  Preparing: SELECT id,name,age FROM user 
01:15.340 [main] DEBUG c.j.c.d.mapper.UserMapper.getList1 - ==> Parameters: 
01:15.364 [main] DEBUG c.j.c.d.mapper.UserMapper.getList1 - <==      Total: 3
01:15.364 [main] INFO  c.j.chat05.demo9.Demo9Test - [UserModel(id=1, name=Java冢狐, age=18), UserModel(id=2, name=Java, age=100), UserModel(id=3, name=冢狐, age=23)]
01:15.367 [main] INFO  c.j.chat05.demo9.Demo9Test - [UserModel(id=1, name=Java冢狐, age=18), UserModel(id=2, name=Java, age=100), UserModel(id=3, name=冢狐, age=23)]
01:15.367 [main] INFO  c.j.chat05.demo9.Demo9Test - true

Se puede ver en la salida que sql solo se genera una vez, lo que indica que se accederá a la base de datos la primera vez, y la segunda vez se obtendrá directamente de la caché y, finalmente, se generará una salida verdadera, lo que también indica que los dos resultados devueltos son el mismo objeto Por segunda vez, los datos se obtienen directamente de la caché, lo que acelera la consulta.

3 formas de borrar la caché de primer nivel

Para consultar los mismos datos en la misma SqlSession, mybatis los obtendrá de la caché de primer nivel por defecto. Si no está en la caché, accederá a la db. Luego, si queremos acceder directamente a la base de datos en lugar de a la caché, ¿qué debemos hacer?

Hay 3 formas de invalidar la caché de primer nivel:

  • Agregue, elimine y modifique operaciones en SqlSession, en este momento sqlsession limpiará automáticamente su caché interna de primer nivel
  • Llame al método clearCache en SqlSession para limpiar su caché interna de primer nivel
  • Establezca el valor del atributo flushCache del elemento de selección en Mapper xml en verdadero, luego todos los datos en el caché de primer nivel se borrarán cuando se ejecute la consulta, y luego ir a la base de datos para obtener los datos

Cualquiera de los métodos anteriores invalidará el actual y el caché en SqlSession, y luego irá a la base de datos para obtener los datos.

Resumen del uso de caché de nivel 1

  • El caché de primer nivel está en el nivel SqlSession. Cada SqlSession tiene su propio caché de nivel 1. El caché de nivel uno entre diferentes SqlSessions está aislado entre sí.
  • La caché de primer nivel en mybatis se activa automáticamente de forma predeterminada
  • Cuando se ejecuta la misma consulta en la misma SqlSession, primero buscará desde el caché de primer nivel, si se encuentra, regresará directamente, si no se encuentra, visitará la base de datos y luego eliminará los datos devueltos por la base de datos en la caché de primer nivel. Consíguela directamente de la caché durante la segunda consulta
  • 3 formas de borrar la caché de primer nivel (1: agregar, eliminar y modificar SqlSession invalidará la caché de primer nivel; 2: llamar al método SqlSession.clearCache invalidará la caché de primer nivel; 3: establecer el atributo flushCache de el elemento de selección en el Mapper xml a verdadero, luego la ejecución de esta consulta invalidará la caché de primer nivel)

Caché secundario

Uso de caché secundaria

Existen limitaciones en el uso de la caché de primer nivel. La misma consulta debe ejecutarse en la misma SqlSession, y la caché de primer nivel puede mejorar la velocidad de la consulta. Si desea utilizar la caché entre diferentes SqlSessions para acelerar la consulta, necesitamos usarlo en este momento El caché de segundo nivel.

La caché de segundo nivel es una caché de nivel de mapeador. Cada xml de mapeador tiene un espacio de nombres, y la caché de segundo nivel está vinculada al espacio de nombres. Cada espacio de nombres está asociado con una caché de segundo nivel. Varias SqlSessions pueden compartir el segundo nivel caché. La caché de segundo nivel se encuentra en SqlSessions. de.

La caché de segundo nivel no está habilitada de forma predeterminada, y debemos habilitarla en el archivo de configuración global de mybatis:

<settings>
    <!-- 开启二级缓存 -->
    <setting name="cacheEnabled" value="true"/>
</settings>

Una vez completada la configuración anterior, se debe agregar la siguiente configuración al xml del asignador correspondiente para indicar que la consulta en este asignador abre la caché de segundo nivel:

<cache/>

La configuración es así de simple.

Principio de consulta cuando coexisten la primera y la segunda caché

Si tanto la caché primaria como la secundaria están habilitadas, el proceso de consulta de datos es el siguiente:

  • Cuando se inicia una consulta, mybatis primero accederá a la caché de segundo nivel correspondiente a este espacio de nombres, y si hay datos en la caché de segundo nivel, regresará directamente; de ​​lo contrario, continuará hacia abajo.
  • Consulte si hay datos correspondientes en la caché de primer nivel, si los hay, regrese directamente, de lo contrario continúe hacia abajo
  • Acceda a la base de datos para obtener los datos requeridos, y luego colóquelos en la caché secundaria correspondiente a la SqlSession actual, y almacene una copia en otro lugar de la memoria local (este lugar se llama TransactionalCache)
  • Cuando se cierra SqlSession, es decir, cuando se llama al método close de SqlSession, los datos de TransactionalCache se colocarán en la caché de segundo nivel y los datos de la caché de primer nivel de SqlSession actual se borrarán.

Caso de caché de segundo nivel

El archivo de configuración global mybatis abre la configuración de la caché secundaria
<settings>
    <!-- 开启二级缓存 -->
    <setting name="cacheEnabled" value="true"/>
</settings>
Utilice el elemento de caché en mapper xml para activar el caché de segundo nivel
<!-- 启用二级缓存 -->
<cache/>
<select id="getList1" resultType="com.zhonghu.chat12.demo9.model.UserModel" parameterType="map">
    SELECT id,name,age FROM user
    <where>
        <if test="id!=null">
            AND id = #{id}
        </if>
        <if test="name!=null and name.toString()!=''">
            AND name = #{name}
        </if>
        <if test="age!=null">
            AND age = #{age}
        </if>
    </where>
</select>
Caso de prueba
com.zhonghu.chat12.demo9.Demo9Test#level2CacheTest1
/**
 * 二级缓存测试
 *
 * @throws IOException
 */
@Test
public void level2CacheTest1() throws IOException {
    String mybatisConfig = "demo9/mybatis-config1.xml";
    this.before(mybatisConfig);
    for (int i = 0; i < 2; i++) {
        try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<UserModel> userModelList1 = mapper.getList1(null);
            log.info("{}", userModelList1);
        }
    }
}

La consulta anterior se ejecuta 2 veces y cada consulta es una nueva SqlSession.

3 formas de borrar u omitir la caché secundaria

Cuando se activa la caché de segundo nivel, después de agregar un elemento de caché a un determinado xml de mapeador, todas las consultas en este xml de mapeador tienen la caché de segundo nivel habilitada de forma predeterminada, entonces, ¿cómo borramos u omitimos la caché de segundo nivel? Las tres formas son las siguientes:

  • Realizar adiciones, eliminaciones y cambios en el asignador correspondiente borrará los datos en la caché secundaria
  • Si el atributo flushCache del elemento de selección se establece en verdadero, los datos en el caché de segundo nivel se borrarán, luego los datos se consultarán en la base de datos y luego los datos se colocarán en el caché de segundo nivel
  • El atributo useCache del elemento de selección se establece en verdadero, lo que puede hacer que esta consulta omita la caché de segundo nivel y luego consulte los datos

para resumir

  • Secuencia de acceso a la caché de primer y segundo nivel: cuando existen cachés de primer y segundo nivel, se accederá primero a la caché de segundo nivel, luego se accederá a la caché de primer nivel y se accederá a la base de datos en Fin. Entendamos esta secuencia.

  • Establezca el atributo flushCache del elemento de selección en el mapeador xml en falso, y todos los datos en la caché de primer nivel se borrarán eventualmente, y todos los datos en la caché de segundo nivel correspondientes al espacio de nombres donde se encuentra la selección se borrarán

  • Establezca useCache del elemento select en el mapeador xml en falso, lo que hará que esta consulta omita la caché secundaria

  • En términos generales, el uso del almacenamiento en caché puede mejorar la eficiencia de las consultas, si domina este conocimiento, puede elegir según su negocio.

    Por fin

    • Si sientes que eres recompensado después de leerlo, espero que le prestes atención. Por cierto, dame un pulgar hacia arriba. Esta será la mayor motivación para mi actualización. Gracias por tu apoyo.
    • Bienvenidos a todos para que presten atención a mi cuenta pública [Java Fox], enfocándome en los conocimientos básicos de Java y la computadora, prometo dejarles obtener algo después de leerlo, si no me creen, péguenme
    • Busque la conexión triple con un clic: me gusta, reenviar y mirar.
    • Si tiene diferentes opiniones o sugerencias después de leer, por favor comente y comparta con nosotros. Gracias por su apoyo y cariño.

    ——Soy Chuhu, y amo la programación tanto como a ti.

Bienvenido a seguir la cuenta pública "Java Fox" para conocer las últimas noticias.

Supongo que te gusta

Origin blog.csdn.net/issunmingzhi/article/details/114269368
Recomendado
Clasificación