添加 SpringBoot 启动器依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
查看引入的依赖结构,打开自动装配的配置文件,发现自动配置主要是两个类。
com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration
com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration
深入看一下 MybatisPlusAutoConfiguration
类,发现 92
行添加了条件注解,内容如下:
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
说明注入了 SqlSessionFactory
类,这是 Mybatis
框架的核心类。
在本地数据库 test
中新建一张表 user
,建表语句如下:
create table user
(
id int auto_increment primary key,
name varchar(255),
age tinyint
) ENGINE = InnoDB
DEFAULT CHARSET = utf8
AUTO_INCREMENT = 1;
同时需要在 SpringBoot
项目的配置文件中添加如下配置:
# 数据库驱动:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=root
新建实体类 User
:
@Data
public class User {
private Integer id;
private String name;
private Integer age;
}
Mapper
接口直接继承 BaseMapper
接口即可:
@Component("userMapper")
public interface UserMapper extends BaseMapper<User> {
}
同时需要在启动类上添加扫描注解,用于扫描 Mapper
。
@SpringBootApplication
@MapperScan("com.lsu.mybatisplus.mapper")
public class MybatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPlusApplication.class, args);
}
}
如果想在日志中看到 SQL
语句,需要在主配置文件中添加一行配置:
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
用来映射数据库表名
@Data
@TableName("user")
public class User {
private Integer id;
private String name;
private Integer age;
}
设置主键映射
value
:映射主键字段名type
:设置主键类型,主键的生成策略:值为 IdType
枚举类型// 这里类型是自增的
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
如果不指定 type
的类型,默认是 ASSIGN_UUID
,指的是使用雪花算法生成随机数填充。
@TableField(value = "gender", exist = false, fill = FieldFill.DEFAULT)
value
:映射属性字段名exist
:是否存在,false
表示不从数据库中查询fill
:自动填充:Mybatis-Plus
自动为字段赋值,例如创建时间和修改时间自动填充的两种情况:
INSERT
:插入时填充INSERT_UPDATE
:修改时填充,创建时也要填充;需要实现的接口:MetaObjectHandler
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}
实体类添加注解如下:
@TableField(fill = FieldFill.INSERT)
private Date createdDate;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updatedDate;
标记乐观锁,保证数据的安全性,修改数据的时候,只有条件成立的时候才会修改成功。
version
字段,默认值为 1
;version
成员变量,并添加 @version
注解;乐观锁的配置
通用的枚举类注解,将数据库字段映射成实体类的枚举类型成员变量。
首先修改表结构,为其增加一列名为状态的字段 status
:
alter table user
modify status tinyint default 0;
随后创建一个枚举类:
@AllArgsConstructor
public enum StatusEnum {
/**
* 1 表示上班
* 0 表示休息
**/
WORK(1, "上班"),
REST(0, "休息"),
;
@EnumValue
private Integer code;
private String msg;
}
在主配置文件中新增枚举扫描:
# 枚举包扫描
mybatis-plus.type-enums-package=com.lsu.mybatisplus.enums
实体类:
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String name;
private Integer age;
/**
* 枚举类型
**/
private StatusEnum status;
也可以通过实现接口的方式来映射枚举类:
@AllArgsConstructor
public enum StatusEnum implements IEnum<Integer> {
/**
* 1 表示上班
* 0 表示休息
**/
WORK(1, "上班"),
REST(0, "休息"),
;
private Integer code;
private String msg;
@Override
public Integer getValue() {
return this.code;
}
}
修改数据表:
-- 增加逻辑删除字段
alter table user
add deleted tinyint default 0;
实体类增加:
@TableLogic
private Integer deleted;
修改配置文件,用来配置 0
表示没有删除,1
表示被删除了:
# 逻辑删除数值
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
这样配置以后,再次删除的时候,只会更新数据库的 deleted
字段的数值为 1
,表示已经删除,而不会真正的删除数据,但是在查询的时候,被逻辑删除的数据也查不出来。
SELECT id,name,age,status,deleted FROM user WHERE deleted=0
关于查询,主要是一个 Wrapper
接口的实现类 QueryWrapper
,它是用于封装查询条件的。
查询多值,使用 selectList
方法:
// 不加任何条件全部查询
mapper.selectList(null);
// 单条件查询: 查询姓名是王五的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "王五");
mapper.selectList(wrapper);
// 多条件查询: 查询姓名是王五并且年龄是 20 的用户
Map<String, Object> map = new HashMap<>();
map.put("name", "王五");
map.put("age", 20);
wrapper.allEq(map);
// 模糊查询 %张%
wrapper.like("name", "张");
// 相当于 张%
wrapper.likeRight("name", "张");
// 嵌套查询: 可以写 SQL 语句
wrapper.inSql("age", "select age from user where age < 20");
// 排序: 升序
wrapper.orderByAsc("age");
根据 ID
查询:
// 根据 ID 查询
mapper.selectById(1);
// 查询多个 ID
mapper.selectBatchIds(Arrays.asList(1, 2, 3));
分页插件
通常使用自定义 SQL 进行多表关联查询。
首先创建一张新的表 product
用于多表关联:
create table product
(
id int auto_increment primary key comment '主键ID',
category tinyint comment '分类',
count int comment '数量',
description varchar(255) comment '商品描述',
user_id int comment '用户ID | 关联用户表',
foreign key product (user_id) references user (id)
) engine = InnoDB
default charset = utf8
auto_increment = 1;
userMapper
实体类,增加自定义 SQL
语句:
@Component("userMapper")
public interface UserMapper extends BaseMapper<User> {
/**
* 查询商品表和用户表
*
* @param id: ID
* @author wang shuo
* @date 2021/7/19 8:24
* @return: java.util.List<com.lsu.mybatisplus.vo.ProductVO>
**/
@Select("select category, count, description, user_id, name as username from product p left join user u on p.user_id = u.id where p.id = #{id}")
List<ProductVO> selectProduct(Integer id);
}
注意这里 user
部分,数据库中的字段名为 name
而我们的 VO
实体类中的属性名为 username
,会自动赋值失败;这里采取的解决办法是,写数据库查询语句的时候取别名,用到了 name as username
。
修改需要传入待修改的数据结构和条件。
User user = new User();
user.setName("王硕");
user.setAge(21);
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("id", 4);
mapper.update(user, wrapper);
对应的 SQL
语句如下:
UPDATE user SET name=?, age=? WHERE deleted=0 AND (id = ?)
参数:王硕(String), 21(Integer), 4(Integer)
删除和新增同理,只需调用相关的 API
即可。