Mybatisplus-【1/3】基础
  TEZNKK3IfmPf 2023年11月14日 38 0

项目应用实践:​​基于grpc从零开始搭建一个准生产分布式应用(0) - quickStart​​ 

也是属于闲来无事吧,这个插件的出镜率还是很高的,所以挑重点记录一下。供日后开发参考,笔者是采用的springboot-starter的方式进行的集成。

Maven引入

--因为这是非官方的插件,所以需要在maven的setting文件中配置如下仓库。
<repository>
<id>snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>

项目的pom.xml文件引入如下:

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/>
</parent>
<!--spring-boot安装和配置-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
</dependencies>

spring-boot配置yml文件

<!--application.yml-->
# DataSource Config
spring:
datasource:
driver-class-name: org.h2.Driver
schema: classpath:db/schema-h2.sql
data: classpath:db/data-h2.sql
url: jdbc:h2:mem:test
username: root
password: test

插件全局配置类

@Bean
public GlobalConfig globalConfig() {
GlobalConfig conf = new GlobalConfig();
conf.setDbConfig(new GlobalConfig.DbConfig().setColumnFormat("`%s`"));
DefaultSqlInjector logicSqlInjector = new DefaultSqlInjector() {
/**
* 注入自定义全局方法
*/
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
// 不要逻辑删除字段, 不要乐观锁字段, 不要填充策略是 UPDATE 的字段
methodList.add(new InsertBatchSomeColumn(t -> !t.isLogicDelete() && !t.isVersion() && t.getFieldFill() != FieldFill.UPDATE));
// 不要填充策略是 INSERT 的字段, 不要字段名是 column4 的字段
methodList.add(new AlwaysUpdateSomeColumnById(t -> t.getFieldFill() != FieldFill.INSERT && !t.getProperty().equals("column4")));
return methodList;
}
};
conf.setSqlInjector(logicSqlInjector);
return conf;
}

简单实现

实体类

@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("t_case")
public class UserEntity {
private Long id;
private String name;
private Integer age;
private String email;
}
public interface UserMapper extends BaseMapper<UserEntity> {
}

dao实现

public interface IUserDao extends IService<UserEntity>
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
public class UserDaoImpl extends ServiceImpl<UserMapper, UserEntity> implements IUserDao

spring启动类

@SpringBootApplication
@MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

二、安装maven-test-plug

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter-test</artifactId>
<version>3.5.1</version>
</dependency>
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import static org.assertj.core.api.Assertions.assertThat;
@MybatisPlusTest
class MybatisPlusSampleTest {
@Autowired
private SampleMapper sampleMapper;
@Test
void testInsert() {
Sample sample = new Sample();
sampleMapper.insert(sample);
assertThat(sample.getId()).isNotNull();
}
}

三、注解

@TableName

描述:表名注解,标识实体类对应的表,使用位置:实体类

@TableName("sys_user")
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}

@TableId

描述:主键注解,使用位置:实体类主键字段

@TableName("sys_user")
public class User {
@TableId
private Long id;
private String name;
private Integer age;
private String email;
}

value==主键字段名;type==指定主键类型(默认值IdType.NONE),IdType的可选值

  • -->AUTO:数据库 ID 自增
  • -->NONE:insert 前自行 set 主键值
  • -->INPUT:insert 前自行 set 主键值
  • -->ASSIGN_ID:分配 ID(主键类型为 Number(Long 和 Integer)或 String),使用接口IdentifierGenerator的方法nextId(默认实现类DefaultIdentifierGenerator雪花算法)
  • -->ASSIGN_UUID:分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认 default 方法)

@TableField

字段注解(非主键)

