MybatisPlus
本文最后更新于48 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

一、快速入门

1、入门案例

  • 引入MybatisPlus的起步依赖

MyBatisPlus官方提供了starter,其中集成了Mybatis和MybatisPlus的所有功能,并且实现了自动装配效果。因此我们可以用MybatisPlus的starter代替Mybatis的starter:

<!--MybatisPlus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>
  • 定义Mapper

自定义的Mapper继承MybatisPlus提供的BaseMapper接口:

public interface UserMapper extends BaseMapper<User> {
}

2、常见注解

  • MyBatisPlus通过扫描实体类,并基于反射获取实体类信息作为数据库表信息。
  • 常用的几个注解:
@TableName:用来指定表名
@TableId:用来指定表中的主键字段信息
@TableField:用来指定表中的普通字段信息
    
IdType枚举:
    AUTO:数据库自增长
    INPUT:通过set方法自行输入
    ASSIGN_ID:分配 ID,接口IdentifierGenerator的方法nextId来生成id,默认实现类为DefaultIdentifierGenerator雪花算法
    
使用@TableField的常见场景:
    变量名与数据库字段名不一致
    变量名以is开头,且是布尔值
    变量名与数据库关键字冲突
    变量不是数据库字段,如@TableField(exist = false)

3、常见配置

MyBatisPlus的配置项继承了MyBatis原生配置和一些自己特有的配置。例如:

mybatis-plus:
    type-aliases-package: com.itheima.mp.domain.po # 别名扫描包
        mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址,默认值
        configuration:
        map-underscore-to-camel-case: true # 是否开启下划线和驼峰的映射
            cache-enabled: false # 是否开启二级缓存
        global-config:
        db-config:
            id-type: assign_id # id为雪花算法生成
            update-strategy: not_null # 更新策略:只更新非空字段

二、核心功能

1、条件构造器

MyBatisPlus支持各种复杂的where条件,可以满足日常开发的所有需求。

  • 查询出名字中带o的,存款大于等于1000元的人的id、username、info、balance字段
SELECT id,username,info,balance 
FROM user 
WHERE username LIKE ? AND balance >= ?
void testQuerywrapper(){
    //1.构建查询条件
    QueryWrapper<User> wrapper = new QueryWrapper<User>()
        .select("id",,"username","info","balance")
        .llike( column: "username", val: "o")
        ·ge( column: "balance",val: 1000);
    // 2.查询
        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
}
// 参数是函数,避免硬编码,比如User::getId就是User的getId方法
void testQuerywrapper(){
    //1.构建查询条件
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
        .select(User::getId,User::getUsername,User::getInfo,User::getBalance)
        .like(User::getUsername, val:"o")
        ·ge(User::getBalance, val:1000);
    // 2.查询
        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
}
  • 更新用户名为jack的用户的余额为2000
UPDATE user 
    SET balance = 2000 
    WHERE (username = "jack")
void testUpdateByQueryWrapper(){
    // 1.要更新的数据
    User user = new User();
    user.setBalance(2000) ;
    //2.更新的条件
    QueryWrapper<User> wrapper = new QueryWrapper<User>().eq( column: "username",val: "jack");
    //3.执行更新I
    userMapper.update(user, wrapper) ;
}
  • 更新id为1,2,4的用户的余额,扣200
UPDATE user 
    SET balance = balance - 200 
    WHERE id in (1, 2, 4)
void testUpdateWrapper(){
    List<Long> ids = List.of(1L,2L,4L);
    UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
        .SetSql("balance = balance - 2oo")
        .in( column: "id", ids);I
    userMapper.update( entity: null, wrapper);
}

2、自定义SQL

利用MyBatisPlus的Wrapper来构建复杂的Where条件,然后自己定义SQL语句中剩下的部分。

  • 基于Wrapper构建where条件
