Mybatis-Plus入门笔记

本文是Mybatis-Plus的入门教程,涵盖配置启动、分布式ID生成方案(如Twitter的Snowflake算法)、自动填充处理、乐观锁机制、常规查询与分页查询、以及删除操作(包括逻辑删除)。文章还讨论了如何在数据库中设置默认值以及在Java实体类中添加注解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

快速开始

	本篇文章是在哔哩哔哩秦疆老师的mybatisplus教程下做的笔记,并且插入了一些自己的理解。
	1. 新建springboot项目导入pom依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.example</groupId>
    <artifactId>mybatisplus01</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--mybatis-plus 导入了这个就不能导入mybatis了             3.0.5-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <!--处理jar包冲突-->
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        
        <!--thymeleaf-->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>ava
在这里插入代码片
  1. 改配置 application.properties,yml文件也行
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.url=jdbc:mysql:///mybatisplus?serverTimezone=UTC&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

#默认日志,其它的要导依赖。你也可以用别的日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

server.port=8081
  1. 在类路径下新建pojo包存放数据,再建一个User类
@Data  //我这里是安装了lombok插件的,没安装自己手动生成getter,setter,tostring还有构造。
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

  1. 在类路径下新建mapper包,再建一个UserMapper接口
//在对应的mapper上继承BaseMapper<T>接口
@Repository
public interface UserMapper extends BaseMapper<User> {
	//BaseMapper点进去,你会发现它已经帮你做好了sql操作CRUD相应的方法。
}
  1. 建立数据库
