MyBatisPlus详解(一)项目搭建、@TableName、@TableId、@TableField注解与常见配置

前言

为了简化或省略单表的CRUD开发工作,国内使用较多的一个组件是MyBatisPlus。

其官网地址是:https://baomidou.com/

MyBatisPlus不仅可以简化单表操作,还对MyBatis的功能有很多的增强,可以让开发更加简单、高效。

1 快速入门

1.1 环境准备

1.1.1 新建数据库

在MySQL中创建一个新的数据库mybatis_plus_db:

CREATE DATABASE mybatis_plus_db;
USE mybatis_plus_db;

创建一张新表t_address并添加一些数据:

-- 创建t_address
CREATE TABLE `t_address` (
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `user_id` INT COMMENT '用户ID',
  `province` VARCHAR(10) COMMENT '省',
  `city` VARCHAR(10) COMMENT '市',
  `town` VARCHAR(10) COMMENT '县/区',
  `mobile` VARCHAR(255) COMMENT '手机',
  `street` VARCHAR(255) COMMENT '详细地址',
  `contact` VARCHAR(255) COMMENT '联系人',
  `is_default` BIT(1) DEFAULT b'0' COMMENT '是否是默认 1默认 0否',
  `notes` VARCHAR(255) COMMENT '备注',
  `deleted` BIT(1) DEFAULT b'0' COMMENT '逻辑删除',
  KEY `user_id` (`user_id`) USING BTREE
);

-- 初始化t_address数据
INSERT INTO `t_address` (`user_id`, `province`, `city`, `town`, `mobile`, `street`, `contact`, `is_default`, `notes`, `deleted`) VALUES
	(2, '北京', '北京', '朝阳区', '13900112222', '金燕龙办公楼', 'Rose', b'1', NULL, b'0'),
	(1, '北京', '北京', '朝阳区', '13700221122', '修正大厦', 'Jack', b'0', NULL, b'0'),
	(1, '上海', '上海', '浦东新区', '13301212233', '航头镇航头路', 'Jack', b'1', NULL, b'0'),
	(2, '广东', '佛山', '永春', '13301212233', '永春武馆', 'Rose', b'0', NULL, b'0'),
	(3, '浙江', '杭州', '拱墅区', '13567809102', '浙江大学', 'Hope', b'1', NULL, b'0'),
	(3, '浙江', '杭州', '拱墅区', '13967589201', '左岸花园', 'Hope', b'0', NULL, b'0'),
	(4, '湖北', '武汉', '汉口', '13967519202', '天天花园', 'Thomas', b'1', NULL, b'0'),
	(3, '浙江', '杭州', '拱墅区', '13967589201', '左岸花园', 'Hopey', b'0', NULL, b'0'),
	(4, '湖北', '武汉', '汉口', '13967519202', '天天花园', 'Thomas', b'1', NULL, b'0'),
	(3, '浙江', '杭州', '拱墅区', '13967589201', '左岸花园', 'Hopey', b'0', NULL, b'0'),
	(4, '湖北', '武汉', '汉口', '13967519202', '天天花园', 'Thomas', b'1', NULL, b'0');

再创建一张新表t_user并添加一些数据:

-- 创建t_user
CREATE TABLE `t_user` (
	`id` INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '用户id',
	`username` VARCHAR(50) NOT NULL COMMENT '用户名',
	`password` VARCHAR(128) NOT NULL COMMENT '密码',
	`phone` VARCHAR(20) COMMENT '注册手机号',
	`info` VARCHAR(200) NOT NULL COMMENT '详细信息',
	`status` INT(10) NOT NULL DEFAULT 1 COMMENT '使用状态(1正常 2冻结)',
	`balance` INT(10) COMMENT '账户余额',
	`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
	`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
	UNIQUE INDEX `username` (`username`) USING BTREE
) COMMENT='用户表';

-- 导入t_user数据
INSERT INTO `t_user` (`username`, `password`, `phone`, `info`, `status`, `balance`) VALUES
	('Jack', '123', '13900112224', '{"age": 20, "intro": "佛系青年", "gender": "male"}', 1, 1600),
	('Rose', '123', '13900112223', '{"age": 19, "intro": "青涩少女", "gender": "female"}', 1, 600),
	('Hope', '123', '13900112222', '{"age": 25, "intro": "上进青年", "gender": "male"}', 1, 100000),
	('Thomas', '123', '17701265258', '{"age": 29, "intro": "伏地魔", "gender": "male"}', 1, 800);

1.1.2 创建项目

创建一个SpringBoot项目,项目结构如下图所示:

