SpringBoot整合MybatisPlus(小白也秒懂)

SpringBoot整合MybatisPlus(小白也秒懂)

话不多说,上流程

创建好对应的数据库和表

-- 删除tb_brand表
drop table if exists tb_brand;
-- 创建tb_brand表
create table tb_brand
(
    -- id 主键
    id           int primary key auto_increment,
    -- 品牌名称
    brand_name   varchar(20),
    -- 企业名称
    company_name varchar(20),
    -- 排序字段
    ordered      int,
    -- 描述信息
    description  varchar(100),
    -- 状态:0:禁用  1:启用
    status       int
);
-- 添加数据
insert into tb_brand (brand_name, company_name, ordered, description, status)
values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
       ('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1);

创建SpringBoot项目

目录结构在这里插入图片描述

导入pom.xml配置

   <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.3.0</version>
        </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>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>
<!--        mybatisplus依赖-->
        <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.1</version>
    </dependency>
<!--        数据源依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0</version>
        </dependency>

    </dependencies>

yml文件配置

server:
  port: 8889

spring:
  application:
    name: mybatis_test
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_test?useSSL=false&serverTimezone=UTC
    username: root
    password: 1234
 mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印SQL日志到控制台
  global-config:
    db-config:
      id-type: auto #主键id生成策略。

创建对应的实体类

@Data
@Entity
@TableName("tb_brand")
public class Brand implements Serializable {
    private Integer id;
    // 品牌名称
    private String brandName;
    // 企业名称
    private String companyName;
    // 排序字段
    private Integer ordered;
    // 描述信息
    private String description;
    // 状态:0:禁用  1:启用
    private Integer status;
    
}

这里的@TableName注解是依赖映射数据库对应表的名字的,如实体类名与表名一致可以不加。

创建对应的Dao接口

@Mapper
public interface BrandDao extends BaseMapper<Brand> {
}

@Repository和@Mapper的区别

  • @Repository和@Mapper都是作用在dao层的接口,使其生成代理对象Bean。
  • @Repository:需要在添加配置地址@MapperScannerConfigurer来使用,单独使用会报错
  • @Mapper:只需要在dao类上使用就行,若有多个Mapper在启动类上加MapperScan(“mapper所在的包”)就行

这里继承了MybatisPlus的BaseMapper接口,泛型内填实体类的类名

使用Mybatis进行数据层开发(CRUD)

增加数据

int insert(T t) //新增方法

编写测试案例

@SpringBootTest
class MybatisPlustTestApplicationTests {
    @Autowired
    private BrandDao brandDao;
    /**
     * 增加对象测试
     */
    @Test
    public void testInsert(){
        Brand brand = new Brand();
        brand.setBrandName("菠萝");
        brand.setCompanyName("菠萝公司");
        brand.setDescription("菠萝很好吃");
        brand.setOrdered(100);
        brand.setStatus(1);
        int insert = brandDao.insert(brand);
        if (insert > 0){
            System.out.println("添加成功");
        }else {
            System.out.println("添加失败");
        }
    }
}

​ 执行成功后数据库会生成一条数据。这个测试案例中没有给id赋值,是因为MybatisPlus的id生成策略。在yml文件中配置了auto策略。意识是跟随主键id自增。需要表中有主键并设置了主键id自生成。

​ 从以上案例可以发现,对比Mybatis,Mybatisplus简化了许多,例如无需在Dao中编写方法,也无需创建对应的xml文件。但是需知道的是,MybatisPlus是用来强化Mybati,而非替代,因此,在遇到一些MybatisPlus无法解决的场景时,也可以使用Mybatis的方法来解决。


修改数据

  • 根据id修改
int updateById(T entity);

编写测试案例

/**
 *根据id删除数据测试
 */
@Test
public void testDelete(){
    int i = 7;
    int i1 = brandDao.deleteById(i);
    if(i1 > 0){
        System.out.println("删除成功");
    }else{
        System.out.println("删除失败");
    }
}

该方法是通过id来修改的,因此对象需要有id的值。


删除数据

  • 根据id删除
  int deleteById(Serializable id);

编写案例测试

/**
 *根据id删除数据测试
 */
@Test
public void testDelete(){
    int i = 7;
    int i1 = brandDao.deleteById(i);
    if(i1 > 0){
        System.out.println("删除成功");
    }else{
        System.out.println("删除失败");
    }
}

此方法是根据id删除,所传参数为对象的id

  • 批量删除
 int deleteBatchIds(Collection<? extends Serializable> idList);

编写测试案例

/**
 * 批量删除,根据集合
 */
@Test
public void testDeleteArr(){
    List list = new ArrayList();
    list.add(13);
    list.add(14);
    list.add(15);

    int i = brandDao.deleteBatchIds(list);
    if(i > 0){
        System.out.println("删除成功");
    }else{
        System.out.println("删除失败");
    }
}

此方法根据集合删除,集合中可传入多个id值


查询数据

接下来,是最常用的查询数据

普通查询
  • 查询所有
List<T> selectList(Wrapper<T> queryWrapper);

编写测试案例

/**
 * 查询所有测试
 */
@Test
public void testGetALl(){
    List<Brand> brands = brandDao.selectList(null);
    System.out.println(brands);
}

该方法所传参数为查询条件,条件的设置后面再讲,现在先传null

  • 根据id查询
T selectById(Serializable id);

编写测试案例

    /**
     * 根据id查询数据
     */
    @Test
    public void selectById(){
        int i  = 1;
        Brand brand = brandDao.selectById(i);
        System.out.println(brand);
    }

分页查询

分页查询方法:

IPage<T> selectPage(IPage<T> page, Wrapper<T> queryWrapper)
  • IPage:用来构建分页查询条件
  • Wrapper:用来构建条件查询的条件,目前我们没有可直接传为Null
  • IPage:返回值,你会发现构建分页条件和方法的返回值都是IPage

IPage是一个接口,我们需要找到它的实现类来构建它,具体的实现类,可以进入到IPage类中按ctrl+h,会找到其有一个实现类为Page

  1. 调用方法传参获取返回值
 /**
  * 分页查询
  */
// selectPage(IPage<T> page, Wrapper<T> queryWrapper)
 @Test
 public void testSelectPage(){
     //1.创建IPage对象,1为当前页码,3为每页记录数
     IPage<Brand> iPage = new Page<>(1,3);
     //2.执行分页查询
     IPage<Brand> brandIPage = brandDao.selectPage(iPage, null);
     //3 获取分页结果
     System.out.println("当前页码值:"+iPage.getCurrent());
     System.out.println("每页显示数:"+iPage.getSize());
     System.out.println("一共多少页:"+iPage.getPages());
     System.out.println("一共多少条数据:"+iPage.getTotal());
     System.out.println("数据:"+iPage.getRecords());
 }
  1. 设置分页拦截器

这个拦截器MP已经为我们提供好了,我们只需要将其配置成Spring管理的bean对象即可。

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        //1 创建MybatisPlusInterceptor拦截器对象
        MybatisPlusInterceptor mpInterceptor=new MybatisPlusInterceptor();
        //2 添加分页拦截器
        mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mpInterceptor;
    }
}
条件查询