@TableName("sys_user")
public class User {
@TableId
private Long id;
@TableFiled("nickname")
private String name;
private Integer age;
private String email;
}
  • value:默认为“”, 数据库字段名
  • exist:默认为true,是否为数据库表字段
  • condition:默认为“”,字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s}
  • update:默认为“”,字段 update set 部分注入,例如:当在version字段上注解update="%s+1" 表示更新时会 set version=version+1 (该属性优先级高于 el 属性)
  • insertStrategy:默认值FieldStrategy.DEFAULT,当值为NOT_NULL时,则生成的语句如下:insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>)
  • updateStrategy:FieldStrategy.DEFAULT,举例:当值为IGNORED时,则生成的语句为update table_a set column=#{columnProperty}
  • whereStrategy:默认值FieldStrategy.DEFAULT,当NOT_EMPTY时,生成语句为where <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
  1. IGNORED:忽略判断
  2. NOT_NULL:非 NULL 判断
  3. NOT_EMPTY:非空判断(只对字符串类型字段,其他类型字段依然为非 NULL 判断)
  4. DEFAULT:追随全局配置
  • fill:默认值为FieldFill.DEFAULT,字段自动填充策略
  1. DEFAULT:默认不处理
  2. INSERT:插入时填充字段
  3. UPDATE:更新时填充字段
  4. INSERT_UPDATE:插入和更新时填充字段
  • select:是否进行 select 查询,默认为ture
  • keepGlobalFormat:是否保持使用全局的 format 进行处理,默认为false
  • typeHandler:Class<? extends TypeHandler>,默认值为UnknownTypeHandler.class, 类型处理器 (该默认值不代表会按照该值生效)

@Version

描述:乐观锁注解、标记 @Verison 在字段上

@EnumValue

描述:普通枚举类注解(注解在枚举字段上)

@TableLogic

描述:表字段逻辑处理注解(逻辑删除)

属性

类型

必须指定

默认值

描述

value

String

""

逻辑未删除值

delval

String

""

逻辑删除值

@OrderBy

描述:内置 SQL 默认指定排序,优先级低于 wrapper 条件查询

属性

类型

必须指定

默认值

描述

isDesc

boolean

true

是否倒序查询

sort

short

Short.MAX_VALUE

数字越小越靠前

四、mybatis缓存

一般在开发时不太需要关注的,这里只是简单描述下其原理。Mybatis 中有一级缓存和二级缓存,默认情况下一级缓存是开启的,而且不能关闭。一级缓存是指 SqlSession 级别的缓存,当在同一个 SqlSession 中进行相同的 SQL 语句查询时,第二次以后的查询不会从数据库查询,而是直接从缓存中获取,一级缓存最多缓存 1024 条 SQL。二级缓存是指可以跨 SqlSession 的缓存。是 mapper 级别的缓存,对于 mapper 级别的缓存不同的 sqlsession 是可以共享的。整体结构如下图所示:

Mybatisplus-【1/3】基础

一级缓存-sqlsession

第一次发出一个查询 sql,sql 查询结果写入 sqlsession 的一级缓存中,缓存使用的数据结构是一个 map,格式为:

{key:MapperID+offset+limit+Sql+所有的入参;value:结果数据}

同一个 sqlsession 再次发出相同的 sql,就从缓存中取出数据。如果两次中间出现 commit 操作 (修改、添加、删除),本 sqlsession 中的一级缓存区域全部清空,下次再去查询先从数据库查询,从数据库查询到再写入缓存。

二级缓存-mapper

二级缓存的范围是 mapper 级别(mapper 同一个命名空间),mapper 以命名空间为单位创建缓存数据结构,结构是 map。mybatis 的二级缓存是通过 CacheExecutor 实现的。CacheExecutor其实是 Executor 的代理对象。所有的查询操作,在 CacheExecutor 中都会先匹配缓存中是否存在,不存在则查询数据库,格式为{key:MapperID+offset+limit+Sql+所有的入参},具体使用需要配置:

  • Mybatis 全局配置中启用二级缓存配置;
  • 在对应的 Mapper.xml 中配置 cache 节点;
  • 在对应的 select 查询节点中添加 useCache=true
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月14日 0

暂无评论