
添加 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 即可。