​ MyBatisPlus将书写复杂的SQL查询条件进行了封装,使用编程的形式完成查询条件的组合。

​ 这个我们在前面都有见过,比如查询所有和分页查询的时候,都有看到过一个Wrapper类,这个类就是用来构建查询条件的
​ 在进行查询的时候,我们的入口是在Wrapper这个类上,因为它是一个接口,所以我们需要去找它对应的实现类,关于实现类也有很多,说明我们有多种构建查询条件对象的方式

在这里插入图片描述

先来看第一中:QueryWrapper

/**
 * 条件查询数据(QueryWrapper)
 */
@Test
public void testGetAll(){
    //1.创建QueryWrapper对象
    QueryWrapper<Brand> qw = new QueryWrapper<Brand>();
    //2.设置查询条件,lt()代表小于号,column:字段名称,val:值
    qw.lt("ordered",100);
    List list = brandDao.selectList(qw);
    System.out.println(list);
}

​ 从上面案例看,通过QueryWrapper实体类设置好查询条件后即可进行查询,这里是通过书写字段的形式来设置条件字段的,为了避免开发时字段书写错误,可以通过Lambda的方法来进行字段的条件设置。

/**
 * 条件查询数据(QueryWrapper)
 */
@Test
public void testGetAll(){
    //1.创建QueryWrapper对象
    QueryWrapper<Brand> qw = new QueryWrapper<Brand>();
    //2.设置查询条件,lt()代表小于号,column:字段名称,val:值
   // qw.lt("ordered",100);

    //2.2使用Lambda表达式方法设置查询条件
    qw.lambda().lt(Brand::getOrdered,100);
    List list = brandDao.selectList(qw);
    System.out.println(list);
}

