mybatis-plus基础使用

mybatis-plus基础使用

https://baomidou.com/introduce/

引入依赖
  • 注意mybatis和mybatis的版本,如果版本差距过大会报错
//还是需要引入mybatis的starter的 mybatisplus中的mubatis-spring版本太低,启动会报错
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.5'
// https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter
implementation("com.baomidou:mybatis-plus-boot-starter:3.5.14")
基础配置
# mybatis-plus
# 自动给这个包下的实体类生成别名 例如 User -> user
# 可以在 MyBatis 的 XML 映射文件中直接使用这些别名,而不需要全限定类名 等同于 @Alias("user")
mybatis-plus.type-aliases-package: com.example.springboottest.entity
# mybatis xml文件地址
mybatis-plus.mapper-locations: classpath:mapper/*.xml
# mybatis 开启驼峰转下划线
mybatis-plus.configuration.map-underscore-to-camel-case: true
# 开启 MyBatis-Plus SQL 打印日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
实体类常用注解
@TableName("user") // 表名
public class User {
    @TableId(type = IdType.AUTO) // 自增ID
    private Integer id;
    @TableField(value = "username") // 数据库中字段名为username
    private String name;
    private String phoneNumber;
    // 乐观锁字段 设置之后每次更新自动+1
    @Version
    private Integer version;
    // 逻辑删除字段 默认为0
    //@TableLogic
    private Integer deleted;
    // 创建时间字段 默认填充当前时间
    @TableField(fill = FieldFill.INSERT,update = "now()")
    private Date createTime;
    // 更新时间字段 默认填充当前时间
    @TableField(fill = FieldFill.INSERT_UPDATE,update = "now()")
    private Date updateTime;
}
创建Mapper并实现BaseMapper<T>
  • 泛型T为实体类的类型 例如User

  • BaseMapper默认实现一些常用的增删改查方法,具体使用时可以点进去看看

    image-20250923134113058

    创建Service并继承Iservice接口
  • service接口继承Iservice<实体类>接口,service实现继承ServiceImpl<Mapper类名, 实体类名> 继承的service中也提供了一些常用方法,一些批量接口添加了@Transactional注解

    public interface UserService extends IService<User> {
    }
    
    @Service
    public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService  {
    
    }
    
  • 业务一些简单增删改查直接使用提供的默认实现就行,类似于JPA那种

自动填充

  • 在需要自动填充的实体类字段上添加@TableField(fill = FieldFill.INSERT)注解
@TableField(fill = FieldFill.INSERT)
private Date createTime;

// FieldFill的取值
public enum FieldFill {
    /**
     * 默认不处理
     */
    DEFAULT,
    /**
     * 插入时填充字段
     */
    INSERT,
    /**
     * 更新时填充字段
     */
    UPDATE,
    /**
     * 插入和更新时填充字段
     */
    INSERT_UPDATE
}
  • 继承MetaObjectHandler接口,实现insertFill与updateFill方法
@Component
public class UserMapperHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        // 插入时进行填充
        this.strictInsertFill(metaObject,"createTime", Date.class,new Date());
        this.strictInsertFill(metaObject,"updateTime", Date.class,new Date());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        // 数据更新时进行填充
        this.strictUpdateFill(metaObject,"updateTime", Date.class,new Date());
    }
}

使用Wrapper(条件构建器)构建一些复杂的查询条件

基础使用
User user = initUser();
LambdaQueryWrapper<User> query = new LambdaQueryWrapper<>();
// 构建一些复杂的查询条件
// SELECT username AS name,password FROM user WHERE (username = ? AND password LIKE ? AND id >= ? AND address IS NOT NULL)
query.eq(User::getName, "zhangsan")
    .like(User::getPassword,"%23456%")
    .ge(User::getId, 0)
    .select(User::getName, User::getPassword)
    .isNotNull(User::getAddress);
// 更新
LambdaUpdateWrapper<User> update = new LambdaUpdateWrapper<>();
update.set(User::getName, "张三")
    .set(User::getPassword,"aassasas")
    .set(User::getEmail, "[email protected]")
    .eq(User::getId, 1);
        
  • AND OR 构建一些复杂条件 and()or ()or()….