create database mybatisplus;
use mybatisplus;
CREATE TABLE user
(
	id BIGINT(20) NOT NULL COMMENT '主键ID',
	name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
	age INT(11) 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');

  1. 测试
//注意注意注意注意注意注意注意注意注意注意注意注意
//测试前给主启动类加上@MapperScan("com.example.mybatisplus.mapper")开启包扫描
@SpringBootTest
public class MybatisPlus01ApplicationTest {

    @Autowired
    UserMapper userMapper;

    //查询测试
    @Test
    void contextLoads(){
        //这里条件为null查所有
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }

    //插入测试
    @Test
    void testInsert(){
        User user =new User();
        user.setName("老王");
        user.setAge(22);
        user.setEmail("1231213@qq.com");

        //自动生成id
        int result = userMapper.insert(user);
        System.out.println(result);
        System.out.println(user);
    }
    //测试更新
    @Test
    void testUpdate(){
        User user =new User();

        user.setId(6L);//这个如果后面自动生成了主键要注释掉
        user.setName("老李");
        user.setAge(19);

        int i = userMapper.updateById(user);
        System.out.println(i);

    }
}

分布式系统唯一id生成方案

参考博客:https://www.cnblogs.com/haoxinyue/p/5208136.html](https://www.cnblogs.com/haoxinyue/p/5208136.html)
雪花算法:
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。具体实现的代码可以参看https://github.com/twitter/snowflake

 //注意在集群环境下用数据库的主键自增并不好,会出现单点故障。详情请参考上面博客
 //user类  对应数据库中的主键自动生成
    @TableId(type = IdType.ID_WORKER)
    private Long id;

自动填充处理

方案一、注意数据库最好不要轻易改动
1. 在数据库里user表新增两个日期类型字段create_time,update_time设置默认值
2. 在user类中加上添加好的字段,over
方案二、
1. 记得先去掉刚设置的默认值,在user类加上的字段上加上注解

// 字段添加填充内容
    @TableField(fill= FieldFill.INSERT)
    private Date createTime; //这里有个坑你这里这么写,你数据库的字段必须是create_time
    @TableField(fill= FieldFill.INSERT_UPDATE)
    private Date updateTime;
	2. 点进  FieldFill它是字段填充的意思
	@TableField("字段名")当数据库字段与类中不一样时也可以这样使用
public enum FieldFill {
    DEFAULT,	
    INSERT,		  //当执行insert语句时执行
    UPDATE,		  //当执行UPDATE语句时执行
    INSERT_UPDATE;//当执行insert和UPDATE语句时执行

    private FieldFill() {
    }
}
  1. 测试

乐观锁

	乐观锁 : 故名思意十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了
	问题,再次更新值测试
	悲观锁:故名思意十分悲观,它总是认为总是出现问题,无论干什么
	都会上锁!再去操作!
	乐观锁实现方式:
			取出记录时,获取当前 version
			更新时,带上这个version
			执行更新时,set version = newVersion where version = oldVersion
			如果version不对,就更新失败
			**乐观锁:先查询,获得版本号 version = 1
			-- A
			update user set name = "老李1111", version = version + 1
			where id = 2 and version = 1
			-- B 
			如果查询版本号也是1但此线程抢先完成,这个时候 version = 2,会导致 A 修改失败!
			update user set name = "老李2222", version = version + 1
			where id = 2 and version = 1**
	1.
	添加字段version int ,加上default约束
	添加默认约束语法:alter table user change column version version int default 1;
	删除默认约束语法:把default后面的值改成null就行
	2.
	在user类里把字段补上
	@Version   //乐观锁
     private Integer version;
     3.注册乐观锁插件
     类路径下新建config包,再新建MyBatisPlusConfig类,这个时候主启动类的包扫描注解就
     可以放到这里了
@MapperScan("com.example.mybatisplus.mapper")
@Configuration
public class MyBatisPlusConfig {
    // 注册乐观锁插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}
  1. 测试
    在测试类添加方法
// 测试乐观锁成功!
    @Test
    public void testOptimisticLocker(){
        // 1、查询用户信息
        User user=userMapper.selectById(1L);
        // 2、修改用户信息
        user.setName("老李111");
        user.setEmail("123123123@qq.com");
        // 3、执行更新操作,执行完这条语句你会发现version+1变成了2
        userMapper.updateById(user);
    }
    // 测试乐观锁失败!多线程下!
    @Test
    public void testOptimisticLocker2(){
        // 1、查询用户信息
        User user=userMapper.selectById(1L);
        // 2、修改用户信息
        user.setName("老李1111");
        user.setEmail("123123123@qq.com");
        // 3、执行更新操作

        // 模拟另外一个线程执行了插队操作
        User user2=userMapper.selectById(1L);
        user2.setName("老李2222");
        user2.setEmail("123123123@qq.com");
        userMapper.updateById(user2);//此时version=3

        // 可以尝试自旋锁来多次尝试提交!
        //执行到这里你会发现version本来是2但跟新两次应该是+了两次1可结果version却是3说明有一个没有执行。
        //再看name=“老李222”userMapper.updateById(user2);明明先执行却没有被 userMapper.updateById(user);覆盖
        //说明这里如果没有乐观锁就会覆盖插队线程的值!
        //此时version=3+1不等于3,所以被锁了。
        userMapper.updateById(user); 
    }

查询

常规查询
// 测试查询
    //这里提示看下源码,其实非常好懂。
    @Test
    public void testSelectById() {
        //查id=1的用户,看下日志里面有拼接好的sql
        User user = userMapper.selectById(1L);
        System.out.println(user);
    }

    // 测试批量查询!
    @Test
    public void testSelectByBatchId() {
        //查id=1 ro 2 ro 3
        //注意Arrays工具类是import java.util.Arrays;下的
        List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
        users.forEach(System.out::println);
    }

    // 按条件查询之一使用map操作
    @Test
    public void testSelectByBatchIds() {
        HashMap<String, Object> map = new HashMap<>();
        // 自定义查询  select * from where name = '老李222' and age = 19
        map.put("name", "老李222");
        map.put("age", 19);
        List<User> users = userMapper.selectByMap(map);
        users.forEach(System.out::println);
    }
分页查询(很重要)
		1. 配置拦截器组件(在MyBatisPlusConfig类里加如下代码)
// 分页插件(官网里有详细描述)
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
	 2. 测试类里使用内置page对象测试
// 测试分页查询
    @Test
    public void testPage() {
        //  参数一:当前页 参数二:页面大小
        //  使用了分页插件之后,所有的分页操作也变得简单的!
        Page<User> page = new Page<>(1, 3);
        userMapper.selectPage(page, null);
        //获取并输出所有数据
        page.getRecords().forEach(System.out::println);
        //总页数Total: 3
        System.out.println(page.getTotal());
    }

删除

常规删除
// 测试删除
    @Test
    public void testDeleteById() {
        userMapper.deleteById(1240620674645544965L);
    }

    // 通过id批量删除
    @Test
    public void testDeleteBatchId() {
        userMapper.deleteBatchIds(Arrays.asList(1L, 2L));
    }

    // 通过map自定义删除
    @Test
    public void testDeleteMap() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("name", "老李222");
        userMapper.deleteByMap(map);
    }
逻辑删除
	物理删除:从数据库中直接移除
	逻辑删除:在数据库中没有被移除,而是通过一个变量来让他失效! 假设这个变量为  deleted。
			我们通过一个update语句让原本deleted=0改为deleted=1让原本查询语句依赖这个
			deleted=0查询就查不到了。这就是所谓的逻辑删除!
			例:管理员可以查看被删除的记录!防止数据的丢失,类似于回收站!
1. 在数据表中增加一个 deleted 字段设为int,给个默认值0
2. user类里加上字段
    @TableLogic //逻辑删除:实际上只是把这个delete字段值改了一下让原本的查询语句查不出来
	private Integer deleted;
3. 配置  在MyBatisPlusConfig类加上如下代码
   // 逻辑删除组件!
    @Bean
    public ISqlInjector sqlInjector() {
        return new LogicSqlInjector();
    }
    
4. 然后在application.properties里添加配置
    #配置逻辑删除
 	#删除后的delete值设为1
	mybatis-plus.global-config.db-config.logic-delete-value=1
	#没删除前的delete值设为0
	mybatis-plus.global-config.db-config.logic-not-delete-value=0
5. 测试一下删除操作

好了入门篇就到这里,进阶篇等我至少做完一个相关项目再说。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值