这种方法可以很好的避免字段字母输错的问题,但多加了个lambda()方法。

第二种方法:LambdaQueryWrapper()

/**
 * 条件查询数据(LambdaQueryWrapper)
 */
@Test
public void testGetAll2(){
    //1.创建LambdaQueryWrapper对象
    LambdaQueryWrapper<Brand> lqw = new LambdaQueryWrapper<>();
    //2.设置插叙条件
    lqw.lt(Brand::getOrdered,100);
    //3.执行查询方法
    List<Brand> brands = brandDao.selectList(lqw);
    System.out.println(brands);
}

LambdaQueryWrapper()支持使用Lambda格式的书写方式

注意:构建LambdaQueryWrapper的时候泛型不能省。

/**
 * 各种条件查询
 * * eq():等于
 * * gt():大于(>)
 * * ge():大于等于(>=)
 * * lt():小于(<)
 * * le():小于等于(<=)
 * * between():between ? and ?
 */

以上都是单个条件查询,若是有多个条件该如何构建查询条件呢?

例如:我们要查询字段status大于0并且ordered字段小于100的数据

/**
 * 多条件查询数据(LambdaQueryWrapper)
 */
@Test
public void testGetAll3(){
    //1.创建LambdaQueryWrapper对象
    LambdaQueryWrapper<Brand> lqw = new LambdaQueryWrapper<>();
    //2.设置查询条件(2个条件)
    lqw.gt(Brand::getStatus,0);
    lqw.lt(Brand::getOrdered,100);
    //3.执行查询方法
    List<Brand> brands = brandDao.selectList(lqw);
    System.out.println(brands);
}

可以看到,只需要编写两个条件就默认是&&的关系

多条件查询也支持链式编程

查找字段status大于0或ordered字段小于100的数据

/**
 * 多条件查询数据(LambdaQueryWrapper)
 * 链式编程
 */
@Test
public void testGetAll3(){
    //1.创建LambdaQueryWrapper对象
    LambdaQueryWrapper<Brand> lqw = new LambdaQueryWrapper<>();
    //2.设置查询条件(2个条件)
    lqw.gt(Brand::getStatus,0).or().lt(Brand::getOrdered,100);
    //3.执行查询方法
    List<Brand> brands = brandDao.selectList(lqw);
    System.out.println(brands);
}

当我们在不确定前端传来的条件为几个时,可以用以下方法拼接查询条件

/**
 * 动态多条件查询数据(LambdaQueryWrapper)
 */
