mybatis-plus基本使用

1、Mybatis-Plus

1.1 简介

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。

在这里插入图片描述
1.2 特性
  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
1.3 框架结构
框架结构
在这里插入图片描述

2、Mybatis-Plus 入门

2.1 数据库准备
DROP TABLE IF EXISTS user;

CREATE TABLE user
(
	id BIGINT(20) NOT NULL COMMENT '主键ID',
	name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
	age INT(11) NULL DEFAULT NULL COMMENT '年龄',
	email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
	PRIMARY KEY (id)
);

DELETE FROM user;

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
2.2 导入mybatis-plus依赖
<!--   mybatis-plus依赖     -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.4.2</version>
</dependency>
2.3 Spring整合MP
<!-- 配置Mybatis-plus的SqlSessionFactoryBean  -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <!-- 加载mybatis配置 -->
    <property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>


<!-- 配置Mapper扫描  -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.qf.mapper"/>
</bean>
2.4 编写实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;
    private String name;
    private Integer age;
    private String email;
}
2.5 编写Mapper接口
//BaseMapper封装了基本的CRUD
public interface UserMapper extends BaseMapper<User> {
}
2.5 测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class MPTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    public void test01(){
        List<User> userList = userMapper.selectList(null);
        userList.forEach(System.out::println);
    }
}

3、Mybatis-Plus实现CRUD

  • 通用 CRUD 封装BaseMapper (opens new window)接口,为 Mybatis-Plus 启动时自动解析实体表关系映射转换为 Mybatis 内部对象注入容器
  • 泛型 T 为任意实体对象
  • 参数 Serializable 为任意类型主键 Mybatis-Plus 不推荐使用复合主键约定每一张表都有自己的唯一 id 主键
  • 对象 Wrapper条件构造器
3.1 Insert增加

插入一条记录

//测试增加
@Test
public void test(){
    User user = new User(null,"jack",30,"jack@qq.com");
    userMapper.insert(user);
}

此时,代码会出现异常。因为User类并没有设置ID,那么MP会使用ID生成策略自动生成一个ID。

这个ID是由雪花算法得到的,类型为Long类型,而实体类在中ID为Integer类型

3.2 ID生成策略

通过@TableId(type = IdType.AUTO) 注解进行指定

主键类型参数说明
AUTO(0)数据库ID自增(数据库使用自增)
NONE(1)该类型为未设置主键类型(将跟随全局)
INPUT(2)用户手动输入ID
ID_WORKER(3)全局唯一ID (idWorker )
UUID(4)全局唯一ID (UUID)
ID_WORKER_STR(5)符串全局唯一ID (idWorker 的字符串表示)
3.3 Delete删除

根据 ID 删除

删除(根据ID 批量删除)

//测试删除
@Test
public void test03(){
    userMapper.deleteById(6);
}
//测试批量删除
@Test
public void test04(){
    Integer[] ids = {1,2,3,4};
    userMapper.deleteBatchIds(Arrays.asList(ids));
}
3.4 逻辑删除

在开发中有些数据不能直接从数据库中进行删除。用户删除数据有时候管理员还需要查看!!!

那么在实际的开发中可以实现逻辑删除

实现:

  • 1、在数据库中添加deleted字段(0表示未删除、1表示删除)
  • 2、在实体上添加@TableLogic注解
@TableLogic
private Integer deleted;
//测试逻辑删除
@Test
public void test11(){
    userMapper.deleteById(1);
}
# 执行sql语句为:
UPDATE user SET deleted=1 WHERE id=? AND deleted=0

添加逻辑删除属性后,查询中都会自动带上条件where deleted = 0

3.5 Update修改

根据 ID 修改(参数为实体类对象)

//测试修改
@Test
public void test05(){
    User user = new User(5,"rose",30,"rose@qq.com");
    userMapper.updateById(user);
}
3.6 Select查询

根据 ID 查询

查询(根据ID 批量查询)

根据 entity 条件,查询全部记录

根据 Wrapper 条件,查询总记录数

//测试根据id查询
@Test
public void test06(){
    User user = userMapper.selectById(1);
    System.out.println(user);
}
//查询(根据ID 批量查询)
@Test
public void test07(){
    List<User> userList = userMapper.selectBatchIds(Arrays.asList(1, 2, 3, 4));
    userList.forEach(System.out::println);
}
//根据 entity 条件,查询全部记录
@Test
public void test08(){
    List<User> userList = userMapper.selectList(null);
    userList.forEach(System.out::println);
}
//根据 Wrapper 条件,查询总记录数
@Test
public void test09(){
    Integer count = userMapper.selectCount(null);
    System.out.println(count);
}
3.7 分页查询
  • 使用数据库limit实现
  • 使用PageHelper分页插件
  • Mybatis-Plus内置了分页插件

