MyBatis-Plus --- MyBatis aprimorada

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);

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"));

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;
    }

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;

 

Publicado 105 artigos originais · ganhou elogios 33 · vê 30000 +

Acho que você gosta

Origin blog.csdn.net/github_38596081/article/details/104526455
Recomendado
Clasificación