Especifique o nome da tabela de banco de dados
@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";
Especifique o campo de chave primária
@TableId(value = "id", type = IdType.ASSIGN_ID) //生成id的类型:数据库自增(AUTO)、默认id生成器(ASSIGN_ID)、自定义id生成器(INPUT)
private Long id;
E campos de tabelas de mapeamento de atributo
@TableField(value = "content")
private String content;
A participação não é serializado, não como um campo de dados
private transient Integer eventId;
private static Integer eventId;
@TableField(exist = false)
private Integer eventId;
CRUD
condições construtor
com.baomidou.mybatisplus.core.conditions.AbstractWrapper
Capítulo 3 métodos de consulta MyBatis-Plus
Este capítulo apresenta as principais MyBatis-Plus conteúdo consultas, incluindo consulta geral, a condição de construtor de consulta, selecione a consulta não lista todos os campos e assim por diante.
QueryWrapper
new QueryWrapper<Event>().orderBy(true, !isDesc, orderBy)
.like(Boolean.valueOf(nameLike), searchName, searchValue);
- condição 3-5 construtor de consulta (4) (05:54)
- 3-6 selecionar todas as colunas não são listados (05:29)
Lista apenas o id eo campo proprietário
wrapper.select("id", "owner").likeLeft("owner", "sp").gt("level", 3);
Não proprietário da lista e campos de conteúdo (chave primária: id não terá efeito)
wrapper.likeLeft("owner", "sp").gt("level", 3)
.select(
Event.class
, info -> !info.getColumn().equals("owner") && !info.getColumn().equals("content"));
- 7/3 efeito condição (06:47)
- 3-8 condições de processo como uma entidade estrutural parâmetros do construtor (06:24)
- 3-9 uso AllEq (06:10)
- Outros métodos 3-10 (10:36) Condições construtor
- 3-11 condições lambda construtores (09:49)
consultas e paginação Capítulo 4 Personalização sql
Este capítulo descreve os MyBatis-Plus conteúdo personalizado e sql paginação consultas.
Capítulo 5 UPDATE e DELETE
Esta seção descreve como MyBatis-Plus atualização, e as funções de eliminação.
Modo AR Capítulo 6, as principais estratégias primárias e configuração básica
Este capítulo descreve os MyBatis-Plus no modo AR, as principais estratégias primárias e configuração básica e assim por diante.
@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);
}
PS:
forma Assembleia mapeador:
1, a interface de montagem anotações
@Mapper
public interface EventMapper extends BaseMapper<Event> {
...
}
2, a montagem unificada
@EnableTransactionManagement
@Configuration
@MapperScan(value = {"ik.starriver.log.mapper*"})
public class MyBatisPlusAutoConfiguration {
....
}
definições de política local sobre a entidade mesa
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;
configurações de política global no arquivo de configuração
mybatis-plus:
global-config:
db-config:
id-type: ASSIGN_ID
modo multi-módulo: Para adicionar classpath volta "*"
mybatis-plus:
type-handlers-package: ik.starriver.log.handler*
mapper-locations: classpath*:/mapper*/*Mapper.xml #
estratégia de geração de campo (também pode ser fornecido localmente, topicamente do que global)
global-config:
db-config:
#未设置字段sql语句生成的策略 IGNORED:"直接设置为null",NOT_NULL:"可以插入设置的空字符串"),NOT_EMPTY:"未设置和空字符串都不会插入"
field-strategy: not_empty
Configuração 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
PS:
estratégia de geração de campo também afetará as entidades parâmetro invólucro
estratégia campo ignorado
instrução SQL não está definida em todo o nulo campos inserido
serviço Capítulo 7 Universal
Este capítulo descreve o conteúdo de um serviço geral.
MyBatis avançada
Capítulo 1 Visão geral
Este capítulo descreve os principais conteúdos do curso, o curso abrange a estrutura da tabela, e a situação básica do projeto.
Capítulo 2 lápide
Este capítulo fornece MyBatis-Plus informação na lápide.
Tombstone: false Delete (Excluir através da identificação de campo, para indicar a exclusão de dados ou não, não vai apagar os dados reais)
Definições globais Perfis
{
"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"
},
campo lápide notas
Excluir, operação de actualização é realmente o excluído é definido como 1, isso indica logicamente excluída
Todas as consultas retornar somente os dados apagados = 0
Da mesma forma Atualização
@TableField(select = false)
private Integer deleted;
selecionar excluir campo deletados sem inquérito
PS:
sql personalizado não terá efeito
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 excluído
Capítulo 3 autofill
Este capítulo fornece informações preenchidas automaticamente e otimização de MyBatis-Plus.
Afirmando a necessidade de campos preencher automaticamente
@TableField(fill = FieldFill.INSERT_UPDATE)
private Timestamp createTime;
MetaObjectHandler implementar a interface, escrevendo a lógica de enchimento (nota: nome do campo nome do atributo java não é um nome de campo do banco de dados)
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())));
}
}
}
Chinês ilegível: characterEncoding = utf8
Erro tempo: serverTimezone = GMT% 2B8
banco de dados de determinada conexão 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";
Apenas indicação com campos createTime1 irá ser gerado automaticamente mediante tempo de inserção (guardando o overhead necessário para gerar automaticamente tempo)
Apenas o campo especificado não está definido valores quando a atualização, irá preencher automaticamente
Capítulo 4 bloqueio otimista
Este capítulo descreve a implementação MyBatis-Plus bloqueio otimista.
Leia bloqueio mais otimista em minúsculas
Escrever bloqueio de leitura menos pessimista
embalagem não pode ser reutilizado! ! ! !
Capítulo 5 Análise de Desempenho
Este capítulo descreve o desempenho de MyBatis-Plus análise, ajustes de parâmetros e realizar análises de impressão SQL e assim por diante.
@Bean
@Profile({"dev","test"})
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor interceptor = new PaginationInterceptor();
interceptor.setLimit(100);
interceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return interceptor;
}
PS:
https://mybatis.plus/guide/performance-analysis-plugin.html
Capítulo 6 multi-tenant
Este capítulo introduz o conceito de MyBatis-Plus multi-tenant e implementação.
Multi-tenancy:
Sub-bibliotecas, cada usuário de um banco de dados, segurança de dados, facilidade de recuperação
pontos de esquema de banco de dados unificadas
Unified banco de dados, esquema unificado, sub-mesa
@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, a tabela dinâmica
Este capítulo descreve a implementação e precauções MyBatis-Plus da tabela dinâmica.
estrutura de tabela mesmo, sub-tabela de armazenamento, como tabela de log por mês, outras tabelas parte por objeto a empresa
Capítulo 8 SQL Injector
Este dispositivo de injeção introduz capítulo SQL, e o conteúdo de anexos.
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);
}
}
Adicionados à lista de anotações é montado em container Spring IoC
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;
}
}
forma Fitting AutoConfiguration @Bean
@Bean
public DefaultSqlInjector defaultSqlInjector(){
CustomizedSqInjector defaultSqlInjector = new CustomizedSqInjector();
return defaultSqlInjector;
}
- 8-2 anexos InsertBatchSomeColumn (07:38)
- 8-3 选 装 importa LogicDeleteByIdWithFill (04:13)
- 8-4 选 装 件 alwaysUpdateSomeColumnById (03:53)
Tipo de campo Processor
@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;