Mybatis-Plus教程

本文介绍MybatisPlus的基本概念及快速上手指南,演示如何利用MybatisPlus简化数据库操作,提高开发效率。涵盖数据库配置、实体类定义、Mapper接口创建及测试用例编写等内容。

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

Mybatis-Plus教程

1.Mybatis-Plus的简介

(写这篇博客时发现自己很多基础都忘了**JDBC,MYSQL,MYBATIS,**在我复习完这些时,争取写一篇MP源码级的教程)
MybatisPlus是一种为了简化开发,提高效率而制作的Mybatis的插件。主要用来屏蔽重复的Sql语句编写,使得开发人员可以使用编程(调方法)的方式来完成数据库中数据的CRUD操作。

// 查询表中一个信息
User user = userMapper.selectOne(new QueryWrapper<User>(
                User.builder().id(6l).build()
        ));
等价于 Select * from User where id = 6;
// 同时:userMapper.selectList();代表查询所有数据

通过调用方法来避免编写重复的Sql语句,更加符合业务程序员的习惯的风格。但是这种方式无异于让初学者逐渐丧失编写sql的能力,同时由于MybatisPlus中存在的些许小坑(这些坑大多是由于使用中忽略了MybatisPlus的一些规定,并非MP本身的缺陷),可能给实际项目中带来一些不太危险的后果。

  1. 我们是否应该学习MP
    不管你用不用MP,我都建议你学习一下MP
    • 学习成本并不高——通常16个小时足够学习结束
    • MP确实很实用和强大
  2. 是否应该使用MP
    如果你是团队中的某个成员,我不推荐日常开发中使用MP,因为这样会让你个人丧失战斗力。如果你是项目的负责人,从开发效率的角度可以使用,但是要对MP非常熟悉。
    总结一句话:应该学习,但不应该使用。

MP前言

MP支持的数据库:

  1. mysql 、postgresql 、oracle 。
  2. mariadb 、db2 、h2 、hsql 、sqlite 、、sqlserver 、presto 、Gauss 、Firebird
  3. Phoenix 、clickhouse 、Sybase ASE 、 OceanBase 、达梦数据库 、虚谷数据库 、人大金仓数据库 、南大通用数据库 。
    (很多数据库都没听过)

MP的架构

MP架构

Quick Start

  1. 数据准备
DROP TABLE IF EXISTS user;

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

DELETE FROM user;

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. 新建SpringBoot项目
  2. 实际编码
//1. 编写实体类
/**
 * @author :是雄不是熊
 * @date :Created in 2020/9/21 4:10 下午
 * @description:User
 * @modified By:
 * @version: $
 */
@Builder
@Data
@TableName
public class User {
    @TableId(value = "id", type = IdType.ASSIGN_ID/*, type = IdType.ASSIGN_ID*/)
    private Long id;
    @TableField(value = "name", fill = FieldFill.UPDATE/*, condition = SqlCondition.LIKE*/)
    private String name;
    @TableField(value = "age", update = "%s+1")
    private Integer age;
    //    @EnumValue
    @TableField(value = "email", fill = FieldFill.INSERT, updateStrategy = FieldStrategy.IGNORED)
//    @TableLogic(value = "Tomm@email", delval = "delval@email")
    private String email;
  /*  @TableField(exist = false)
    private String phoneNumber;*/
}
//2. 编写UserMapper接口,继承BaseMapper<T>接口

public interface UserMapper extends BaseMapper<User> {
  
}

//3. Application需要添加@MapperScan注解 why?后面要了解

@SpringBootApplication
@MapperScan
public class HaloApplication {

    public static void main(String[] args) {
        SpringApplication.run(HaloApplication.class, args);
    }

}
//4.编写测试用例

@RunWith(SpringRunner.class)
@SpringBootTest
class HaloApplicationTests {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserIService userIService;

    @Test
    public void testSelect() {
        System.out.println(("----- selectAll method test ------"));
       List<User> userList = userMapper.selectList(null);
//        Assert.assertEquals(6, userList.size());
        userList.forEach(System.out::println);
        }
}
5.运行结果
User(id=1, name=Jone, age=18, email=test1@baomidou.com)
User(id=2, name=Jack, age=20, email=test2@baomidou.com)
User(id=3, name=wangerha, age=35, email=null)
User(id=4, name=Sandy, age=21, email=test4@baomidou.com)
User(id=5, name=Billie, age=24, email=test5@baomidou.com)
User(id=6, name=Tomm, age=19, email=delval@email)
User(id=11, name=nosnakflow, age=18, email=nosnakflow@email)
User(id=1308430037258141697, name=wangxiaoxiao, age=18, email=wangxiaoxiao@email))
数据不一致是因为我对其中的数据进行了修改