根据 entity 条件,查询全部记录(并分页)

配置分页插件拦截器

<!--  设置分页插件    -->
<plugins>
    <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor">		</plugin>
</plugins>
//测试分页查询
@Test
public void test10(){
    Page<User> page = new Page<>(1,3);
    userMapper.selectPage(page, null);
    //userPage中包含了分页的相关信息
    System.out.println(page.getTotal());
    List<User> userList = page.getRecords();
    userList.forEach(System.out::println);
}

4、条件构造器

说明:

  • 以下出现的第一个入参boolean condition表示该条件是否加入最后生成的sql中,例如:query.like(StringUtils.isNotBlank(name), Entity::getName, name) .eq(age!=null && age >= 0, Entity::getAge, age)
  • 以下代码块内的多个方法均为从上往下补全个别boolean类型的入参,默认为true
  • 以下出现的泛型Param均为Wrapper的子类实例(均具有AbstractWrapper的所有方法)
  • 以下方法在入参中出现的R为泛型,在普通wrapper中是String,在LambdaWrapper中是函数(例:Entity::getId,Entity为实体类,getId为字段idgetMethod)
  • 以下方法入参中的R column均表示数据库字段,当R具体类型为String时则为数据库字段名(字段名是数据库关键字的自己用转义符包裹!)!而不是实体类数据字段名!!!,另当R具体类型为SFunction时项目runtime不支持eclipse自家的编译器!!!
  • 以下举例均为使用普通wrapper,入参为MapList的均以json形式表现!
  • 使用中如果入参的Map或者List,则不会加入最后生成的sql中!!!

警告:

不支持以及不赞成在 RPC 调用中把 Wrapper 进行传输

  1. wrapper 很重
  2. 传输 wrapper 可以类比为你的 controller 用 map 接收值(开发一时爽,维护火葬场)
  3. 正确的 RPC 调用姿势是写一个 DTO 进行传输,被调用方再根据 DTO 执行相应的操作
  4. 我们拒绝接受任何关于 RPC 传输 Wrapper 报错相关的 issue 甚至 pr
@Test
public void test12(){
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //年龄大于12,id为1、2、3
    queryWrapper
        .ge("age",20)
        .in("id",1,2,3);
    userMapper.selectList(queryWrapper);
}
@Test
public void test13(){
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //邮箱不为空,姓名为jack
    queryWrapper
        .isNotNull("email")
        .eq("name","jack");
    userMapper.selectList(queryWrapper);
}
@Test
public void test15(){
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //按照年龄降序
    queryWrapper
        .orderByDesc("age");
    userMapper.selectList(queryWrapper);
}
@Test
public void test16(){
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //姓名中包含s
    queryWrapper
        .like("name","s");
    userMapper.selectList(queryWrapper);
}
@Test
public void test17(){
    UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
    //姓名中包含s
    updateWrapper
        .like("name","s");
    User user = new User(null,"rose",null,"rose@qq.com");
    //修改以上条件构造器中包含的数据
    userMapper.update(user,updateWrapper);
}

5、代码生成器

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

5.1 引入依赖
<!--  代码生成器依赖  -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.1</version>
</dependency>
<!--  模板引擎 依赖  -->
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.3</version>
</dependency>
<!--   日志依赖     -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.30</version>
</dependency>
5.2 生成器代码
public class CodeGenerator {
    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        //获取当前路径
        String projectPath = System.getProperty("user.dir");
        //设置生成代码位置
        gc.setOutputDir(projectPath + "/src/main/java");
        //设置代码文件头作者
        gc.setAuthor("威哥");
        //设置是否在资源管理器打开
        gc.setOpen(false);
        //设置生成代码是否覆盖
        gc.setFileOverride(true);
        //设置去除生成代码接口中的I
        gc.setServiceName("%sService");
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql:///java2101");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        //设置模块名称
        //pc.setModuleName("shopping");
        pc.setParent("com.qf");
        pc.setEntity("pojo");
        pc.setMapper("mapper");
        pc.setService("service");
        pc.setController("controller");
        mpg.setPackageInfo(pc);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        //表名  下划线转驼峰
        strategy.setNaming(NamingStrategy.underline_to_camel);
        //字段名  下划线转驼峰
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //实体类是否使用lombok
        strategy.setEntityLombokModel(true);
        //Controller是否使用RESTful风格(RestController)
        strategy.setRestControllerStyle(true);

        //设置逻辑删除字段
        strategy.setLogicDeleteFieldName("deleted");
        //设置生成的表名
        strategy.setInclude("user");
        mpg.setStrategy(strategy);
        mpg.execute();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值