En el desarrollo diario, debería poder encontrar que el código de función CRUD de una sola tabla es muy repetitivo y no difícil. Esta parte del código suele ser relativamente grande y su desarrollo requiere mucho tiempo.
Por lo tanto, algunos componentes se utilizan actualmente en las empresas para simplificar u omitir el trabajo de desarrollo CRUD de una sola tabla. Uno de los componentes que actualmente se utiliza más en China es MybatisPlus.
El sitio web oficial es el siguiente:
Por supuesto, MybatisPlus no solo simplifica las operaciones de una sola tabla, sino que también tiene muchas mejoras en las funciones de Mybatis. Puede hacer que nuestro desarrollo sea más simple y más eficiente.
A través del estudio de hoy, lograremos los siguientes objetivos:
-
Puede usar MybatisPlus para implementar CRUD básico
-
Utilizará construcción condicional para crear consultas y actualizar declaraciones.
-
Utilizará anotaciones comunes en MybatisPlus.
-
Utilizará MybatisPlus para procesar enumeraciones y campos de tipo JSON.
-
Utilizará MybatisPlus para implementar la paginación.
Para facilitar las pruebas, primero creamos un nuevo proyecto y preparamos algunos datos básicos.
1.Preparación del entorno
Copie un proyecto proporcionado en el material previo al curso a su espacio de trabajo (no incluya espacios ni caracteres especiales):
Luego ábrelo con tu herramienta IDEA. La estructura del proyecto es la siguiente:
Preste atención a configurar la versión JDK del proyecto en JDK11. Primero haga clic en la configuración de la estructura del proyecto:
Configure JDK en la ventana emergente:
A continuación, necesitamos importar dos tablas. Los archivos SQL se proporcionan en los materiales previos a la clase:
La estructura de la tabla de la base de datos correspondiente es la siguiente:
Finalmente, application.yaml
modifique los parámetros de jdbc a los parámetros de su propia base de datos:
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: MySQL123
logging:
level:
com.itheima: debug
pattern:
dateformat: HH:mm:ss
2. Inicio rápido
Por ejemplo, si queremos implementar CRUD para la tabla Usuario, solo necesitamos los siguientes pasos:
-
Introducir la dependencia de MybatisPlus
-
Definir asignador
2.1 Introducir dependencias
MybatisPlus proporciona un iniciador para realizar la función de ensamblaje automático de Mybatis y MybatisPlus automáticos, las coordenadas son las siguientes:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
Dado que este arrancador contiene ensamblaje automático de mybatis, puede reemplazar completamente al arrancador Mybatis. En definitiva, las dependencias del proyecto son las siguientes:
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2.2 Definir asignador
Para simplificar CRUD de tabla única, MybatisPlus proporciona una BaseMapper
interfaz básica, que ya ha implementado CRUD de tabla única:
Por lo tanto, siempre que nuestro Mapper personalizado implemente esto BaseMapper
, no es necesario que implementemos CRUD de tabla única nosotros mismos. Modifique la interfaz com.itheima.mp.mapper
bajo el paquete en mp-demo UserMapper
y déjela heredar BaseMapper
:
El código se muestra a continuación:
package com.itheima.mp.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mp.domain.po.User;
public interface UserMapper extends BaseMapper<User> {
}
2.3 Pruebas
Cree una nueva clase de prueba, escriba varias pruebas unitarias y pruebe funciones CRUD básicas:
package com.itheima.mp.mapper;
import com.itheima.mp.domain.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.LocalDateTime;
import java.util.List;
@SpringBootTest
class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
void testInsert() {
User user = new User();
user.setId(5L);
user.setUsername("Lucy");
user.setPassword("123");
user.setPhone("18688990011");
user.setBalance(200);
user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");
user.setCreateTime(LocalDateTime.now());
user.setUpdateTime(LocalDateTime.now());
userMapper.insert(user);
}
@Test
void testSelectById() {
User user = userMapper.selectById(5L);
System.out.println("user = " + user);
}
@Test
void testSelectByIds() {
List<User> users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L, 5L));
users.forEach(System.out::println);
}
@Test
void testUpdateById() {
User user = new User();
user.setId(5L);
user.setBalance(20000);
userMapper.updateById(user);
}
@Test
void testDelete() {
userMapper.deleteById(5L);
}
}
Como puede ver, el registro SQL impreso durante el proceso de ejecución es muy estándar:
11:05:01 INFO 15524 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
11:05:02 INFO 15524 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
11:05:02 DEBUG 15524 --- [ main] c.i.mp.mapper.UserMapper.selectById : ==> Preparing: SELECT id,username,password,phone,info,status,balance,create_time,update_time FROM user WHERE id=?
11:05:02 DEBUG 15524 --- [ main] c.i.mp.mapper.UserMapper.selectById : ==> Parameters: 5(Long)
11:05:02 DEBUG 15524 --- [ main] c.i.mp.mapper.UserMapper.selectById : <== Total: 1
user = User(id=5, username=Lucy, password=123, phone=18688990011, info={"age": 21}, status=1, balance=20000, createTime=Fri Jun 30 11:02:30 CST 2023, updateTime=Fri Jun 30 11:02:30 CST 2023)
3. Anotaciones comunes
En el caso introductorio de ahora, solo introdujimos dependencias y heredamos BaseMapper para poder usar MybatisPlus, que es muy simple. Pero aquí viene la pregunta: ¿Cómo sabe MybatisPlus qué tabla queremos consultar? ¿Qué campos hay en la tabla?
Recuerde que UserMapper especificó un genérico al heredar BaseMapper:
El Usuario en el tipo genérico es el PO correspondiente a la base de datos.
MybatisPlus infiere información de la tabla basada en la información de la entidad PO para generar SQL. por defecto:
-
MybatisPlus convertirá el nombre de clase de la entidad PO a mayúsculas y minúsculas y lo subrayará como el nombre de la tabla.
-
MybatisPlus convertirá todos los nombres de variables de la entidad PO a mayúsculas y minúsculas y los subrayará como los nombres de campo de la tabla, e inferirá el tipo de campo según el tipo de variable.
-
MybatisPlus utilizará el campo denominado id como clave principal
Pero en muchos casos, la implementación predeterminada no coincide con el escenario real, por lo que MybatisPlus proporciona algunas anotaciones para facilitarnos la declaración de información de la tabla.
3.1@NombreTabla
ilustrar:
-
Descripción: Anotación del nombre de la tabla, que identifica la tabla correspondiente a la clase de entidad
-
Dónde usarlo: clase de entidad
Ejemplo:
@TableName("user")
public class User {
private Long id;
private String name;
}
Además de especificar el nombre de la tabla, la anotación TableName también puede especificar muchos otros atributos:
Atributos |
tipo |
Debe ser especificado |
valor por defecto |
describir |
valor |
Cadena |
No |
"" |
Nombre de la tabla |
esquema |
Cadena |
No |
"" |
esquema |
mantenerGlobalPrefix |
booleano |
No |
FALSO |
Si se debe seguir usando el valor global tablePrefix (cuando el valor global tablePrefix esté vigente) |
resultadoMapa |
Cadena |
No |
"" |
La identificación de resultMap en xml (usada para satisfacer tipos específicos de vinculación de objetos de clase de entidad) |
mapa de resultados automáticos |
booleano |
No |
FALSO |
Si se debe compilar y utilizar automáticamente resultMap (si se configura resultMap, no se realizará la construcción e inyección automática de resultMap) |
excluir propiedad |
Cadena[] |
No |
{} |
Nombres de atributos que deben excluirse@desde 3.3.1 |
3.2@ID de tabla
ilustrar:
-
Descripción: Anotación de clave principal, que identifica el campo de clave principal en la clase de entidad
-
Dónde utilizarlo: campo de clave principal de la clase de entidad
Ejemplo:
@TableName("user")
public class User {
@TableId
private Long id;
private String name;
}
TableId
Las anotaciones admiten dos propiedades:
Atributos |
tipo |
Debe ser especificado |
valor por defecto |
describir |
---|---|---|---|---|
valor |
Cadena |
No |
"" |
Nombre de la tabla |
tipo |
enumeración |
No |
Tipo de identificación.NINGUNO |
Especificar el tipo de clave principal |
IdType
Los tipos admitidos son:
valor |
describir |
---|---|
AUTO |
Incremento automático de ID de base de datos |
NINGUNO |
Sin estado, este tipo no tiene una clave principal establecida (la anotación equivale a seguir la global y la Rio global es aproximadamente igual a INPUT) |
APORTE |
Establezca el valor de la clave principal antes de insertar |
ASIGNAR_ID |
Asigne ID (el tipo de clave principal es Número (largo y entero) o Cadena) (desde 3.3.0), use el método nextId de la interfaz IdentifierGenerator (la clase de implementación predeterminada es el algoritmo de copo de nieve DefaultIdentifierGenerator) |
ASIGNAR_UUID |
Asigne UUID, el tipo de clave principal es String (desde 3.3.0), use el método nextUUID de la interfaz IdentifierGenerator (método predeterminado) |
|
Tipo de entero largo de ID único global distribuido (use ASSIGN_ID) |
|
Cadena UUID de 32 bits (use ASSIGN_UUID) |
|
Tipo de cadena de identificación única distribuida globalmente (use ASSIGN_ID) |
Hay tres comunes aquí:
-
AUTO
: Utilice la identificación de la base de datos para crecer automáticamente -
INPUT
: Generar identificación manualmente -
ASSIGN_ID
: El algoritmo de copo de nieve generaLong
una identificación global única para el tipo. Esta es la estrategia de identificación predeterminada.
3.3 @ campo de tabla
ilustrar:
Descripción: Anotaciones de campo comunes
Ejemplo:
@TableName("user")
public class User {
@TableId
private Long id;
private String name;
private Integer age;
@TableField("isMarried")
private Boolean isMarried;
@TableField("concat")
private String concat;
}
Generalmente, no necesitamos agregar @TableField
anotaciones a los campos, excepto en algunas circunstancias especiales:
-
El nombre de la variable miembro no coincide con el nombre del campo de la base de datos
-
Las variables miembro reciben
isXXX
su nombre y, segúnJavaBean
la especificación,MybatisPlus
se eliminarán al identificar camposis
, lo que genera inconsistencia con la base de datos. -
El nombre de la variable miembro es coherente con la base de datos, pero entra en conflicto con la palabra clave de la base de datos. Utilice
@TableField
anotaciones para agregar escapes ```` a los nombres de los campos
Otros atributos admitidos son los siguientes:
Atributos |
tipo |
Requerido |
valor por defecto |
describir |
valor |
Cadena |
No |
"" |
Nombre del campo de la base de datos |
existir |
booleano |
No |
verdadero |
Si es un campo de tabla de base de datos |
condición |
Cadena |
No |
"" |
Campo donde la entidad consulta la condición de comparación. Si hay un valor establecido, el valor establecido prevalecerá. De lo contrario, se utilizará el valor global predeterminado %s=#{%s}. Consulte (se abre en una ventana nueva ) |
actualizar |
Cadena |
No |
"" |
El conjunto de actualización de campos se inyecta parcialmente. Por ejemplo: al anotar update="%s+1" en el campo de versión indica que se establecerá version=version+1 al actualizar (este atributo tiene una prioridad más alta que el atributo el) |
insertarEstrategia |
enumeración |
No |
Estrategia de campo.DEFAULT |
Ejemplo: NOT_NULL insertar en table_a(<if test="columnProperty != null">columna</if>) valores (<if test="columnProperty != null">#{columnProperty}</if>) |
actualizarEstrategia |
enumeración |
No |
Estrategia de campo.DEFAULT |
Ejemplo: IGNORADO actualizar table_a set column=#{columnProperty} |
dondeEstrategia |
enumeración |
No |
Estrategia de campo.DEFAULT |
Ejemplo:NOT_EMPTY donde <if test="columnProperty != null and columnProperty!='">column=#{columnProperty}</if> |
llenar |
enumeración |
No |
FieldFill.DEFAULT |
Estrategia de autocompletar campos |
seleccionar |
booleano |
No |
verdadero |
Ya sea para realizar una consulta de selección |
mantener formato global |
booleano |
No |
FALSO |
Si se debe seguir usando el formato global para el procesamiento |
Tipo jdbc |
Tipo Jdbc |
No |
JdbcType.UNDEFINED |
Tipo JDBC (este valor predeterminado no significa que tendrá efecto según este valor) |
tipoHandler |
TypeHander |
No |
Escriba procesador (este valor predeterminado no significa que tendrá efecto de acuerdo con este valor) |
|
escala numérica |
Cadena |
No |
"" |
Especifique el número de dígitos que se conservarán después del punto decimal |
4. Configuraciones comunes
MybatisPlus también admite configuraciones personalizadas basadas en archivos yaml. Consulte la documentación oficial para obtener más detalles:
La mayoría de las configuraciones tienen valores predeterminados, por lo que no es necesario configurarlas. Pero también hay algunos que no tienen valor predeterminado, como por ejemplo:
-
Paquete de escaneo de alias para clases de entidad
-
tipo de identificación global
mybatis-plus:
type-aliases-package: com.itheima.mp.domain.po
global-config:
db-config:
id-type: auto # 全局id类型为自增长
Cabe señalar que MyBatisPlus también admite SQL escrito a mano y usted mismo puede configurar la dirección de lectura del archivo del mapeador:
mybatis-plus:
mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址,当前这个是默认值。
Puede ver que el valor predeterminado es classpath*:/mapper/**/*.xml
, lo que significa que siempre que coloquemos el archivo mapper.xml en este directorio, se cargará.
Por ejemplo, creemos un nuevo UserMapper.xml
archivo:
Luego defina un método en él:
<?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.itheima.mp.mapper.UserMapper">
<select id="queryById" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>
</mapper>
Luego UserMapperTest
pruebe el método en la clase de prueba:
@Test
void testQuery() {
User user = userMapper.queryById(1L);
System.out.println("user = " + user);
}