注解

1. @TableName

@TableName表示数据库中表的名字

属性类型必须指定默认描述备注
valuessss数据
schema
resultMapString“”xml 中 resultMap 的 id,代表返回结果映射返回结果的封装
autoResultMapbooleanfalse表示是否自动构建ResultMap,如果设置了ResultMap则不会自动构建后续看源码todo
keepGlobalPrefixbooleanfalse是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建并注入)

备注:

  1. resultMap
    resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
  2. schema是什么?
此处的schema代表的即是数据库中的schema,只不过每个数据库对schema定义不一样,mysql中基本与数据库相同.在pgsql中一个数据库可有多个schema todo:学习数据库中schema知识
schema设置:
a. schema = "mybatisplus"(此处的“mybatisplus”随数据库的名字而变化)
@TableName(value = "user", keepGlobalPrefix = true, schema = "mybatispluss")
public class User {}
    
当我把schema的值写错之后,报以下错误
org.springframework.jdbc.BadSqlGrammarException: 
### Error querying database.  Cause: java.sql.SQLSyntaxErrorException: Unknown database 'mybatispluss'

  1. keepGlobalPrefix的设置

a.设置前缀
mybatis-plus.global-config.db-config.table-prefix=t_
当我修改user表为t_user表时,运行test报
org.springframework.jdbc.BadSqlGrammarException: 
### Error querying database.  Cause: java.sql.SQLSyntaxErrorException: Table 'mybatisplus.user' doesn't exist

b.增加keepGlobalPrefix=true时 运行正常
@TableName(value = "user", keepGlobalPrefix = true)
public class User {
这到底是不是一个实用的点呢????我觉得这个作用有点浮夸
// @TableName源码
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface TableName {
    String value() default "";

    String schema() default "";

    boolean keepGlobalPrefix() default false;

    String resultMap() default "";

    boolean autoResultMap() default false;

    String[] excludeProperty() default {};
}


@Builder
@Data
@TableName
public class User {
    @TableId(value = "id", type = IdType.ASSIGN_ID/*, type = IdType.ASSIGN_ID*/)
    private Long id;
    @TableField(value = "name", fill = FieldFill.UPDATE/*, condition = SqlCondition.LIKE*/)
    private String name;
    @TableField(value = "age", update = "%s+1")
    private Integer age;
    //    @EnumValue
    @TableField(value = "email", fill = FieldFill.INSERT, updateStrategy = FieldStrategy.IGNORED)
//    @TableLogic(value = "Tomm@email", delval = "delval@email")
    private String email;
  /*  @TableField(exist = false)
    private String phoneNumber;*/
}


2. @TableId

@TableId代表表中的主键

属性类型必须指定默认描述备注
valueString“”主键字段名
typeenumIdType.NONE主键生成策略(IdType)

备注:
1). IdType

描述
AUTO数据库id自增
NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUTinsert前自行set主键值
ASSIGN_ID分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)

备注:单独使用nextId,nextUUID:

 @Test
    public void snakeFlow() {
        IdentifierGenerator identifierGenerator = new DefaultIdentifierGenerator();
        System.out.println(identifierGenerator.nextId(new Object()));
        System.out.println(identifierGenerator.nextUUID(new Object()));
    }
	nextId:1310190714772242434 雪花算法:默认为Number/String 17——18位
	nextUUID:177137f0aa2096a74eff12783a11cbc8 UUID:默认为String类型 约32

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface TableId {
    String value() default "";

    IdType type() default IdType.NONE;
}

3. @TableField

@TableField:代表表中的字段名称

@Builder
@Data
@TableName(value = "user", keepGlobalPrefix = true, schema = "mybatisplus")
public class User {
	...
    @TableField(exist = false)
    private String phoneNumber;
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface TableField {
    String value() default "";
	// 此属性使用报错,显示org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
// Error querying database.  Cause: java.lang.IndexOutOfBoundsException: Index: 4, Size: 4 不知道是不是MP的bug

    boolean exist() default true;
//
    String condition() default "";

    String update() default "";

    FieldStrategy insertStrategy() default FieldStrategy.DEFAULT;

    FieldStrategy updateStrategy() default FieldStrategy.DEFAULT;

    FieldStrategy whereStrategy() default FieldStrategy.DEFAULT;

    FieldFill fill() default FieldFill.DEFAULT;

    boolean select() default true;

    boolean keepGlobalFormat() default false;

    JdbcType jdbcType() default JdbcType.UNDEFINED;

    Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;

    boolean javaType() default false;

    String numericScale() default "";
}

@Version
@EnumValue
@TableLogic
@SqlParser
@KeySequence

六级标题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值