mybatis plus基础

mybatis plus

1引入依赖

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

2创建mapper,继承自BaseMapper<>中放实体泛型

public interface UserMapper extends BaseMapper<User> {
    
}

3直接调用UserMapper的增删改查方法即可。单表的基本增删改查可以实现。

类名驼峰转下划线为表明,字段名驼峰转下划线为字段名,

常用注解:

MybatisPlus中比较常用的几个注解如下
@TableName:用来指定表名

@Tableld:用来指定表中的主键字段信息

@TableField:用来指定表中的普通字段信息

@TableName("tb_user")
public class User {
    @TableId(value= "id",type= IdType.AUTO )
    private Long id;
    @TableField("username")
    private String  name;
    @TableField("is_married")  //is开头的
    private Boolean isMarried;
    @TableField("'order'")
    private Integer order;      //与数据库关键字报错
    @TableField(exist = false)  //表中不存在的
    private String address;

ldType枚举 :
AUTO : 数据库自增长
INPUT : 通过set方法自行输入
ASSIGN ID : 分配 ID,接口ldentifierGenerator的方法nextld来生成id默认实现类为DefaultldentifierGenerator雪花算法

mybatis-plus:
	type-aliases-package: com.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 # 更新笑略: 只更新非空字段

条件构造器的用法
QueryWrapper和LambdaQueryWrapper通常用来构建select、
delete、update的where条件部分
UpdateWrapper和LambdaUpdateWrapper通常只有在set语句比较特殊才使用
尽量使用LambdaQueryWrapper和LambdaUpdateWrapper
避免硬编码

自定义sql

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

1,基于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);

2,在mapper方法参数中用Param注解声明wrapper变量名称,必须是ew

void updateBalanceByIds(@Param("ew") LambdaQuerywrapper<User> wrapper, @Param("amount") int amount);

3,自定义sql,并使用Wrapper条件

<update id="updateBalanceByIds">
UPDATE tb_user SET balance = balance - #{amount} ${ew.customSqlSegment}
/update>

IService接口

插入:

save(T): boolean

saveBatch(Collection): boolean

saveBatch(Collection, int): boolean

saveOrUpdateBatch(Collection): boolean

saveOrUpdateBatch(Collection, int): boolean

saveOrUpdate(T): boolean

saveOrUpdate(T, Wrapper): boolean

修改:

saveOrUpdateBatch(Collection): boolean

saveOrUpdateBatch(Collection, int): boolean

updateByld(T): boolean

update(Wrapper): boolean

update(T, Wrapper): boolean

updateBatchByld(Collection): boolean

updateBatchByld(Collection, int): boolean

saveOrUpdate(T): boolean

删除:

removeByld(Serializable): boolean

removeByld(Serializable, boolean): boolean

removeByld(T): boolean

removeByMap(Map<String, Object>): boolean

remove(Wrapper<T>): booleanremoveBylds(Collection<?>): boolean

removeBylds(Collection<?>, boolean): boolean

removeBatchBylds(Collection<?>): boolean

removeBatchBylds(Collection<?>, boolean): boolean

removeBatchBylds(Collection<?>, int): boolean

removeBatchBylds(Collection<?>, int, boolean): boolean

列表查询:

listBylds(Collection<? extends Serializable>): List<T>

listByMap(Map<String, Object>): List<T>

list(Wrapper<T>): List<T>

list(): List<T>

查询单个:

getByld(Serializable): T

getOne(Wrapper<T>):T

getOne(Wrapper<T>, boolean):T

查询数量:

count(): long

count(Wrapper<T>): long

分页查询:

page(E, Wrapper<T>): E

page(E): E

调价构造器:

lambdaQuery(): LambdaQueryChainWrapper<T>

lambdaQuery(T): LambdaQueryChainWrapper<T>

lambdaUpdate(): LambdaUpdateChainWrapper<T>

复制Dto到info

BeanUtil.copyProperties(Souces,TargetClass): T

User user=BeanUtil.copyProperties(userDto,User.class);

BeanUtil.copyToList(SourceList,TargetClass): List<T>

List<User> list=BeanUtil.copyToList(userDtoList,User.class);

1.Mapper继承BaseMapper

public interface UserMapper extends BaseMapper<User> {
    
}

2.接口继承IService

public interface IUserService extends IService<User>{

}

3.实现类继承ServiceImpl

public UserServiceImpl extends ServiceImpl<UserMapper,User> implements IUserService{}

想要查询单个字段

使用select()

lambdaQuery().select(User::getUserName).eq(User::getUserId,1)

想要修改单个字段:set(User::getUserName,value)方法

IService批量新增

需求:批量插入10万条用户数据,并作出对比:
1 普通for循环插入,普通for循环逐条插入速度极差,不推荐
2 IService的批量插入,MP的批量新增,基于预编译的批处理,性能不错配置jdbc参数
3 开启rewriteBatchedStatements=true参数,开rewriteBatchedStatements,性能最好

第三种在yml中连接数据库的位置在最后拼上这个配置

MP扩展功能

代码生成


  1. 下载插件mybatis plus
  2. 在IDEA上面菜单栏选择other-》config database
  3. 输入相关信息,点击ok
  4. 选择other -》Code generator

tablePrefix是生成时去掉的表名前缀:如 t_message_

静态工具


Db静态工具类的方法和Iservice提供的方法几乎一样,只不过使用时需要传入字节码文件(.class),一般为了避免循环依赖时可以使用其进行操作。

Db.lambdaQuery(User.class).eq(User::getId,id).one;

逻辑删除


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

思路如下:
在表中添加一个字段标记数据是否被删除
当删除数据时把标记置为1
查询时只查询标记为0的数据

