Especificar el nombre de la tabla de base de datos
@TableName("tianshu_log_event")
//@IdClass(EventCompositePK.class) // 联合主键
public class Event implements Serializable {
private static final long serialVersionUID = 1L;
public static final String TABLE_NAME = "tianshu_log_event";
Especificar el campo de clave principal
@TableId(value = "id", type = IdType.ASSIGN_ID) //生成id的类型:数据库自增(AUTO)、默认id生成器(ASSIGN_ID)、自定义id生成器(INPUT)
private Long id;
Y campos de la tabla de asignación de atributos
@TableField(value = "content")
private String content;
La participación no es de serie, no como un campo de datos
private transient Integer eventId;
private static Integer eventId;
@TableField(exist = false)
private Integer eventId;
CRUD
condiciones constructor
com.baomidou.mybatisplus.core.conditions.AbstractWrapper
Capítulo 3 métodos de consulta MyBatis-Plus
Este capítulo presenta las principales MyBatis-Plus contenido de consultas, incluyendo consulta general, la condición de generador de consultas, seleccione la consulta no enumera todos los campos y así sucesivamente.
QueryWrapper
new QueryWrapper<Event>().orderBy(true, !isDesc, orderBy)
.like(Boolean.valueOf(nameLike), searchName, searchValue);
- condición 3-5 generador de consultas (4) (05:54)
- 3-6 seleccionar todas las columnas no se enumeran (05:29)
Lista sólo el ello y el campo propietario
wrapper.select("id", "owner").likeLeft("owner", "sp").gt("level", 3);
No hagas dueño de la lista y campos de contenido (clave principal: id no entra en vigor)
wrapper.likeLeft("owner", "sp").gt("level", 3)
.select(
Event.class
, info -> !info.getColumn().equals("owner") && !info.getColumn().equals("content"));
- 3-7 efecto condición (06:47)
- 3-8 condiciones de proceso como un estructurales parámetros entidad constructor (06:24)
- uso 3-9 AllEq (06:10)
- Otros métodos 3-10 (10:36) Condiciones constructor
- 3-11 condiciones lambda constructores (09:49)
consultas y paginación Capítulo 4 Personalización de SQL
En este capítulo se describen los MyBatis-Plus de contenido personalizado y SQL paginación consultas.
Capítulo 5 actualizar y borrar
Esta sección describe cómo MyBatis-Plus de actualización, y las funciones de borrado.
Capítulo 6 modo de AR, las estrategias claves primarias y configuración básica
En este capítulo se describen los MyBatis-Plus en el modo AR, las estrategias claves primarias y configuración básica y así sucesivamente.
@Mapper
public interface EventMapper extends BaseMapper<Event> {
...
}
public class Event extends Model<Event> implements Serializable {
private static final long serialVersionUID = 1L;
...
}
@Autowired
private Event event;
@GetMapping(path = "/ActiveRecord/{id}/")
public ResponseEntity activeRecord(@PathVariable Long id){
Event event = this.event.selectById(id);
return this.responseEntity.success(event);
}
PD:
de manera Asamblea asignador:
1, la interfaz del conjunto de anotaciones
@Mapper
public interface EventMapper extends BaseMapper<Event> {
...
}
2, unificado conjunto
@EnableTransactionManagement
@Configuration
@MapperScan(value = {"ik.starriver.log.mapper*"})
public class MyBatisPlusAutoConfiguration {
....
}
configuración de directiva local en la entidad tabla
public class Event extends Model<Event> implements Serializable {
@TableId(value = "id", type = IdType.ASSIGN_UUID) //生成id的类型:数据库自增(AUTO)、默认id生成器(ASSIGN_ID)、自定义id生成器(INPUT)
private Long id;
Configuración global de directivas en el fichero de configuración
mybatis-plus:
global-config:
db-config:
id-type: ASSIGN_ID
Modo multi-módulo: Para añadir la ruta de clase de vuelta "*"
mybatis-plus:
type-handlers-package: ik.starriver.log.handler*
mapper-locations: classpath*:/mapper*/*Mapper.xml #
estrategia de generación de campo (también puede proporcionarse localmente, tópicamente que global)
global-config:
db-config:
#未设置字段sql语句生成的策略 IGNORED:"直接设置为null",NOT_NULL:"可以插入设置的空字符串"),NOT_EMPTY:"未设置和空字符串都不会插入"
field-strategy: not_empty
Configuración local
@TableField(whereStrategy = FieldStrategy.IGNORED)
private String description;
2020-02-28 02:14:29.835 [DEBUG] [http-nio-9000-exec-1] ik.starriver.log.mapper.EventMapper.selectList:143 : ==> Preparing: SELECT id,content,create_time,description,level,owner FROM tianshu_log_event WHERE description=? AND level=?
2020-02-28 02:14:29.851 [DEBUG] [http-nio-9000-exec-1] ik.starriver.log.mapper.EventMapper.selectList:143 : ==> Parameters: null, 3(Integer)
2020-02-28 02:14:29.937 [DEBUG] [http-nio-9000-exec-1] ik.starriver.log.mapper.EventMapper.selectList:143 : <== Total: 0
PD:
estrategia de generación de campo también afectará a las entidades de parámetro envoltorio
estrategia de campo ignorado
instrucción SQL no se encuentra en todos los campos nulos insertados
Capítulo 7 servicio universal
En este capítulo se describe el contenido de un servicio general.
mybatis avanzada
Capítulo 1 Descripción general
En este capítulo se describen los principales contenidos de la asignatura, el curso cubre la estructura de la tabla, y la situación básica del proyecto.
Capítulo 2 lápida
En este capítulo se proporciona información MyBatis-Plus en la lápida.
Lápida: falso Eliminar (Delete mediante la identificación de campo, para indicar la eliminación de datos o no, no se eliminarán los datos reales)
Configuración global Perfiles
{
"name": "mybatis-plus.global-config.db-config.logic-delete-value",
"type": "java.lang.String",
"sourceType": "com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig"
},
{
"name": "mybatis-plus.global-config.db-config.logic-not-delete-value",
"type": "java.lang.String",
"sourceType": "com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig"
},
Notas de campo lápida
Eliminar, operación de actualización es en realidad el borrado se establece en 1, indica lógicamente borrado
Todas las consultas sólo se borran los datos de retorno = 0
Del mismo modo actualización
@TableField(select = false)
private Integer deleted;
seleccionar excluir campo borrado sin consulta
PD:
SQL personalizado no tiene efecto
public interface EventMapper extends BaseMapper<Event> {
@Select("select id, content from tianshu_log_event where id = #{id}")
Event selectByIdSQL(Long id);
Filtro auto-campo para ser borrado
Capítulo 3 autofill
En este capítulo se proporciona información rellena automáticamente y optimización de MyBatis-Plus.
Afirmando la necesidad de poblar campos de forma automática
@TableField(fill = FieldFill.INSERT_UPDATE)
private Timestamp createTime;
MetaObjectHandler implementa la interfaz, escribir la lógica de llenado (nota: nombre de campo nombre de atributo java no es un nombre de campo de base de datos)
package ik.starriver.log.autoconfigure;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
@Component
public class DefaultMetaObjectHandler implements MetaObjectHandler {
private static final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
@Override
public void insertFill(MetaObject metaObject) {
boolean createTime = metaObject.hasSetter("createTime");
Object objVal = getFieldValByName("createTime", metaObject);
if (createTime && null == objVal){
this.strictInsertFill(metaObject,"createTime", Timestamp.class, Timestamp.valueOf(formatter.format(System.currentTimeMillis())));
}
}
@Override
public void updateFill(MetaObject metaObject) {
boolean createTime = metaObject.hasSetter("createTime");
Object objVal = getFieldValByName("createTime", metaObject);
if (createTime && null == objVal){
this.strictUpdateFill(metaObject,"createTime", Timestamp.class, Timestamp.valueOf(formatter.format(System.currentTimeMillis())));
}
}
}
Chino ilegible: characterEncoding = UTF-8
Tiempo de error: serverTimezone = GMT% 2B8
Dada la conexión de base de datos SSL: useSSL = false
public class ApplicationAutoConfiguration {
private final static String DATABASE_URL = "jdbc:mysql://10.1.252.23:3306/springtest?serverTimezone=GMT&useSSL=false&characterEncoding=utf8";
Sólo comunicado con campos createTime1 se generará de forma automática al momento de la inserción (ahorro de la sobrecarga necesaria para generar automáticamente el tiempo)
Sólo el campo especificado no se ha establecido valores cuando la actualización, se encargará de autocompletar
Capítulo 4 bloqueo optimista
En este capítulo se describe la implementación MyBatis-Plus bloqueo optimista.
Leer más optimista de bloqueo en minúsculas
Escribe bloqueo de lectura menos pesimista
envoltorio no pueden ser reutilizados! ! ! !
Análisis de rendimiento Capítulo 5
En este capítulo se describe el comportamiento de MyBatis-Plus análisis, ajustes de los parámetros y realizar el análisis de la impresión del sql y así sucesivamente.
@Bean
@Profile({"dev","test"})
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor interceptor = new PaginationInterceptor();
interceptor.setLimit(100);
interceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return interceptor;
}
PD:
https://mybatis.plus/guide/performance-analysis-plugin.html
Capítulo 6 de múltiples usuarios
En este capítulo se introduce el concepto de MyBatis-Plus múltiples usuarios y ejecución.
Multitenencia:
Sub-bibliotecas, cada usuario de una base de datos, seguridad de datos, facilidad de recuperación
puntos de esquema de base de datos unificadas
la base de datos unificada, esquema unificado, subtabla
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
/*
* 【测试多租户】 SQL 解析处理拦截器<br>
* 这里固定写成住户 1 实际情况你可以从cookie读取,因此数据看不到 【 麻花藤 】 这条记录( 注意观察 SQL )<br>
*/
List<ISqlParser> sqlParserList = new ArrayList<>();
TenantSqlParser tenantSqlParser = new MyTenantParser();
tenantSqlParser.setTenantHandler(new TenantHandler() {
/**
* 2019-8-1
*
* https://gitee.com/baomidou/mybatis-plus/issues/IZZ3M
*
* tenant_id in (1,2)
* @param where 如果是where,可以追加,不是where的情况:比如当insert时,不能insert into user(name, tenant_id) values('test', tenant_id IN (1, 2));
* @return
*/
@Override
public Expression getTenantId(boolean where) {
final boolean multipleTenantIds = true;//这里只是演示切换单个tenantId和多个tenantId
//具体场景,可以根据情况来拼接
if (where && multipleTenantIds) {
//演示如何实现tenant_id in (1,2)
return multipleTenantIdCondition();
} else {
//演示:tenant_id=1
return singleTenantIdCondition();
}
}
private Expression singleTenantIdCondition() {
return new LongValue(1);//ID自己想办法获取到
}
private Expression multipleTenantIdCondition() {
final InExpression inExpression = new InExpression();
inExpression.setLeftExpression(new Column(getTenantIdColumn()));
final ExpressionList itemsList = new ExpressionList();
final List<Expression> inValues = new ArrayList<>(2);
inValues.add(new LongValue(1));//ID自己想办法获取到
inValues.add(new LongValue(2));
itemsList.setExpressions(inValues);
inExpression.setRightItemsList(itemsList);
return inExpression;
}
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
@Override
public boolean doTableFilter(String tableName) {
// 这里可以判断是否过滤表
/*if ("user".equals(tableName)) {
return true;
}*/
// return false;
return !"user".equalsIgnoreCase(tableName);
}
});
sqlParserList.add(tenantSqlParser);
paginationInterceptor.setSqlParserList(sqlParserList);
// paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() {
// @Override
// public boolean doFilter(MetaObject metaObject) {
// MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
// // 过滤自定义查询此时无租户信息约束【 麻花藤 】出现
// if ("com.baomidou.springboot.mapper.UserMapper.selectListBySQL".equals(ms.getId())) {
// return true;
// }
// return false;
// }
// });
return paginationInterceptor;
}
Capítulo 7, tabla dinámica
En este capítulo se describe la implementación y precauciones MyBatis-Plus tabla dinámica.
misma estructura de la tabla, el almacenamiento sub-tabla, como tabla de registro por mes, otra pieza tablas por objeto la empresa
Capítulo 8 SQL inyector
Este dispositivo de inyección SQL capítulo introduce, y el contenido de los archivos adjuntos.
método personalizado
package ik.starriver.log.sqlinjector.methods;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
public class DeleteAllMethod extends AbstractMethod {
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
String mapperName = "deleteAll";
String sql = "DELETE FROM " + tableInfo.getTableName();
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return addDeleteMappedStatement(mapperClass,mapperName,sqlSource);
}
}
Añadido a la lista de anotaciones se monta en un contenedor IoC primavera
package ik.starriver.log.sqlinjector;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import ik.starriver.log.sqlinjector.methods.DeleteAllMethod;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class CustomizedSqInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
methodList.add(new DeleteAllMethod());
return methodList;
}
}
de manera Montaje de configuración automática @Bean
@Bean
public DefaultSqlInjector defaultSqlInjector(){
CustomizedSqInjector defaultSqlInjector = new CustomizedSqInjector();
return defaultSqlInjector;
}
- 8-2 adjuntos InsertBatchSomeColumn (07:38)
- 8-3 选 装 materia LogicDeleteByIdWithFill (04:13)
- 8-4 选 装 件 alwaysUpdateSomeColumnById (03:53)
Procesador Tipo de campo
@Data
@Accessors(chain = true)
@TableName(autoResultMap = true)
public class User {
private Long id;
...
/**
* 注意!! 必须开启映射注解
*
* @TableName(autoResultMap = true)
*
* 以下两种类型处理器,二选一 也可以同时存在
*
* 注意!!选择对应的 JSON 处理器也必须存在对应 JSON 解析依赖包
*/
@TableField(typeHandler = JacksonTypeHandler.class)
// @TableField(typeHandler = FastjsonTypeHandler.class)
private OtherInfo otherInfo;
}
@TableName(value = "tianshu_log_event"
, autoResultMap = true
)
public class Event extends BaseModel {
/**
* 注意!! 必须开启映射注解
*
* @TableName(autoResultMap = true)
*
* 以下两种类型处理器,二选一 也可以同时存在
*
* 注意!!选择对应的 JSON 处理器也必须存在对应 JSON 解析依赖包
*/
@JsonDeserialize(using = EventLevelDeserializer.class)
@TableField(typeHandler = EventLevelHandler.class) //开启autoResultMap后才能使用调到指定的handler
@JsonSerialize(using = EventLevelSerializer.class)
private EventLevelEnum level;