// SELECT name,age,address FROM student WHERE ((name = ? AND age > ?) OR (name = ? AND age > ?) AND (address IS NOT NULL AND height IS NOT NULL)) ORDER BY id DESC
LambdaQueryWrapper<Student> query = new LambdaQueryWrapper<>();  
query.select(Student::getName,Student::getAge,Student::getAddress)  
        .or(queryWrapper->queryWrapper.eq(Student::getName,"zhangsan").gt(Student::getAge,10))  
        .or(queryWrapper -> queryWrapper.eq(Student::getName,"lisi").gt(Student::getAge,10))  
        .and(queryWrapper->queryWrapper.isNotNull(Student::getAddress).isNotNull(Student::getHeight))  
        .orderBy(true,false,Student::getId);  
List<Student> students = mapper.selectList(query);
  • inSql,eqSql,leSql,setSql 可以构建一些子查询
// UPDATE student SET height = height + ? - ? WHERE (id = (select count(*) from teacher))
LambdaUpdateWrapper<Student> updateWrapper = new LambdaUpdateWrapper<>();  
updateWrapper.setSql("height = height + {0} - {1}",3,2)  
        .eqSql(Student::getId,"select count(*) from teacher");  
mapper.update(updateWrapper);

自定义SQL

将wrapper构造的where语句拼接在mapper.xml文件中

  • 版本要求:确保你的项目中使用的 mybatis-plus 版本至少为 3.0.7,以支持自定义 SQL 功能。
  • 参数命名:在自定义 SQL 时,传递 Wrapper 对象作为参数时,参数名必须为 ew,或者使用注解 @Param(Constants.WRAPPER) 明确指定参数为 Wrapper 对象。
  • 使用 ${ew.customSqlSegment}:在 SQL 语句中,使用 ${ew.customSqlSegment} 来引用 Wrapper 对象生成的 SQL 片段。
public List<Student> getStudentByNameOrIds(List<String> names,List<Integer> ids) {  
    LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<Student>().or(!names.isEmpty(),queryWrapper -> queryWrapper.in(Student::getName, names))  
            .or(!ids.isEmpty(),queryWrapper -> queryWrapper.in(Student::getId, ids));  
    return baseMapper.getStudentByNameOrIds(wrapper);  
}

public interface StudentMapper extends BaseMapper<Student> {  
    List<Student> getStudentByNameOrIds(@Param(Constants.WRAPPER) LambdaQueryWrapper<Student> wrapper);  
}
<select id="getStudentByNameOrIds" resultType="com.cpz.final_test.mybatis_plus_test.entity.Student">  
    select * from student ${ew.customSqlSegment}  
</select>

逻辑删除

  • 全局配置中配置逻辑删除的字段
  • 在字段上加@TableLogic注解

静态工具

  • mybatisPlus提供了Db的静态工具类,能够不使用service,mapper进行查询,修改等
  • 其实就是利用反射获取了类信息,然后生成sql语句
  • 使用Db时候要先有Mapper接口继承BaseMapper,里面其实是调用的baseMapper的接口
Student one = Db.lambdaQuery(Student.class).eq(Student::getId, 1).one();

枚举类的处理

  • 将枚举类映射成数据库中对应的字段
    • 例如 将MAN(1,"男") -> 1
  • 在配置文件中指定使用mybayisplus的注解处理器
  • 在想要映射的字段上添加注解 @EnumValue
    • 实际测试时只需加入@EnumValue即可,不需要配置文件设置,可能是版本问题
@Getter  
public enum StudentStatus {  
    NORMAL(1,"正常"),  
    FREEZE(0,"冻结");  
  
    @EnumValue  
    private final Integer value;  
    // jackson注解 返回时处理枚举 返回desc的值 默认返回FREEZE,NORMAL  
    @JsonValue  
    private final String desc;  
  
    StudentStatus(int value, String desc){  
        this.value = value;  
        this.desc = desc;  
    }  
  
}
posted @ 2026-01-14 11:12  lyfa  阅读(5)  评论(0)    收藏  举报