代码下载地址:https://gitee.com/weidag/mybatis_plus_learning.git

1.2 快速开始

1.2.1 引入MyBatisPlus依赖

MybatisPlus提供了starter,实现了Mybatis以及MybatisPlus的自动装配功能:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

由于这个starter已经包含了对mybatis的自动装配,因此可以替换掉Mybatis的starter。

最终的项目依赖如下:

<!--pom.xml-->

<dependencies>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.3.1</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.48</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.8.11</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

1.2.2 定义Mapper

为了简化单表CRUD,MyBatisPlus提供了一个基础的BaseMapper接口,其中已经实现了单表的CRUD:

因此,当自定义的Mapper接口继承该基础的BaseMapper接口,就无需再自己定义单表的CRUD了,如下:

// com.star.learning.mapper.UserMapper

public interface UserMapper extends BaseMapper<User> {}

1.2.3 配置实体类和表的关系

修改User类,使用@TableName、@TableId、@TableField等注解将User类和表t_user关联起来。如下:

// com.star.learning.pojo.User

@Data
@TableName("t_user")
public class User {

    /**
     * 用户id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

    /**
     * 注册手机号
     */
    private String phone;

    /**
     * 详细信息
     */
    private String info;

    /**
     * 使用状态(1正常 2冻结)
     */
    private Integer status;

    /**
     * 账户余额
     */
    private Integer balance;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;

}

默认情况下,MybatisPlus会根据实体的信息自动推断出表的信息,从而生成SQL。

一般遵循以下原则:

  • MybatisPlus会把实体的类名驼峰转下划线作为表名;
  • MybatisPlus会把实体的所有变量名驼峰转下划线作为表的字段名,并根据变量类型推断字段类型,例如变量名createTime会转换为表的字段名create_time。
  • MybatisPlus会把变量名为id的字段作为主键

因此,当实体和表都符合这些原则时,也不再需要配置@TableName、@TableId、@TableField等注解,只是现实场景中不一定符合,例如User类和t_user表就是不符合默认规则,所以还是需要这些注解来进行处理。

1.2.4 简单测试

1.2.4.1 测试插入操作
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyBatisPlusApp .class)
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testInsert() {
        User user = new User();
        user.setUsername("Lucy");
        user.setPassword("123");
        user.setPhone("18688990011");
        user.setBalance(200);
        user.setInfo("{\"age\": 24, \"intro\": \"英语老师\", \"gender\": \"female\"}");
        userMapper.insert(user);
    }
}

执行该单元测试,控制台打印出该操作的SQL语句:

==>  Preparing: INSERT INTO t_user ( username, password, phone, info, balance ) VALUES ( ?, ?, ?, ?, ? )
==> Parameters: Lucy(String), 123(String), 18688990011(String), {"age": 24, "intro": "英语老师", "gender": "female"}(String), 200(Integer)
<==    Updates: 1
1.2.4.2 测试查询操作
@Test
public void testSelectById() {
    // 根据单个ID查询
    User user = userMapper.selectById(4);
    System.out.println("user = " + user);
    // 根据多个ID查询
    List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
    users.forEach(System.out::println);
}

执行该单元测试,控制台打印出该操作的SQL语句及查询结果:

// 根据单个ID查询
==>  Preparing: SELECT id,username,password,phone,info,status,balance,create_time,update_time FROM t_user WHERE id=?
==> Parameters: 4(Integer)
<==      Total: 1
user = User(id=4, username=Thomas, password=123, phone=17701265258, info={"age": 29, "intro": "伏地魔", "gender": "male"}, status=1, balance=800, createTime=2024-04-21T10:13:35, updateTime=2024-04-21T10:14:59)
// 根据多个ID查询
==>  Preparing: SELECT id,username,password,phone,info,status,balance,create_time,update_time FROM t_user WHERE id IN ( ? , ? , ? )
==> Parameters: 1(Integer), 2(Integer), 3(Integer)
<==      Total: 3
User(id=1, username=Jack, password=123, phone=13900112224, info={"age": 20, "intro": "佛系青年", "gender": "male"}, status=1, balance=1600, createTime=2024-04-21T10:13:35, updateTime=2024-04-21T10:14:52)
User(id=2, username=Rose, password=123, phone=13900112223, info={"age": 19, "intro": "青涩少女", "gender": "female"}, status=1, balance=600, createTime=2024-04-21T10:13:35, updateTime=2024-04-21T10:14:54)
User(id=3, username=Hope, password=123, phone=13900112222, info={"age": 25, "intro": "上进青年", "gender": "male"}, status=1, balance=100000, createTime=2024-04-21T10:13:35, updateTime=2024-04-21T10:14:57)
1.2.4.3 测试更新操作
@Test
public void testUpdateById() {
    User user = new User();
    user.setId(3L);
    user.setBalance(20000);
    userMapper.updateById(user);
}

