Proceso de ejecución del marco mybatis:
1. Configure el archivo de configuración de MyBatis, sqlmapconfig.xml (el nombre no es arreglado)
2. Cargue el entorno de ejecución mybatis a través de archivos de configuración y cree la fábrica de sesión de SQLSessionFactory
SQLSessionFactory se usa de manera singleton cuando realmente se usa.
3. Cree SQLSession a través de SQLSessionFactory
SQLSession es una interfaz orientada al usuario (que proporciona métodos de base de datos operativos). El objeto de implementación es Insecure de hilo. Se recomienda que el escenario de aplicación de SQLSession esté dentro del cuerpo del método.
4. Llame al método SQLSession para manipular datos.
Si necesita cometer una transacción, debe ejecutar el método Commit () de SQLSession.
5. Liberar recursos y cerrar SQLSession
Método de desarrollo del agente mapper (recomendado)
Solo los programadores necesitan escribir interfaz Mapper (es decir, interfaz DAO)
Los programadores deben seguir una especificación de desarrollo al escribir mapper.xml (archivos de mapeo) y mapper.java:
1. El espacio de nombres en mapper.xml es la ruta completa de la clase mapper.java.
2. La ID de la declaración en Mappper.xml es la misma que el nombre del método en Mappper.java.
3. El tipo de parámetro de la declaración en mapper.xml especifica el tipo del parámetro de entrada y el tipo de parámetro de entrada del método mapper.java.
4. El resultado resultante de la declaración en mapper.xml especifica el tipo de salida y el tipo de valor de retorno del método mapper.java.
Contenido de este artículo:
Analice el modelo de datos del producto de pedido.
Mapeo avanzado: (aprender)
Implemente una consulta uno a uno, uno a muchos y muchos a muchos.
Retraso de carga
Consulta caché
Caché de nivel 1
Cache de nivel 2 (Comprenda los escenarios de uso de MyBatis Nivel 2 Cache)
Integración MyBatis y Spirng (maestro)
Ingeniería inversa (puede usar)
Ordenar el modelo de datos del producto
Ideas de análisis del modelo de datos
1. Contenido de datos registrado en cada tabla
Estar familiarizado con el contenido registrado en cada tabla por módulo es equivalente al proceso de requisitos del sistema de aprendizaje (funciones).
2. Configuración de campo importante para cada tabla
Campos no vacíos, campos de claves exteriores
3. La relación entre las tablas a nivel de base de datos
Relación de clave extranjera
4. Relación comercial entre tablas
Al analizar la relación comercial entre las tablas, es necesario analizarla en función de un cierto significado comercial.
Análisis del modelo de datos
Usuario de la tabla de usuarios:
Registre la información del usuario del producto comprado
Tabla de pedido: pedidos
Registra el pedido creado por el usuario (pedido para comprar artículos)
Detalle del pedido: OrderDetail:
Registre la información detallada del pedido, a saber, la información de la compra
Lista de productos: artículos
Información de producto registrada
Relación comercial entre tablas:
Al analizar la relación comercial entre las tablas, es necesario analizarla en función de un cierto significado comercial.
Primero analice la relación comercial entre las tablas que tienen relaciones entre los niveles de datos:
usre y órdenes:
Usuario ---> Pedidos: un usuario puede crear múltiples pedidos, uno a muchos
Pedidos -> Usuario: Un solo usuario crea un pedido, uno a uno
órdenes y orden de orden:
Pedidos> Order Detail: un pedido puede incluir detalles de múltiples pedidos, porque un pedido puede comprar múltiples artículos, y la información de compra de cada artículo se registra en OrderDetail, una relación de uno a muchos
OrderDetail> Pedidos: un detalle de pedido solo se puede incluir en un pedido, uno a uno
OrderDetail y elementosm:
OrderDetail‐> Elementos: los detalles de un pedido solo corresponden a una información del producto, uno a uno
Elementos> OrderDetail: un producto se puede incluir en detalles de múltiples pedidos, uno a muchos
Luego analice si existe una relación comercial entre las tablas que no están relacionadas con el nivel de la base de datos:
órdenes y artículos:
La relación entre órdenes y elementos se puede establecer a través de la tabla OrderDetail.
Usuario y elementos: constituyen una relación de muchos a muchos a través de otras tablas
Consulta uno a uno
Requisitos: Información de pedido de consulta e información del usuario de consulta asociada para crear pedidos
Utilice Resulttype para consultar
Consideración sobre el uso de declaraciones SQL
Determine la tabla principal de la consulta: tabla de pedido
Determine la tabla de asociación para la consulta: tabla de usuario
¿La consulta de asociación usa un enlace interno o un enlace externo?
Dado que hay una clave extranjera (user_id) en la tabla de pedidos, solo se puede encontrar un registro consultando la tabla de usuarios a través de la asociación de clave externa, y se pueden usar enlaces internos.
Seleccione pedidos.*, User.username, user.sex, user.address fromorders, usuario donde orders.user_id = user.id
Crear pojo (OrderScustom.java)
Mapee los resultados de la consulta SQL anterior en POJO, que debe incluir todos los nombres de la columna de consulta.
Los órdenes originales. Java no puede mapear todos los campos, y se requiere un POJO recién creado.
Cree una clase PO que hereda una clase PO que incluya muchos campos de consulta.
OrdersMApPerCustom.xml
OrdersMApPerCustom.java
Escribir clases de prueba
Haga clic con el botón derecho en el archivo OrdersMapperCustom.java> Seleccione Nuevo> Otros> Caso de prueba Junit> Seleccione la función para probar
Escriba el siguiente código en OrdersMapperCustomTest.java:
Public Class OrderSMapPerCustomTest {private sqlSessionFactory sqlsessionFactory; // Este método es ejecutar @beforepublic void setup () lanza excepción {// Crear sqlsessionFactory // myBatis Configuración Archivo String Resource = "SqlmapConfig.xml"; // Obtenga el archivo de configuración FIEPTREAM ENTRAAME = " Recursos.getResourCeasstream (recursos); // Cree una fábrica de sesión y pase en la información del archivo de configuración de MyBatis SQLSessionFactory = new SqlSessionFactoryBuilder (). Build (InputStream);}@testPublic Void testFindordersUser () lanza excepción {sqlSession sqlsession = sqlsession.Opensession ()/////////// SQLSession sqlsession = sqlssession. OrdersMapperCustom OrdersMapperCustom = sqlsession.getMapper (OrdersMapperCustom.Class); // Lista de métodos mapeadores de llamada <RdersCustom> list = OrdersMapperCustom.FindorDersUser (); System.Println (LIST); sqlseSession.close ();}Use ResultMap para consultar
Declaración de SQL: SQL implementado en el mismo resultado de resultado
Ideas para usar el mapeo de resultados de resultados
Use ResultMap para asignar la información de pedido en el resultado de la consulta al objeto Orders, agregar el atributo de usuario en la clase de pedidos y asignar la información del usuario de consulta asociada al atributo de usuario en el objeto Orders.
Agregar atributo de usuario a la clase de pedidos
OrdersMApPerCustom.xml
Definir resultados de resultados
TYEP: significa mapear los resultados de toda la consulta a una determinada clase, por ejemplo, cn.itcast.mybatis.po.orders
ID: representa el identificador único de la columna de consulta en la tabla de la base de datos, el identificador único en la información del pedido. Si hay varias columnas que forman un identificador único, configure múltiples ID.
Columna: una columna de identificación única para la información del pedido en la tabla de la base de datos
Propiedad: ¿Qué propiedad se asigna a los pedidos por la columna de identificación única de la información del pedido?
Asociación: se utiliza para mapear información para consultar objetos individuales
Propiedad: qué propiedad en pedidos para asignar la información del usuario de la consulta asociada a
Javatype: qué propiedad asignó al usuario
< información. Si hay múltiples columnas para formar un identificador único, configure múltiples IDColumn: columna de identificación única de la propiedad de información de información de pedido: a qué propiedad en los pedidos se asigna mediante la columna de identificador única de información de pedido-> <Id columna = "id" propiedad = "id" /> <resultado columna = "user_id" propiedad = "userID" /> <resultado columna = "numer" number = "número" /> <resultado columna = "columna =" columna "creatime" createMe " /" creatime " columna = "nota" propiedad = nota/> <!-Configure la información de usuario asociada asignada-> <!-Association: Información utilizada para asignar la propiedad de objeto único de consulta asociada: qué propiedad en órdenes para asignar la información del usuario de la consulta asociada a-> <Association Property = "User" Javatype = "Cn.it.itcast.mybatis.po.user"> <!-Id: Id: Id Id para la columna de usuario asociado para la columna de usuario Asociado para la columna de User de la quirera. Información Javatype: qué propiedad asignó al usuario -> <id columna = "user_id" propiedad = "id"/> <resultado columna = "username" propiedad = "username"/> <resultado columna = "sexo" propiedad = "sex"/> <resultado columna = "dirección" propiedad = "dirección"/> <</asociación> </sultMap>
Definición de declaración
OrdersMApPerCustom.java
Código de prueba
@TestPublic void testFindORDERSUSRERSULTMAP () lanza la excepción {sqlSession sqlsession = sqlsession.Opensession (); // Crea proxy Object OrdersMapperCustom OrdersMapperCustom = SqlSession.getMapper (OrdersMapperCustom.classas OrdersMapperCustom.FindORDERSUSERRESSULTMAP (); System.out.println (List); SqlSession.Close ();}ResultType y ResultMap implementan un resumen de consulta individual
Resulttype: es relativamente simple de implementar usando resultType. Si el nombre de la columna de consulta no está incluido en el POJO, debe agregar los atributos correspondientes del nombre de la columna para completar el mapeo.
Si no hay requisitos especiales para los resultados de la consulta, se recomienda utilizar el resultado de los resultados.
ResultMap: el resultado de resultados debe definirse por separado, lo cual es un poco problemático. Si hay requisitos especiales para los resultados de la consulta, el uso de ResultMap puede completar los atributos del mapeo de consultas asociado POJO.
ResultMap puede implementar la carga perezosa, el thittype no puede implementar la carga perezosa.
Uno a muchos consulta
Requisitos: pedidos de consulta e información de detalles del pedido.
Declaración SQL
Determine la tabla de consulta principal: tabla de pedido
Determine la tabla de consulta asociada: tabla de detalles del pedido
Simplemente agregue la asociación de la lista de detalles del pedido basada en una consulta individual.
Selectorders.*, User.userName, user.sex, user.address, ordendetail.id ordendetail_id, ordendetail.items_id, ordendetail.items_num, orden.orders_idFromorders, usuario, orden de pedido donde órdenes.User_id = user.id and Orderdetail.orders.id = orderers.id.idDID
Análisis: use ResultType para mapear los resultados de la consulta anterior en POJO, y la información del pedido es la duplicación.
Requisito: no pueden ocurrir registros duplicados para la asignación de pedidos.
Agregue la lista <OrderDetail> Propiedad OrderDetails en la clase de órdenes.java.
Finalmente, la información del pedido se asignará a los pedidos, y los detalles del pedido correspondientes a la orden se asignan a la propiedad de OrdenDetails en pedidos.
El número de pedidos registrados en Mapped es dos (la información de los pedidos no se repite)
La propiedad OrderDetails en cada pedido almacena los detalles del pedido correspondientes al pedido.
Agregar atributo de detalles del pedido de la lista en pedidos.java
OrdersMApPerCustom.xml
Definición de mapas de resultados
El uso extiende la herencia sin configurar la asignación de la información del pedido y la información del usuario en
Colección: consulta múltiples registros para asignar al objeto de colección para la consulta de asociación
Propiedad: asigne la consulta de asociación a múltiples registros a cn.itcast.mybatis.po.orders qué propiedad se asigna a cn.itcast.mybatis.po.orders
oftype: especifica el tipo que se asigna a POJO en el atributo de colección de listas
< heredar, no necesita configurar la asignación de la información del pedido y la información del usuario en él-> <!-Información de detalles del pedido Una consulta de asociación de pedidos tiene múltiples detalles. To use collection to map collection: map multiple records to the collection object property: map association query to multiple records to cn.itcast.mybatis.po.Orders Which property ofType: Specify the type of pojo map to list collection properties--><collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"><!-- id: Order details unique identifier property: to map the unique Identificador de los detalles del pedido a cn.itcast.mybatis.po.OrderDetail-> <id columna = "ordendetail_id" propiedad = "id"/> <resultado columna = "items_id" Property = "itemsID"/> <resultado columna = "items_num" Property = "itemsnum"/> <resultado columna = "Orders_id" Propiedad = "OrdersID"//<Collect Collect Collect Collection
OrdersMApPerCustom.java
Código de prueba:
@TestPublic void testFindordersAndOrderDetailResultMap () lanza la excepción {sqlSession sqlsession = sqlSessionFactory.opensession (); // crea objetos proxy ordersMapperCustom OrdersMapperCustom = SqlSession.getMapper (OrderSMapperCerRust.class); // mappersmappercustom = SQLSession.getMapper (OrderSmapperCerUnstom.class); // mappersmapperCustom = SQLSession.getMapper (OrdersMapperNUSTO.Class); // mappersmapperCustom = list de órdenes <orders list = LITS/ LITS/ LISTS/ LITS/ LITS/ LISTS/ LISTA <Orders List. OrdersMapperCustom.FindordersAnderDerDetailResultMap (); System.out.println (List); SqlSession.Close ();}resumen
MyBatis utiliza la colección de ResultMap para mapear múltiples registros de la consulta asociada en una propiedad de colección de listas.
Implementación utilizando resultType:
Detalles de mapeo de pedidos en las colas de pedido En pedidos, debe manejarlo usted mismo, usar un doble bucle para atravesar, eliminar registros duplicados y colocar los detalles de pedido en las colas de orden.
Muchos a muchos
Requisitos: Usuarios de consulta e información de compra de usuarios.
Declaración SQL
La tabla principal de la consulta es: tabla de usuario
Tabla de asociación: dado que el usuario y el producto no están directamente relacionados, están relacionados a través de pedidos y detalles de pedidos, por lo que la tabla de asociación: pedidos, orden de orden, artículos
SELECT orders.*,USER.username,USER.sex,USER.address,orderdetail.id orderdetail_id,orderdetail.items_id,orderdetail.items_num,orderdetail.orders_id,items.name items_name,items.detail items_detail,items.price items_priceFROMorders,USER,orderdetail,itemsWHERE orders.user_id = user.id y ordendetail.orders_id = orders.id y orderDetail.items_id = items.id
Ideas de mapeo
Mapee la información del usuario en el usuario.
Agregue la lista de atributos de la lista de pedidos <Orders> OrdersList en la clase de usuario para asignar los pedidos creados por el usuario a la lista de órdenes
Agregue la lista de propiedades de la lista de detalles del pedido <OrderDetail> OrderDetials en pedidos para asignar Detials de pedidos
Agregue la propiedad de elementos en orden de cola para mapear los elementos correspondientes a los detalles del pedido a los elementos
OrdersMApPerCustom.xml
Definición de mapas de resultados
< Propiedad = "dirección"/> <!-INFORMACIÓN DEL PEDIDO Un usuario corresponde a múltiples órdenes y use la asignación de colección-> <Propiedad de colección = "OrdersList" oftype = "cn.itcast.mybatis.po.orders"> <id columna = "id" id "protain property="createtime"/><result column="note" property="note"/><!-- Order details One order includes multiple details--><collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"><id column="orderdetail_id" property="id"/><result column="items_id" property="itemsId"/><result columna = "items_num" Property = "itemsnum"/> <resultado column = "orders_id" propiedad = "orderSid"/> <!-Información del producto Un detalle de pedido corresponde a un producto-> <propiedad de asociación = "elementos" javatype = "cn.itcast.mybatis.po.items"> <id columna = "items_id" propiedad = "Id"/> <resultado columna columna " Propiedad = "Name"/> <resultado columna = "items_detail" Property = "Detalle"/> <resultado columna = "items_price" Property = "Price"/> </sociation> </ Collection> </Collection> </resultmap>
OrdersMApPerCustom.java
Código de prueba:
@TestPublic void testFindUserAndItemSResultMap () lanza la excepción {sqlSession sqlsession = sqlSessionFactory.Opensession (); // Crear objetos proxy OrdersMappercustom OrdersMapperCustom = SQLSession.getMapper (OrderSMappercustom.class); // mappersmapperCustom = usuary list <sersser OrdersMapperCustom.FindUserAndItemSResultMap (); System.out.println (List); SqlSession.Close ();} Resumen de la consulta de muchos a muchos
Se verificará la lista detallada de la información del producto comprada por el usuario (nombre de usuario, dirección del usuario, nombre del producto, hora de compra, cantidad de compra)
En respuesta a los requisitos anteriores, utilizamos ResultType para asignar los registros de consulta en un POJO extendido, que es muy simple de implementar la función de una lista detallada.
Uno a muchos es un caso especial de muchos a muchos, como sigue:
Al consultar la información del producto comprada por los usuarios, la relación entre el usuario y el producto es una relación de muchos a muchos.
Requisito 1:
Campos de consulta: cuenta de usuario, nombre de usuario, género del usuario, nombre del producto, precio del producto (más común)
Listas detalladas comunes en el desarrollo empresarial, listas detalladas de productos comprados por los usuarios,
Use Resulttype para asignar la columna de consulta anterior a la salida de POJO.
Requisito 2:
Campos de consulta: cuenta de usuario, nombre de usuario, cantidad de artículos comprados, detalles del producto (mouse para mostrar detalles)
Use ResultMap para mapear la lista de detalles del producto comprado del usuario en el objeto de usuario.
Resumir:
El uso de ResultMap es para aquellas funciones que tienen requisitos especiales para la asignación de resultados de consulta, como la asignación de requisitos especiales en listas que incluyen múltiples listas.
Resumen de resultype y ResultMap
Resulttype:
efecto:
Mapee los resultados de la consulta en POJO de acuerdo con el nombre de la columna SQL Nombre del atributo POJO Consistencia.
ocasión:
Visualización común de registros detallados, como cuando los usuarios compran los detalles del producto y muestran toda la información de consulta asociada en la página, puede usar directamente el TurnaTtype para asignar cada registro.
Dispara al pojo y atraviesa la lista (POJO en la lista) en la página delantera.
ResultMap:
Use la asociación y la colección para completar el mapeo avanzado uno a uno y uno a muchos (existen requisitos de mapeo especiales para los resultados).
asociación:
efecto:
Mapee la información de consulta asociada en un objeto POJO.
ocasión:
Para facilitar la consulta de información asociada, puede utilizar la asociación para asignar información de pedido asociada en los atributos de POJO de objetos de usuario, como: consulta de pedidos e información de usuario asociada.
El uso de resultType no puede mapear los resultados de la consulta al atributo POJO del objeto POJO. Elija si se utiliza TEVETTYPE o ResultMap de acuerdo con las necesidades de atravesar la consulta de conjunto de resultados.
Recopilación:
efecto:
Mapee la información de consulta asociada en una recopilación de listas.
ocasión:
Para facilitar la consulta de la información de la asociación transversal, puede usar la recopilación para asignar la información de la asociación a la recopilación de la lista, como: consultar el módulo de alcance de permiso del usuario y el menú bajo el módulo, puede usar la recopilación para asignar la lista del módulo para asignar los atributos de la lista del menú del objeto del módulo. El propósito de esto también es facilitar la consulta de transferencia del conjunto de resultados de consulta.
Si usa resultType, no puede asignar los resultados de la consulta a la colección de la lista.
Retraso de carga
ResultMap puede implementar el mapeo avanzado (utilizando la asociación y la recopilación para implementar el mapeo uno a uno y uno a muchos). La asociación y la colección tienen funciones de carga perezosa.
necesidad:
Si se consulta el pedido y se asocia la información del usuario. Si primero consultamos la información del pedido para cumplir con los requisitos, consultaremos la información del usuario cuando necesitemos consultar la información del usuario. La consulta de información del usuario a pedido se retrasa la carga.
Carga de retraso: Primera consulta desde una sola tabla, y luego desde la tabla asociada cuando sea necesario, mejorando enormemente el rendimiento de la base de datos, porque la consulta de una sola tabla es más rápida que consultar múltiples tablas.
Use la asociación para implementar la carga perezosa
Requisitos: pedidos de consulta e información del usuario de consulta asociada
Ordresmappercustom.xml
Es necesario definir la declaración correspondiente a los dos métodos mapeadores.
1. Solo información de orden de consulta
Seleccionar * de los pedidos
Use la asociación para retrasar la carga (ejecutar) la siguiente satisfacción (información del usuario de la consulta de asociación) en la declaración de la orden de consulta
2. Información del usuario de consulta relacionada
User_ID se utiliza para consultar la información del usuario siguiendo el USER_ID en la consulta de información de pedido anterior
Use FinduserByID en usermapper.xml
El anterior primero ejecuta FindorDersUserlayLoading, y cuando necesita consultar al usuario, luego ejecuta FindUserByID, y la carga y ejecución tardía se configuran a través de la definición de resultados de resultados.
Retraso de carga de resultados
Use Seleccionar en la asociación para especificar la ID de la declaración que se ejecutará mediante carga perezosa.
< columna = "CreateTime" Property = "CreateTime"/> <resultado columna = "nota" propiedad = "nota"/> <!-Mapeo de la configuración de la información del pedido-> <id columna = "id" propiedad = "user_id" propiedad = "userid"/> <resultado columna = "number" propiedad = "número"/> <resultado columna = "createTime"/> <resultado columna = "nota" nota = "nota"/<!-numery---numi
Seleccione: Especifique la ID de la declaración que se ejecutará para la carga perezosa (la declaración que consulta la información del usuario basada en User_ID)
Para usar FindUserById en Usermapper.xml para completar la consulta basada en la información del usuario de ID de usuario (user_id). Si FindUserByid no está en este mapeador, debe agregar el espacio de nombres antes.
Columna: la columna en la información de la información del pedido asociada con la consulta de información del usuario es user_id
La consulta SQL para Association se entiende como:
Seleccione órdenes.*, (Seleccione el nombre de usuario del usuario donde orders.user_id = user.id) UserName, (seleccione Sexo del usuario donde orders.user_id = user.id) SexFrom Orders-> <Association Property = "User" javatype = "cn.itcast.mybatis.po.user" select = "cn.itcast.mybatis.mappaper.usmermerbyby". columna = "user_id"> <!-Implementar la carga perezosa de la información del usuario-> </sociation> </resultadomap>
Ordenesmappercustom.java
Ideas de prueba:
1. Ejecute el método mapeador anterior (findorDersUserlayLoading), y llame a FindOrderSUserlayLoading en cn.itcast.mybatis.mapper.ordersMapPerCustom para solo consultar información de pedido (tabla única).
2. En el programa, atraviese la lista <Ordens> consultada en el paso anterior. Cuando llamamos al método GetUser en pedidos, comenzamos la carga perezosa.
3. Retraso de carga, llame al método FindUserByID en Usermapper.xml para obtener información del usuario.
Configuración de carga perezosa
MyBatis no habilita la carga perezosa de forma predeterminada, y debe configurarse en sqlmapconfig.xml.
Configurar en el archivo de configuración de MyBatis Core:
Establecer el elemento Descripción Valor permitido Valor predeterminado
LazyLoadingEnabled Globaly Set Lazy Carging. Si se establece en 'falso', todos los asociados se inicializarán y cargarán. Verdadero o falso
Agressl vellyAgreading cuando se establece en 'verdadero', los objetos de carga perezosos pueden cargarse por todas las propiedades perezosas. De lo contrario, cada propiedad se carga según sea necesario. Verdadero o falso Verdadero
Config en sqlmapconfig.xml:
Código de prueba
Pensando en la carga retrasada
¿Cómo lograr una carga perezosa sin usar la asociación y la colección proporcionada por MyBatis?
El método de implementación es el siguiente:
Definir dos métodos mapeadores:
1. Consulta la lista de pedidos
2. Consulta información del usuario basada en ID de usuario
Ideas de implementación:
Primero consulte el primer método mapeador y obtenga la lista de información del pedido
En el programa (servicio), llame al segundo método mapeador según sea necesario para consultar la información del usuario.
En resumen: use el método de carga perezoso para consultar SQL simple (preferiblemente una sola tabla, también puede asociar consultas) y luego cargar otra información de las consultas asociadas según sea necesario.
Consulta caché
MyBatis proporciona cachés de consulta para reducir la presión de datos y mejorar el rendimiento de la base de datos.
MyBaits proporciona caché de primer nivel y caché de segundo nivel.
El caché de nivel 1 es un caché de nivel SQLSession. Al operar la base de datos, debe construir el objeto SQLSession, y hay una estructura de datos (hashmap) en el objeto para almacenar datos en caché. Las áreas de datos en caché (hashmaps) entre diferentes SQLSessions no se afectan entre sí.
El caché secundario es un caché de nivel de mapeador. Múltiples SQLSessions operan las declaraciones SQL del mismo mapeador. Múltiples SQLSessions pueden compartir el caché secundario. El caché secundario es la sesión cruzada.
¿Por qué usar caché?
Si hay datos en el caché, no necesita obtenerlo de la base de datos, lo que mejora enormemente el rendimiento del sistema.
Caché de nivel 1
Principio de trabajo en caché de primer nivel
La primera vez que inicié una consulta sobre la información del usuario con ID de usuario 1, primero busque si hay información del usuario con información del usuario con ID 1 en el caché. Si no, consulte la información del usuario de la base de datos.
Obtenga información del usuario y almacene la información del usuario en un caché de primer nivel.
Si SQLSession realiza operaciones de confirmación (ejecuta inserción, actualización y eliminación), borra el caché de primer nivel en SQLSession. El propósito de esto es hacer que el caché almacene la información más reciente y evitar la lectura sucia.
La segunda vez que inicié una consulta sobre la información del usuario con el ID de usuario 1, primero busque si hay información del usuario con información del usuario con ID 1 en el caché. Si hay uno en el caché, obtendré directamente la información del usuario del caché.
Prueba de caché de nivel 1
MyBatis admite almacenamiento en caché de primer nivel de forma predeterminada y no es necesario configurar en el archivo de configuración.
Siga los pasos del principio de caché de nivel uno anterior para probar.
//OrdersMapperCusntomTest.java@Testpublic void testCache1() throws Exception{SqlSession sqlSession = sqlSessionFactory.openSession();//Create a proxy object UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//The following query uses a SqlSession//The first request is initiated and El usuario con ID 1 es la consulta user User1 = usermapper.finduserByid (1); system.out.println (user1); // Si SQLSession realiza operaciones de confirmación (ejecuta inserción, actualización y eliminación), borra el caché de primer nivel en SQLSession. El propósito de esto es hacer que el caché almacene la información más reciente y evitar la lectura sucia. // actualizar la información del usuario1 user1.setUsername ("Test User22"); usermapper.UpdateUser (user1); // Ejecutar la operación de confirmación para borrar el caché sqlsession.commit (); // Inicie la segunda solicitud y consulte al usuario con ID 1 usuario user2 = usermapper.finduserByID (1); system.out.println (user2); sqlSession.close ();}Aplicación de caché de nivel 1
El desarrollo formal es integrar MyBatis y Spring, y las transacciones se controlan en el servicio.
Un método de servicio incluye muchas llamadas de métodos mapeadores.
Servicio {// Al iniciar la ejecución, inicie la transacción y cree el objeto SQLSession // llame al método de mapeador para la primera vez FindUserByid (1) // celda El método de mapper para la segunda vez finduserByID (1), obteniendo datos del caché de primer nivel // el método termina, sqlSession está cerrado}Si ejecuta dos llamadas de servicio para consultar la misma información del usuario, no va al caché de primer nivel, porque el método de sesión finaliza, el SQLSession se cerrará y se borrará el caché de primer nivel.
Caché de nivel 2
principio
Primero, habilite el caché de segundo nivel de mybatis.
SQLSession1 consulta información del usuario con ID de usuario 1. Al consultar la información del usuario, los datos de consulta se almacenarán en el caché secundario.
Si SQLSession3 ejecuta SQL en el mismo mapa, ejecuta el envío de Commit y borra los datos en el área de caché secundario debajo del mapeador.
SQLSession2 consulta la información del usuario con ID de usuario 1 y encuentra si hay datos en el caché. Si existe, los datos se recuperan directamente del caché.
La diferencia entre el caché secundario y el caché primario es mayor. El rango del caché secundario es más grande. Múltiples SQLSessions pueden compartir el área de caché secundaria de Usermapper.
Usermapper tiene un área de caché secundaria (subdividido por el espacio de nombres), y otros mapppers también tienen su propio área de caché secundaria (subdividido por el espacio de nombres).
Cada mapeador de espacio de nombres tiene un segundo área de caché. Si el espacio de nombres de los dos mapeadores es el mismo, los dos mapeadores tendrán el mismo área de caché en el segundo área cuando SQL ejecute los datos.
Encienda el caché de nivel 2
El caché de segundo nivel de mybaits es el nivel de rango de mapeadores. Además de configurar el interruptor principal del caché de segundo nivel en sqlmapconfig.xml, el caché de segundo nivel también debe habilitarse en el mapper.xml específico.
Agregado al archivo de configuración central sqlmapconfig.xml
<setting name = "cacheenabled" value = "true"/>
Descripción Permitido Valor Valor predeterminado
Configuración de encendido/apagado de CacheenApled Global para todos los cachés en este archivo de configuración. Verdadero o falso
Encienda el caché secundario en usermapper.xml, y la ejecución SQL en Usermapper.xml se almacenará en su área de caché (HASHMAP).
Llame a la clase POJO para implementar la interfaz de serialización
Para extraer datos en caché, se realizan operaciones de deserialización, porque los medios de almacenamiento de datos en caché secundarios son diversos y diferentes en la memoria.
Prueba de caché de nivel 2
@TestPublic Void testCache2 () lanza la excepción {SQLSession SqlSession1 = SqlSession.Apensession (); SqlSession SqlSession2 = SqlSessionFactory.Opensession (); SqlSession SqlSession3 = SQLSessionFactory.Opensession sqlsession1.getMapper (usermapper.class); // inicia la primera solicitud y consulta al usuario con ID 1 usuario user1 = usermapper1.finduserByid (1); system.out.println (user1); // Ejecutar la operación de cierre aquí y escribir los datos en el sqlSession a la secundaria cache sqlsession1.cleCle ();) Ejecutar la operación commit () usermapper usermapper3 = sqlsession3.getMapper (usermapper.class); user user = usermapper3.finduserByid (1); user.setUsername ("Zhang mingming"); usermapper3.UpdateUser (user);/ejecute el cicebo segundo bajo userMapper sqlsession3.commit (); sqlsession3.close (); usermapper usermapper2 = sqlsession2.getMapper (usermapper.class); // Enviar la segunda solicitud para consultar al usuario con ID 1 usuario user2 = usermapper2.finduserByid (1); system.println (user2); sqlsession2.cleSession ();Configuración de USECACHE
Configurar useCache = false en la declaración puede deshabilitar el caché secundario de la instrucción SELECT actual, es decir, cada consulta emitirá SQL para consultar. El valor predeterminado es verdadero, es decir, el SQL usa caché secundario.
<select id = "findOrderListResultMap" resultMap = "OrderSUsermap" useCache = "false">
Resumen: para cada consulta, se requiere los últimos datos SQL. Configurarlo en useCache = false y deshabilitar el caché secundario.
Actualizar caché
Solo borra el caché
En el mismo espacio de nombres del mapeador, si hay otros datos de operación de inserción, actualización o eliminación, el caché debe actualizarse, y si el caché no se actualiza, se producirá una lectura sucia.
Establezca la propiedad flushcache = "true" en la configuración de la instrucción. Por defecto, es cierto, lo que significa que el caché se actualiza. Si se cambia a falso, no se actualizará. Al usar caché, se producirán lecturas sucias si modifica manualmente los datos de consulta en la tabla de la base de datos.
<inserto id = "insertuser" parametertype = "cn.itcast.mybatis.po.user" flushcache = "true">
Resumen: En general, después de ejecutar la operación de confirmación, el caché debe actualizarse. flushcache = verdadero significa refrescar el caché, lo que puede evitar la lectura sucia de la base de datos.
Integración mybatis ehcache
Ehcache es un marco de almacenamiento en caché distribuido.
分布缓存
我们系统为了提高系统并发,性能、一般对系统进行分布式部署(集群部署方式)
不使用分布缓存,缓存的数据在各各服务单独存储,不方便系统开发。所以要使用分布式缓存对缓存数据进行集中管理。
mybatis无法实现分布式缓存,需要和其它分布式缓存框架进行整合。
整合ehcache方法(掌握)
mybatis提供了一个cache接口,如果要实现自己的缓存逻辑,实现cache接口开发即可。
mybatis和ehcache整合,mybatis和ehcache整合包中提供了一个cache接口的实现类。
mybatis默认实现cache类是:
加入ehcache包
整合ehcache
配置mapper中cache中的type为ehcache对cache接口的实现类型。
加入ehcache的配置文件(在classpath下配置ehcache.xml)
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"><diskStore path="F:/develop/ehcache" /><defaultCache maxElementsInMemory="1000" maxElementsOnDisk="10000000"eternal="false" overflowToDisk="false" timeToIdleSeconds="120"timeToLiveSeconds="120" diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"></defaultCache></ehcache>
属性说明:
diskStore:指定数据在磁盘中的存储位置。
defaultCache:当借助CacheManager.add(“demoCache”)创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略
以下属性是必须的:
maxElementsInMemory - 在内存中缓存的element的最大数目
maxElementsOnDisk - 在磁盘上缓存的element的最大数目,若是0表示无穷大
eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断
overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上
以下属性是可选的:
timeToIdleSeconds - 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大
timeToLiveSeconds - 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大
diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区.
diskPersistent - 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。
diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s,相应的线程会进行一次EhCache中数据的清理工作
memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)
二级应用场景
对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术降低数据库访问量,提高访问速度,业务场景比如:耗时较高的统计分析sql、电话账单查询sql等。
实现方法如下:通过设置刷新间隔时间,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔flushInterval,比如设置为30分钟、60分钟、24小时等,根据需求而定。
二级缓存局限性
mybatis二级缓存对细粒度的数据级别的缓存实现不好,比如如下需求:对商品信息进行缓存,由于商品信息查询访问量大,但是要求用户每次都能查询最新的商品信息,此时如果使用mybatis的二级缓存就无法实现当一个商品变化时只刷新该商品的缓存信息而不刷新其它商品的信息,因为mybaits的二级缓存区域以mapper为单位划分,当一个商品信息变化会将所有商品信息的缓存数据全部清空。解决此类问题需要在业务层根据需求对数据有针对性缓存。