@Test
public void testGetAll4(){
    //模拟前端传来的数据
    BrandDto brandDto = new BrandDto();
    brandDto.setOrdered(100);
    brandDto.setOrdered2(5);
    LambdaQueryWrapper<Brand> lqw = new LambdaQueryWrapper<>();
    //设置查询条件
    if(brandDto.getOrdered() != null){
        lqw.lt(Brand::getOrdered,brandDto.getOrdered());
    }
    if(brandDto.getOrdered2() != null){
        lqw.gt(Brand::getOrdered,brandDto.getOrdered2());
    }
    //执行查询方法
    List<Brand> brands = brandDao.selectList(lqw);
    System.out.println(brands);
}

上面的案例用if判空来确定查询条件,MybatisPlus还为我们提供了一种更为简便的方法

lt(boolean condition, R column, Object val);
/**
 * 动态多条件查询数据简化版(LambdaQueryWrapper)
 * condition属性
 */
@Test
public void testGetAll5(){
    //模拟前端传来的数据
    BrandDto brandDto = new BrandDto();
    brandDto.setOrdered(100);
    brandDto.setOrdered2(5);
    LambdaQueryWrapper<Brand> lqw = new LambdaQueryWrapper<>();
    //设置查询条件
    lqw.lt(brandDto.getOrdered() != null,Brand::getOrdered,brandDto.getOrdered());
    lqw.gt(brandDto.getOrdered2() != null,Brand::getOrdered,brandDto.getOrdered2());
    //执行查询方法
    List<Brand> brands = brandDao.selectList(lqw);
    System.out.println(brands);
}

此方法是原来方法的重载方法,在设置查询条件前加了一个表达式属性,当conition为true时则添加条件,为false时则不添加。

模糊查询

MybatisPlus也提供了一组模糊查询的方法

 /**
     * * like():前后加百分号,如 %J%
     * * likeLeft():前面加百分号,如 %J
     * * likeRight():后面加百分号,如 J%
     */
@Test
public void testGetAll5(){
    LambdaQueryWrapper<Brand> lqw = new LambdaQueryWrapper<>();
    //like()
    //lqw.like(Brand::getCompanyName,"科技有限");
    //likeLeft()
    lqw.likeLeft(Brand::getBrandName,"米");
    //likeRight()
    lqw.likeRight(Brand::getCompanyName,"小");
    List<Brand> brands = brandDao.selectList(lqw);
    System.out.println(brands);
}

查询投影

刚才的数据,我们都是查询所有字段相当于

select * from table

当想查询某一些字段时该使用select()方法

/**
 * 查询投影,利用select()来指定查询的字段
 */
@Test
public void testGetAll(){
    LambdaQueryWrapper<Brand> lqw = new LambdaQueryWrapper<>();
    lqw.select(Brand::getBrandName,Brand::getCompanyName,Brand::getDescription);
    lqw.gt(Brand::getOrdered,0);
    List<Brand> brands = brandDao.selectList(lqw);
    System.out.println(brands);
}
  • select(…)方法用来设置查询的字段列,可以设置多个,最终的sql语句为:

    SELECT id,name,age FROM teble
    
  • 如果使用的不是lambda,就需要手动指定字段,这里要使用QueryWrapper和表中的字段名

/**
 * 查询投影,利用select()来指定查询的字段
 */
@Test
public void testGetAll(){
    	QueryWrapper<Brand> lqw = new QueryWrapper<>();
        lqw.select("brand_name","company_name","description");
        lqw.gt("ordered",0);
        List<Brand> brands = brandDao.selectList(lqw);
        System.out.println(brands);
}

聚合函数
需求:聚合函数查询,完成count、max、min、avg、sum的使用

count:总记录数

max:最大值

min:最小值

avg:平均值

sum:求和
/**
 * 聚合函数
 */
@Test
public void testGetAll2(){
   QueryWrapper<Brand> lqw = new QueryWrapper<>();
    lqw.select("count(*) as count");
    List<Map<String, Object>> maps = brandDao.selectMaps(lqw);
    System.out.println(maps);
}
分组查询
/**
 * 分组查询
 */