执行该单元测试,控制台打印出该操作的SQL语句:

==>  Preparing: UPDATE t_user SET balance=? WHERE id=?
==> Parameters: 20000(Integer), 3(Long)
<==    Updates: 1
1.2.4.4 测试删除操作
@Test
public void testDelete() {
    userMapper.deleteById(1L);
}

执行该单元测试,控制台打印出该操作的SQL语句:

==>  Preparing: DELETE FROM t_user WHERE id=?
==> Parameters: 1(Long)
<==    Updates: 1

1.3 常见注解

1.3.1 @TableName

该注解是一个表名注解,用于标识实体类对应的表,如下例中就代表实体类User对应的表是t_user:

// com.star.learning.pojo.User

@TableName("t_user")
public class User {...}

除了指定表名以外,TableName注解还可以指定很多其它属性:

1.3.2 @TableId

该注解是一个主键注解,用于标识实体类中的主键字段,如下例中就代表实体类User的主键字段是id,其对应的表字段也是id:

// com.star.learning.pojo.User

/**
 * 用户id
 * value - 主键字段名
 * type - 指定主键类型,默认值IdType.NONE
 */
@TableId(value = "id", type = IdType.AUTO)
private Long id;

IdType支持的类型有:

1.3.3 @TableField

该注解是一个普通字段注解,用于标识实体类中的普通字段,例如:

// com.star.learning.pojo.User

/**
 * 用户名
 */
@TableField("username")
private String username;

一般情况下,并不需要给字段添加@TableField注解,MyBatisPlus会根据驼峰转下划线的原则自动匹配。但有一些特殊情况除外:

  • 成员变量名与数据库字段名不符合驼峰转下划线原则;
  • 成员变量是以isXXX命名,MybatisPlus识别字段时会把is去除,而导致与数据库字段不符;
  • 成员变量名与数据库一致,但是与数据库的关键字冲突。此时需要使用@TableField注解给字段名添加转义字符:``。

@TableField注解支持的属性有:

1.4 常见配置

MybatisPlus支持基于yaml文件的自定义配置,详见官方文档:https://www.baomidou.com/pages/56bac0/#基本配置

大多数的配置都有默认值,因此都无需配置。但还有一些是没有默认值的,例如:

# src\main\resources\application.yaml

mybatis-plus:
  # 实体类的别名扫描包
  type-aliases-package: com.star.learning.pojo
  # 全局ID类型
  global-config:
    db-config:
      id-type: auto

同时,MyBatisPlus也支持MyBatis本身的写法去手写SQL的,而mapper文件的读取地址可以自己配置:

# src\main\resources\application.yaml

mybatis-plus:
  # Mapper.xml文件的路径,当前配的是默认值
  mapper-locations: classpath*:/mapper/**/*.xml

例如,在resources目录下创建一个mapper/UserMapper.xml文件,并手写SQL:

<!--src\main\resources\mapper\UserMapper.xml-->

<mapper namespace="com.star.learning.mapper.UserMapper">
    <!--自定义的根据ID查询用户信息-->
    <select id="customQueryUserById" resultType="com.star.learning.pojo.User">
        SELECT *
        FROM t_user
        WHERE id = #{id}
    </select>
</mapper>

然后在UserMapper接口中定义这个customQueryUserById()方法:

// com.star.learning.mapper.UserMapper

public interface UserMapper extends BaseMapper<User> {
    /**
     * 自定义的根据ID查询用户信息
     */
    User customQueryUserById(Long id);
}

最后编写一个单元测试:

@Test
public void testCustomSelectById() {
    // 根据单个ID查询
    User user = userMapper.customQueryUserById(3L);
    System.out.println("user = " + user);
}

执行该单元测试,控制台打印出该操作的SQL语句及查询结果:

==>  Preparing: SELECT * FROM t_user WHERE id = ?
==> Parameters: 3(Long)
<==      Total: 1
user = User(id=3, username=Hope, password=123, phone=13900112222, info={"age": 25, "intro": "上进青年", "gender": "male"}, status=1, balance=20000, createTime=2024-04-21T10:13:35, updateTime=2024-04-21T11:12:48)

本节完,更多内容请查阅分类专栏:MyBatisPlus详解

本文涉及代码下载地址:https://gitee.com/weidag/mybatis_plus_learning.git

感兴趣的读者还可以查阅我的另外几个专栏:

  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灰色孤星A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值