List<Long> ids = List.of(1L, 2L, 4L);
int amount = 200;
// 1.构建条件
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>().in(User::getId, ids);
// 2.自定义SQL方法调用
userMapper.updateBalanceByIds(wrapper, amount);
  • 在mapper方法参数中用Param注解声明wrapper变量名称,必须是ew
void updateBalanceByIds(@Param("ew") LambdaQueryWrapper<User> wrapper, @Param("amount") int amount);
  • 自定义SQL,并使用Wrapper条件
<update id="updateBalanceByIds">
    UPDATE tb_user SET balance = balance - #{amount} ${ew.customSqlSegment}
</update>

3、Service接口

// 自定义Service接口继承IService接口
public interface IUserService extends IService<User> {}
​
// 自定义Service实现类,实现自定义接口并继承ServiceImpl类
// ServiceImpl<UserMapper, User>:用到的mapper和实体
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
}

三、扩展功能

1、代码生成

idea中存在插件MybatisPlus,能够代码生成。

2、静态工具

3、逻辑删除

基于代码逻辑模拟删除效果,但并不会真正删除数据。

  • 思路如下:
    • 在表中添加一个字段标记数据是否被删除
    • 当删除数据时把标记置为1
    • 查询时只查询标记为0的数据
  • 删除操作:
// 例如逻辑删除字段为deleted
UPDATE user SET deleted = 1 WHERE id = 1 AND deleted = 0
  • 查询操作:
SELECT * FROM user WHERE deleted = 0
mybatis-plus:
    global-config:
        db-config:
            logic-delete-field: flag # 全局逻辑删除的实体字段名,字段类型可以是boolean、integer
            logic-delete-value: 1 # 逻辑已删除值(默认为 1)
            logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

4、枚举处理器

假如一个实体中有大量的枚举类型,为了避免冗余,需要全局的处理器。

@Getter
enum UserStatus {
    NORMAL(1, "正常"),
    FROZEN(2, "冻结");

    @EnumValue  // 标记这个字段的值存入数据库
    private final int value;
    @JsonValue
    private final String desc;

    // 构造方法名必须与枚举类名一致
    UserStatus(int value, String desc) {
        this.value = value;
        this.desc = desc;
    }
}
mybatis-plus:
  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

5、JSON处理器

四、插件功能

MyBatisPlus基于MyBatis的Interceptor实现了一个基础拦截器,并在内部保存了MyBatisPlus的内置拦截器的集合:

序号拦截器拦截器描述描述
1TenantLineInnerInterceptor多租户插件
2DynamicTableNameInnerInterceptor动态表名插件
3PaginationInnerInterceptor分页插件
4OptimisticLockerInnerInterceptor乐观锁插件
5IllegalSQLInnerInterceptorSQL性能规范插件,检测并拦截垃圾SQL
6BlockAttackInnerInterceptor防止全表更新和删除的插件

1、分页插件

在配置类中注册MyBatisPlus的核心插件,同时添加分页插件:

@Configuration
public class MybatisConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        //1.初始化核心插件
         MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
         //2.添加分页插件
         PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
         pageInterceptor.setMaxLimit(1000L);
         //3.设置分页上限
         interceptor.addInnerInterceptor(pageInterceptor);
         return interceptor;
    }
}
@Test
void testPageQuery() {
    // 1.查询
    int pageNo = 1, pageSize = 5;
    // 1.1.分页参数
    Page<User> page = Page.of(pageNo, pageSize);
    // 1.2.排序参数, 通过OrderItem来指定
    page.addOrder(new OrderItem("balance", false));
    // 1.3.分页查询
    Page<User> p = userService.page(page);
    // 2.总条数
    System.out.println("total = " + p.getTotal());
    // 3.总页数
    System.out.println("pages = " + p.getPages());
    // 4.分页数据
    List<User> records = p.getRecords();
    records.forEach(System.out::println);
}

2、通用分页实体

3、通用分页实体与MP转换

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