你最愿意做的哪件事,才是你的天赋所在

0%

mybatis-plus

Mybatis-Plus

Quick-Start

导入包

1
2
3
4
5
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>

配置数据库

1
2
3
4
5
6
7
spring.datasource.username=root
spring.datasource.password=709508
spring.datasource.url=jdbc:mysql://localhost:3306/mybatisplus
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# 配置日志输出的位置
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

创建对应的实体类

1
2
3
4
5
6
7
8
9
10
11
public class User {
// 主键自增,不需要配置
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
@Version
// 乐观锁配置版本号
private Integer version;
}

创建接口集成BaseMapper

1
2
3
public interface UserMapper extends BaseMapper<User> {

}
1
2
3
4
5
6
7
8
@Autowired
UserMapper userMapper;
@Test
void contextLoads() {
User user = userMapper.selectById(1L);
user.setName("123");
userMapper.updateById(user);
}

然后直接使用即可

乐观锁与悲观锁

乐观锁

乐观锁(Optimistic Lock),每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。乐观锁适用于读多写少的应用场景,这样可以提高吞吐量

乐观锁实现

  • 取出记录的时候取出version
  • 更新时,带上version更新
  • 执行更新的时候 执行 set version = newVersion where version = oldVersion
  • 如果version不存在,那么更新失败

这样做的话即很乐观, 出现了类似乌托邦的假象, 没有除了我之外的人来更新这个记录

Mybatisplus 实现乐观锁

  • 打开乐观锁插件
1
2
3
4
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
  • 在version字字段上加上注释@Version
1
2
3
4
5
6
7
8
9
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
@Version
private Integer version;
}

条件查询

通过Map进行条件查询

1
2
3
4
5
6
7
8
9
10
11
@Test
void test(){
// 线程1
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
HashMap<String, Object> map = new HashMap<>();
map.put("name","tom");
map.put("age",28);
List<User> userList = userMapper.selectByMap(map);
userList.forEach(System.out::println);
}
1
2
3
4
5
==>  Preparing: SELECT id,name,age,email,version FROM user WHERE id IN ( ? , ? , ? )
==> Parameters: 1(Integer), 2(Integer), 3(Integer)

==> Preparing: SELECT id,name,age,email,version FROM user WHERE name = ? AND age = ?
==> Parameters: tom(String), 28(Integer)

分页查询

  • 注册分页插件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Bean
    public PaginationInterceptor paginationInterceptor() {
    PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
    // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
    // paginationInterceptor.setOverflow(false);
    // 设置最大单页限制数量,默认 500 条,-1 不受限制
    // paginationInterceptor.setLimit(500);
    // 开启 count 的 join 优化,只针对部分 left join
    paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
    return paginationInterceptor;
    }
  • 使用Page对象进行分页

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void test1(){
    // 参数1: 当前页面
    // 参数2: 页面大小
    Page<User> page = new Page<>(2,5);
    userMapper.selectPage(page, null);
    page.getRecords().forEach(System.out::println);
    }
    ==> Preparing: SELECT id,name,age,email,version FROM user LIMIT ?,?
    ==> Parameters: 5(Long), 5(Long)
    <== Columns: id, name, age, email, version
    <== Row: 101, Fuxuanwei, 16, null, 1
    <== Row: 1320910446370365442, Fuxuanwei, 16, null, 1
    <== Total: 2

删除操作

物理删除

1
2
3
4
@Test
void deleteTest(){
userMapper.deleteById(1);
}

逻辑删除

在表中不进行删除,在逻辑上被删除了.在数据库增加字段后,同步pojo类

1
2
@TableLogic
private Integer deleted;

在3.3.0版本之后的mybatis-plus都不需要注入bean了

设置删除值和不删除的值

1
2
mybatis-plus.global-config.db-config.logic-delete-field=0
mybatis-plus.global-config.db-config.logic-not-delete-value=1

这种情况一般在没有管理数据库权限的情况下使用

SQL性能分析插件

在mybatis3.3.0之后 使用了p6spy进行分析

1
2
3
4
5
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.9.1</version>
</dependency>

将连接数据库的参数修改一下

1
2
3
4
spring.datasource.username=root
spring.datasource.password=709508
spring.datasource.url=jdbc:p6spy:mysql://localhost:3306/mybatisplus
spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver

新增一个spy.properties 在resources下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2

运行即可查看日志

1
2
Consume Time:6 ms 2020-10-28 01:06:38
Execute SQL:SELECT id,name,age,email,version,deleted FROM user WHERE id=2 AND deleted=1

条件构造器(Wrapper)

这里官方讲的非常详细,之后我会用上什么说什么 条件构造器

代码自动生成类似mybatis-generator

3.0.3后分离了,所以需要导入

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>

编写映射策略,然后直接运行即可!!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class MybatisGenrator {
public static void main(String[] args) {
AutoGenerator mpg = new AutoGenerator();
// 1. 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath+"/src/main/java");
gc.setAuthor("geray");
gc.setOpen(false);
gc.setFileOverride(true);
gc.setServiceName("%sService");// 去除Service的I前缀
gc.setIdType(IdType.AUTO);
gc.setDateType(DateType.ONLY_DATE);
mpg.setGlobalConfig(gc);
// 配置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/mybatisplus");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("709508");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName("mybatisplus");
pc.setParent("com.geray");
pc.setEntity("entity");
pc.setService("service");
pc.setController("controller");
pc.setMapper("mapper");
mpg.setPackageInfo(pc);
// 策略配置
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("user");// 设置要映射的表名
strategy.setNaming(NamingStrategy.underline_to_camel); // 类驼峰命名
strategy.setColumnNaming(NamingStrategy.underline_to_camel); // 属性驼峰命名
strategy.setEntityLombokModel(true);// lombok
strategy.setLogicDeleteFieldName("deleted");// 逻辑删除
TableFill gmt_create = new TableFill("gmt_create", FieldFill.INSERT);// 自动填充
TableFill gmt_modify = new TableFill("gmt_modify", FieldFill.INSERT_UPDATE);// 自动填充设置
strategy.setTableFillList(Arrays.asList(gmt_create,gmt_modify));
// 设置乐观锁
strategy.setVersionFieldName("version");
strategy.setControllerMappingHyphenStyle(true);// 连接请求localhost:8080/hello
mpg.setStrategy(strategy);
mpg.execute();
}

}

image-20201028014413242

-------------你最愿意做的哪件事才是你的天赋所在-------------