@Test
public void testGetAll3(){
    QueryWrapper<Brand> qw = new QueryWrapper<>();
    qw.select("count(*) as count,ordered");
    qw.groupBy("ordered");
    List<Map<String, Object>> maps = brandDao.selectMaps(qw);
    System.out.println(maps);
}

这个查询方法相当于sql语句:

select count(*) as count,ordered from tb_brand group by ordered;
排序查询
orderBy(boolean condition, boolean isAsc, R... columns)
 /**
     * condition :条件,返回boolean,
     		当condition为true,进行排序,如果为false,则不排序
     * isAsc:是否为升序,true为升序,false为降序
     * columns:需要操作的列
     */
    /**
     * 根据id排序查询
     */
    @Test
    public void testOrder(){
        LambdaQueryWrapper<Brand> lqw = new LambdaQueryWrapper<>();
        lqw.orderBy(true,false,Brand::getId);
        List<Brand> brands = brandDao.selectList(lqw);
        System.out.println(brands);
    }

MybatisPlus中的Service开发

刚刚都是编写Dao层的开发,在一边的service层开发,都是写好service接口和serviceImpl实现类,再再serviceImpl实现类中注入Dao实体类,实现service接口的方法。如下:

/**
*service接口
*/
public interface UserService{
	
}
/**
*service实现类
*/
@Service
public class UserServiceImpl implements UserService{

}

接口和实现类有了以后,需要在接口和实现类中声明方法

public interface UserService{
	public List<User> findAll();
}

@Service
public class UserServiceImpl implements UserService{
    @Autowired
    private UserDao userDao;
    
	public List<User> findAll(){
        return userDao.selectList(null);
    }
}

MybatisPlus提供了一个Service接口和实现类,分别是:IServiceServiceImpl,后者是对前者的一个具体实现。具体使用方式如下:

  • service接口
public interface BrandService extends IService<Brand> {
}
  • serviceImpl实现类
@Service
public class BrandServiceImpl extends ServiceImpl<BrandDao, Brand> implements BrandService {
}
  • 测试案例
@SpringBootTest
public class MybatisPlustTest3 {
    
    @Autowired
    private BrandService brandService;
    /**
     * 查询所有
     */
    @Test
    public void testService(){
        List<Brand> list = brandService.list(null);
        System.out.println(list);
    }
}

修改以后的好处是,MP已经帮我们把业务层的一些基础的增删改查都已经实现了,可以直接进行使用。至于更复杂的方法,可以通过在service接口写方法并实现的办法实现。MP封装的Service层都有哪些方法可以用可以在MybatisPlus官网查看

https://www.baomidou.com/

最后再提示:MybatisPlus不是替代Mybatis,它旨在加强mybatis,使开发者在开发一些基础的方法时可以更为便捷的实现,在MP环境下也可以使用mybatis的各种方法

体使用方式如下:

  • service接口
public interface BrandService extends IService<Brand> {
}
  • serviceImpl实现类
@Service
public class BrandServiceImpl extends ServiceImpl<BrandDao, Brand> implements BrandService {
}
  • 测试案例
@SpringBootTest
public class MybatisPlustTest3 {
    
    @Autowired
    private BrandService brandService;
    /**
     * 查询所有
     */
    @Test
    public void testService(){
        List<Brand> list = brandService.list(null);
        System.out.println(list);
    }
}

修改以后的好处是,MP已经帮我们把业务层的一些基础的增删改查都已经实现了,可以直接进行使用。至于更复杂的方法,可以通过在service接口写方法并实现的办法实现。MP封装的Service层都有哪些方法可以用可以在MybatisPlus官网查看

https://www.baomidou.com/

最后再提示:MybatisPlus不是替代Mybatis,它旨在加强mybatis,使开发者在开发一些基础的方法时可以更为便捷的实现,在MP环境下也可以使用mybatis的各种方法

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值