当前位置: 首页 > article >正文

MybatisPlus概述

MybatisPlus概述

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错

特点

  1. 无侵入

  2. BaseMapper(条件构造器)

  3. 内置分页

  4. 全局拦截插件

快速入门

1. 创建数据库

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user`
(
    id BIGINT NOT NULL COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);
INSERT INTO `user` (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

2. 初始化springboot项目

<!--连接数据库-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<!--mybatisPlus-->
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.2</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

3. 配置数据库连接对象

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    password: root
    username: root

4. 创建实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class User {
    private Long id;
    private String name;
    private int age;
    private String email;
}

5. 编写接口

@Repository
@Mapper
public interface UserMapper extends BaseMapper<User> {

}

6. test测试

@SpringBootTest
class MybatisplusApplicationTests {

    @Autowired
    private UserMapper userMapper;
    @Test
    void contextLoads() {
        List<User> userList = userMapper.selectList(null);
        userList.forEach(System.out::println);
    }

}

配置日志

我们所有的sql现在不可见,需要到日志功能

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

CRUD拓展

插入操作

插入

@Test
public void testInsert(){
    User user = new User();
    user.setName("张三");
    user.setAge(18);
    user.setEmail("123123@qq.com");

    int res = userMapper.insert(user);
    System.out.println(res);//受影响行数
    System.out.println(user);//id会自动回填
}

 数据库插入的id的默认值为:全局唯一的id

主键生成策略

默认 ASSIGN_ID

分布式系统唯一id生成策略:分布式系统唯一ID生成方案汇总 - nick hao - 博客园 (cnblogs.com)

雪花算法:

snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0,可以保证全球唯一。

主键自增

  1. 实体类字段上增加@TableId(type = IdType.AUTO)

  2. 数据库字段是自增的

  3. 再次测试插入

 其余源码解释

AUTO(0),//自增
NONE(1),//未设置主键
INPUT(2),//手动输入
ASSIGN_ID(3),//默认的全局id
ASSIGN_UUID(4);//全局唯一id  uuid

 更新操作

    public void testUpdate(){
        User user = new User();
        user.setId(6L);
        user.setName("李四");
        int res = userMapper.updateById(user);//虽然此时是byid,但传入的是一个对象
    }

 

 所有的sql都会自动动态给你配置

自动填充策略

创建时间,修改时间,这些操作都是自动完成的,我们不希望手动更新

阿里开发手册:所有的数据库表:gmt_create,gmt_modified几乎所有的表都具备,而且需要自动化。

数据库级别

1. 在表中新建字段create_time,update_time

2. 与实体类同步

代码级别

1. 删除数据库默认值

2.实体类的字段上增加注解

@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;

@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;

 3. 编写处理器处理注解

@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        //MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
        this.setFieldValByName("createTime", LocalDateTime.now(),metaObject);
        this.setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        this.setFieldValByName("updateTime",LocalDateTime.now(),metaObject);
    }
}

 乐观锁

乐观锁:无论出现什么问题都不会去上锁,如果出现问题就在测试加锁处理,再次更新值测试

悲观锁:无论干什么都会上锁

  • 取出记录时,获取当前 version

  • 更新时,带上这个 version

  • 执行更新时, set version = newVersion where version = oldVersion

  • 如果 version 不对,就更新失败

测试:

1. 数据库字段中增加version字段为1

2. 同步实体类

@Version
private Integer version;

3.  注册乐观锁组件

@EnableTransactionManagement
@Configuration
@MapperScan("com.sfy.mybatisplus.dao")
public class MybatisPlusConfig {
    //注册乐观锁插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

4. 测试:

成功案例:

@Test
public void TestOptimisticLocker(){
    User user = userMapper.selectById(6l);
    user.setName("王五");
    userMapper.updateById(user);
}

 

失败案例:

 此时可以使用自旋锁进行操作

@Test
public void TestOptimisticLocker2(){
    User user = userMapper.selectById(6l);
    user.setName("王五1");

    //模拟另一个线程插队
    User user1 = userMapper.selectById(6l);
    user1.setName("王五2");

    userMapper.updateById(user1);
    userMapper.updateById(user);//如果没有乐观锁就会覆盖插队线程

}

查询操作

1. 单次查询

User user = userMapper.selectById(1l);

2.  批量查询

List<User> users = userMapper.selectBatchIds(Arrays.asList(1l, 2l, 3l));

3.  条件查询

HashMap<String,Object> map = new HashMap<>();
map.put("name","张三");
List<User> users1 = userMapper.selectByMap(map);
users1.forEach(System.out::println);

 

会自动进行sql拼接

分页查询

  1. 使用limit语句

  2. 使用pageHelper

  3. MP中内置分页插件

1. 导入插件

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor2() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果配置多个插件,切记分页最后添加
    //interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 如果有多数据源可以不配具体类型 否则都建议配上具体的DbType
    return interceptor;
}

2. 直接使用即可

 在分页查询之间会进行一次查询总数

删除操作

1. 单条删除

userMapper.deleteById(1l);

2.  批量删除

userMapper.deleteBatchIds(Arrays.asList(1l, 2l, 3l));

3. 条件删除

HashMap<String, Object> map = new HashMap<>();
map.put("name","张三");
userMapper.selectByMap(map);

逻辑删除

物理删除:数据库字段被删除

逻辑删除:数据库字段并没有被删除,而是通过变量使他失效

管理员可以查看被删除得记录,防止数据得丢失,类似于回收站

1. 数据库中添加deleted字段,默认值为0;

2. 同步字段

@TableLogic
private Integer deleted;

 3. 配置yml文件

global-config:
    db-config:
      logic-delete-value: 1
      logic-not-delete-value: 0

4. 测试

实际上是进行了一次更新操作

条件构造器Wrapper

可以进行复杂得条件查询

allEq:条件进行拼接

eq:等于

ne:不等于

gt:大于

ge:大于等于

lt:小于

Ie:小于等于

between:范围查询

like:模糊查询

isNull:为空

in:设置条件得范围


http://www.kler.cn/a/158478.html

相关文章:

  • 保存数据到Oracle时报错ORA-17004: 列类型无效: 1111
  • Nuxt3 动态路由URL不更改的前提下参数更新,NuxtLink不刷新不跳转,生命周期无响应解决方案
  • 任务管理功能拆解——如何高效管理项目任务?
  • 【会话文本nlp】对话文本解析库pyconverse使用教程版本报错、模型下载等问题解决超参数调试
  • 【分布式技术】ES扩展知识-Elasticsearch分词器的知识与选择
  • python+Django+MySQL+echarts+bootstrap制作的教学质量评价系统,包括学生、老师、管理员三种角色
  • c题目16:写一个递归函数,计算N阶乘
  • 智能优化算法应用:基于类电磁机制算法无线传感器网络(WSN)覆盖优化 - 附代码
  • 用友U8 Cloud RegisterServlet SQL注入漏洞复现
  • 高低压供配电智能监控系统
  • ARM64安全特性之CET
  • java连接池 理解及解释(DBCP、druid、c3p0、HikariCP)
  • Debian 终端Shell命令行长路径改为短路径
  • 【Maven】更新依赖索引
  • LeetCode-478. 在圆内随机生成点【几何 数学 拒绝采样 随机化】
  • 深入浅出 Linux 中的 ARM IOMMU SMMU III
  • 【Python函数】魔法函数
  • 如何写一个吸引人的标题?
  • copilot的使用
  • 钉钉员工组织资料实时同步至飞书的应用解析
  • C#Backgroundworker与Thread的区别
  • 解决ssr服务端渲染程序启动报错: ReferenceError: location is not defined
  • minio配置监听(对象操作日志)
  • 连接池 Druid (四) - 连接归还
  • Vue3 pinia的基本使用
  • Squid安装与配置(ip代理)