1. Mybatis-plus
官网:链接
1. 依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.9</version>
</dependency>
2. 注解配置表名、字段名
一般情况下,数据库映射为实体类对应关系
- 数据库表与实体类类名:下划线转为驼峰
- 实体类中的id字段对应数据库中的主键字段id
- 表中列名与实体类属性名:下划线转驼峰
如不满足以上条件,需在实体类中使用注解
- 表名注解:
@TableName
:用来指定表名 - 指定主键:
@TableId
指定表中的主键 - 实体类属性注解:
@TableField
指定表中的字段信息
// 指定该实体类对应的表名是t_vip
@TableName("`t_vip`")
public class Vip {
// 指定该属性为主键,且在数据表中的列名为id,且自增
@TableId(value = "id", type = IdType.AUTO)
private Long vid;
// 指定该属性对应表中的username列
@TableField(value = "username")
private String name;
// 数据表中不存在该属性对应的列
@TableField(exist = false)
private String birthday;
}
@TableId:常见类型
- 主键最好指定类型,默认是
type = IdType.ASSIGN_ID
@TableId(type = IdType.AUTO) // 主键自增,数据库自动生成
@TableId(type = IdType.INPUT) // 通过set方法自行输入,例如uuid作为主键,需要手动赋值
@TableId( type = IdType.ASSIGN_ID) // 通过接口生成主键,由mybatis-plus自动生成
@TableField:常见场景
- 实体类属性与数据库表中字段不一致,
// 属性是name,表中是username
@TableField("username")
private String name;
- 表中以is开头并且是boolean值
// 表中字段名:is_ban,映射的属性名为ban
@TableField("is_ban")
private Boolean name;
- 属性名与数据库的关键字一致
// order在数据库中是关键字,注意使用了 ``
@TableField("`order`")
private String order;
- 属性并不属于数据库表中的字段
// 数据表中不存在该属性对应的列
@TableField(exist = false)
private String birthday;
3. yml中的配置
官方:链接
- 很多默认配置已经足够了
mybatis-plus:
type-aliases-package: org.example.learn.domain # 实体类包
global-config:
db-config:
id-type: auto # id生成策略:自增长
logic-delete-field: deleted # 表中的逻辑删除字段名
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
banner: false # 是否在控制台打印 MyBatis-Plus 的 LOGO
configuration:
default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler # 枚举类型处理器
4. mapper和service的用法
- mapper:继承
BaseMapper
接口
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.example.learn.bean.User; // 实体类
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
- service:继承
IService
接口
import com.baomidou.mybatisplus.extension.service.IService;
import org.example.learn.bean.User; // 实体类
public interface UserService extends IService<User> {
}
- service的实现类seviceImpl:继承
ServiceImpl
ServiceImpl:两个泛型
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.learn.bean.User;
import org.example.learn.dao.UserMapper;
import org.example.learn.service.UserService;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
}
2. 使用工具生成mapper和service
3. 逻辑删除
- 在实际应用中很多数据是不能删除的,比如:订单信息,mybatis-plus提供了逻辑删除
- 逻辑删除:使用数据表中的某一个列,通过列的值表示该数据是否被删除
1. 需要在yml中配置
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted # 表中的逻辑删除字段名
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
2. 代码
代码还是使用正常的删除和查询操作,mybaits-plus在删除时实际使用的是updata操作,查询时总是会把标志位作为条件带入
- 使用remove方法删除时,mybatis-plus使用了updata方法更新了逻辑删除的列
addressService.removeById(59L);
/*
* ==> Preparing: UPDATE address SET deleted=1 WHERE id=? AND deleted=0
* ==> Parameters: 59(Long)
* <== Updates: 0
* */
- 查询时也会自动添加逻辑删除标志位为未删除的条件
Address address = addressService.getById(59L);
/*
* ==> Preparing: SELECT id,user_id,province,city,town,mobile,street,contact,is_default,notes,deleted FROM address WHERE id=? AND deleted=0
* ==> Parameters: 59(Long)
* <== Total: 0
* */
4. json类型
在数据表中类型格式为json,在查询、新增、更新等操作时,此数据转为对象形式
1. 定义json类型字段内容对应的类
{"age": 20, "intro": "佛系青年", "gender": "male"}
@Data
public class UserInfo {
private Integer age;
private String intro;
private String gender;
}
2. 在数据表对应的类属性和类上加注解
- 类上注解:
@TableName(autoResultMap = true)
- 属性注解:
@TableField(typeHandler = JacksonTypeHandler.class)
@Data
//@Accessors(chain = true)
@TableName(autoResultMap = true)
public class User implements Serializable {
/**
* 详细信息
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private UserInfo info;
}
3. 在查询后返回的结果就是对象形式
5. 自动映射枚举
经常使用数字或布尔值代表一种状态,每次查询或新增时都需要对照状态表来解释状态码。
例如:
// private Boolean gender; // 男/女
private Integer status; // 使用状态(1正常 2冻结)
1. 配置yml
mybatis-plus:
configuration:
default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
2. 创建枚举类
@Getter
public enum UserStatus {
NORMAL(1, "正常"),
FREEZE(2, "冻结");
@EnumValue // 在数据库存/取的值是code的属性值
private final Integer code;
@JsonValue // 在序列化时返回的JSON中显示的属性值
private final String desc;
UserStatus(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
}
3. 修改数据表对应的实体类中该属性的类型
/**
* 使用状态(1正常 2冻结)
*/
private UserStatus status;
4. 使用
// 1. 查询id是否存在
User user = this.getById(id);
if (user == null || user.getStatus() == UserStatus.FREEZE) {
throw new RuntimeException("用户不存在或已经被禁用");
}
pom中所有的依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.11</version>
</dependency>
<!--swagger-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
<version>4.1.0</version>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>