MvbatisPlus提供了逻辑删除功能,无需改变方法调用的方式,而是在底层帮我们自动修改CRUD的语句。我们要做的就是在application.yml文件中配置逻辑删除的字段名称和值即可:

mybatis-plus:
	global-config:
		db-config:
		Logic-delete-field: del_flag # 全局逻辑删除的实体字名,字段类型可以是boolean、integer
		Logic-delete-value: 1 # 逻辑已删值(默认为 1)
		Logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

枚举处理器


如何实现PO类中的枚举类型变量与数据库字段的转换?
给枚举中的与数据库对应value值添加@EnumValue注解,即可实现,@JsonValue注解用户实现给前端传递字段的指定

@EnumValue
private final int value;
@JsonValue
private final String desc;

分页

简单用法:

1 定义配置类,声明插件

@Configuration
public class MyBatisConfig {
@Bean
public MybatisPlusInterceptor mybatisplusInterceptor(){
    MybatisplusInterceptor interceptor = new MybatisplusInterceptor();
    // 1.创建分页插件
    PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSOL);
    paginationInnerInterceptor.setMaxLimit(1000L);
    // 2.添加分页插件
    interceptor.addInnerInterceptor(paginationInnerInterceptor);
    return interceptor;
  }
}

2使用

@Test
void testPageQuery() {
int pageNo = 1, pageSize = 2;
// 1.准备分页条件
// 1.1.分页条件
Page<User> page = Page.of(pageNo,pageSize);
// 1.2.排序条件,字段,true升序,false降序
page.addorder(new OrderItem(  "balance"r , true)) ;
page.addOrder(new OrderItem(  "id",  true));
// 2.分页查询,
Page<User> p = userService.page(page);
// 3.解析
 long total = p.getTotal();
 System.out.println("total=" + total);
 long pages = p.getPages();
 System.out.println("pages="+ pages);
 List<User> users = p.getRecords();
 users.forEach(System.out::println);

}

举例创建:

分页查询实体:

@Data
@ApiModel(description = "分页查询实体")
public class PageQuery {
    @ApiModelProperty("页码")
    private Integer pageNo ;
    
    @ApiModelProperty("每页大小")
    private Integer pageSize;
    
    @ApiModelProperty("排序字段")
    private String sortBy;
    
    @ApiModelProperty("是否升序")
    private Boolean isAsc;
    
    
    //user转userVo
/* 调用  
    return PageDTO.of(p,user ->
    // 1.拷贝基础属性
    UserVO vo = BeanUtil.copyProperties(user,UserV0.class);
    // 2.处理特殊逻辑
    return vo;
    );
*/
    
    
    public static <PO,V0> PageDTO<V0>  of(Page<P0> p, Function<PO,V0> convertor){
        PageDTO<V0> dto = new PageDTO<>();
		// 1.总条数
		dto,setTotal(p.getTotal()) ;
		// 2.总页数
		dto.setPages(p.getPages()) ;
		// 3,当前页数据
		List<PO> records = p.getRecords();
        // 4.拷贝user的VO
        dto,setList(records,stream() .map(convertor).collect(Collectors,toList()));
        // 5.返回
		return dto;  
    }
    
    public static PageDTO<UserVO>of(Page<User> p){
        PageDTO<UserV0> dto = new PageDTO<>();
        // 1.总条数
		dto.setTotal(p.getTotal());
        // 2.总页数
        dto,setPages(p.getPages());
        // 3.当前页数据
		List<User> records = p.getRecords();
        if (CollUtil.isEmpty(records)) {
            dto,setList(Collections.emptyList());
            return dto;
        }
		// 4.拷贝user的vO
        dto.setList(BeanUtil.copyToList(records, Uservo.class));
        // 5.返回
        return dto;
    }
}

用于传参的Dto:

@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(description ="用户查询条件实体")
public class UserQuery extends PageQuery {
    @ApiModelProperty("用户名关键字")
    private String name;
    @ApiModelProperty("用户状态: 1-正常,2-冻结")
    private Integer status;
    @ApiModelProperty("余额最小值")
    private Integer minBalance;
	@ApiModelProperty("余额最大值")
	private Integer maxBalance;
}

返回结果定义:

@Data
@ApiModel(description = "分页结果")
public class PageVO<T> {
    @ApiModelProperty("总条数")
    private Integer total;
    @ApiModelProperty("总页数")
    private Integer pages ;
    @ApiModelProperty("集合")
    private List<T> list;
}
public PageDTO<UserVo> queryUsersPage(UserQuery query){
    String name = query.getName();
	Integer status = query.getStatus() ;
	// 1.构建分页条件
	// 1.1.分页条件
	Page<User> page = Page.of(query.getPageNo(),query.getPageSize());
	// 1.2.排序条件
	page.addOrder(new OrderItem(query.getSortBy(),query.getIsAsc()));

    // 2.分页查询
	Page<User> p = lambdaQuery()
	.like( condition: name != null, User::getUsername, name).
        eq( condition: status != null, User::getStatus, status).page(page);
     // 3.封装VO结果
    PageVo<UserV0> dto = new PageVo<>();
    // 3.1.总条数
    dto.setTotal(p.getTotal()) ;
    // 3.2.总页数
	dto.setPages(p.getPages());
    // 3.3.当前页数据
	List<User> records = p.getRecords();
	if (CollUtil.isEmpty(records)) {
        dto.setList(Collections.emptyList());
     	return dto ;
	// 3.4.拷贝user的VO
    List<UserVo> vos = BeanUtil.copyToList(records, UserV0.class);
	dto.setList(vos);
	// 4.返回
	return dto; 
}

posted @ 2024-02-16 14:27  赤叶秋枫  阅读(33)  评论(0编辑  收藏  举报