Mybatis-Plus知识点总结(上)

Mybatis-Plus知识点总结

1.简介

Mybatis-Plus(简称MP),是Mybatis框架的增强版,在不改变Mybatis原有功能的基础上进行功能增强,目标是为了简化开发,提升效率效率。官网地址:MyBatis-Plus (baomidou.com)

2.快速入门

1.快速创建一个SpringBoot工程,并在pom.xml文件中导入Mybatis-Plus的坐标和mysql的坐标

tips:因为IDEA还未引入MP的依赖选项,因此MP的坐标需要在工程创建以后手动引入,mysql坐标可以在创建工程时进行勾选引入。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.5.1</version>
	</dependency>
2.进行application.yml文件的数据库参数配置
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?ServerTime=UTC
    username: root
    password: root
3.创建实体类
public class User {

      private int id;
    private String username;
    private Integer age;
    private String sex;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}
4.创建mapper接口,继承Mybatis-Plus包中的BaseMapper,泛型为要进行操作的实体类
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ht.domain.User;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

5.在测试类中,注入UserMapper,测试对User对象基本的增删查改的操作(包含知识点)

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ht.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class MybatisplusLearningApplicationTests {

	@Autowired
	private UserMapper userMapper;

	//增加

	/**
	 *     int insert (T t)
	 *    参数解释:
	 *      T:泛型,用来新增保存的对象数据
	 *    int:返回值,新增成功返回为1,新增失败返回为0
	 *
	 */
	@Test
   void testSave(){
      //1.定义一个新的User对象,并对属性赋值
	   User user = new User();
	   user.setUsername("zhangsan");
	   user.setAge(21);
	   user.setSex("男");
	   //2.调用userMapper中的方法向数据库中进行插入
	   userMapper.insert(user);
   }

   //删除

	/**
	 *   int deleteById (Serializable id)
	 *   参数解释:
	 *      Serializable:Serializable是String和Number的父类,Number是Integer,Float,Double的父类,因此Serializable
	 *      类似于我们用Object类型用来接收任意类型的对象一样
	 *      int:返回值,新增成功返回为1,新增失败返回为0
	 *
	 *   int deleteById (T t)
	 *  参数解释:
	 *      T:泛型,用来需要删除的对象数据,因为是根据ID值进行删除,所以对象属性值中需要包含ID值
	 *      int:返回值,新增成功返回为1,新增失败返回为0
	 */
   @Test
   void testDelete(){
		//1.根据id进行删除
	   userMapper.deleteById(2);
		//2.根据指定对象进行删除
	   User user = new User();
	   user.setUsername("zhangsan");
	   user.setAge(21);
	   user.setSex("男");
	   userMapper.deleteById(user);

   }

   //查找

	/**
	 *   T selectById (Serializable id)
	 *   参数解释:
	 *     T:根据ID查询返回的一条查询对象
	 *     Serializable:解释参照上面,为主键
	 *
	 *   List<T> selectList(Wrapper<T> queryWrapper)
	 *   参数解释:
	 *      Wrapper:用来构建条件查询的条件,没有可直接传为Null,默认返回所有
	 *      List<T>:查询的结果是一个对象集合
	 */
	@Test
   void testSearch(){
		//根据id进行查找
		User user = userMapper.selectById(2);
		//查找所有
		List<User> users = userMapper.selectList(null);
		System.out.println(users);//[User{username='ttttt', age=22, sex='男'}, User{username='ttttt', age=22, sex='男'}, User{username='ttttt', age=22, sex='男'}, User{username='ttttt', age=22, sex='男'}, User{username='zhangsan', age=21, sex='男'}]

	}
	//修改

	/**
	 *  T selectById (Serializable id)
	 *  参数信息:
	 *     T:需要修改的数据内容,注意因为是根据ID进行修改,所以传入的对象中需要有ID属性值
	 *     Serializable:解释参照上面,为主键
	 */
	@Test
	void testUpdate(){
		User user = new User();
		user.setUsername("zhangsan");
		user.setSex("女");
		user.setAge(23);
		//根据ID进行修改
		userMapper.updateById(user);
	}



	//分页查询

	/**
	 *    IPage<T> selectPage(IPage<T> page, Wrapper<T> queryWrapper)
	 *    参数解释:
	 *    IPage:返回值
	 *    IPage:用于构建分页查询的条件
	 *    Wrapper:用于构建条件查询的条件
	 *
	 */
	@Test
	void testPage(){
        //1.创建IPage分页对象,设置分页参数,1为当前页码,2为每页的记录数
		//IPage是一个接口,因此需要new它实现类,只有一个Page类
		IPage<User> page = new Page<>(1,2);
		//2.执行分页查询
		userMapper.selectPage(page, null);
		//3.查询不同结果
        
		System.out.println("当前的页面:"+page.getCurrent());//当前的页面:1
		System.out.println("页数:"+page.getSize());//页数:2
		System.out.println("数据数:"+page.getRecords());//数据数:[User{username='zhangsan', age=21, sex='男'}, User{username='zhangsan', age=21, sex='男'}]
		System.out.println("一共多少页:"+page.getPages());//一共多少页:3
		System.out.println("一共多少条数据:"+page.getTotal());//一共多少条数据:5


	}

}

注意:想要分页查询生效,需要配置一个分页拦截器MybatisPlusInterceptor(MP已经提供好了),并注入Spring容器,创建过程在下面

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisPlusConfig  {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        //1.创建MyBatisInterceptor对象
        MybatisPlusInterceptor mybatisPlusInterceptor1 = new MybatisPlusInterceptor();
        //2.添加分页拦截器,如需添加其它拦截器,可直接添加下面语句
        // mybatisPlusInterceptor1.addInnerInterceptor(new 所需拦截器类名);
        mybatisPlusInterceptor1.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor1;
    }
}

3.查询知识点详解

增删改查中,查询功能是比较复杂而且非常重要的,详细解释一下

3.1 条件查询

Mybatis-Plus将复杂的sql语句进行了封装,使用编程的方式就完成条件查询中条件组和,达到了简化开发的目的,用于构建查询条件的类为Wrapper类,上文已经作为参数出现过。

重点来了,Wrapper类怎样来进行条件的构建呢?一般常用的为QueryWrapper和LambdaWrapper

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wW8HtRrK-1659333705447)(C:\Users\if shining\AppData\Roaming\Typora\typora-user-images\image-20220801091722795.png)]

3.1.1 QueryWrapper
	//使用QueryWrapper
	@Test
	void testConditionSearch(){
		QueryWrapper<User> queryWrapper = new QueryWrapper<>();
		//生成的sql语句:SELECT username,age,sex FROM user WHERE (age > ?)
		//gt:<
		queryWrapper.gt("age",23);
		List<User> users = userMapper.selectList(queryWrapper);
		System.out.println(users);//[User{username='zhangsan', age=21, sex='男'}, User{username='zhangsan', age=21, sex='男'}, User{username='zhangsan', age=21, sex='男'}, User{username='zhangsan', age=23, sex='男'}]
	}

3.1.2 LambdaWrapper
//使用LambdaWrapper
	@Test
	void testConditionSearch2(){
		LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.gt(User::getAge,23);
		List<User> user1 = userMapper.selectList(lambdaQueryWrapper);
		System.out.println(user1);//[User{username='zhangsan', age=21, sex='男'}, User{username='zhangsan', age=21, sex='男'}, User{username='zhangsan', age=21, sex='男'}, User{username='zhangsan', age=23, sex='男'}]
	}

注意: 使用QueryWrapper可能出现字段名写错的情况,如age写成aeg,导致查询失败,而且不容易发现,使用LambdaWrapper,为lambda表达式中的,类名::方法名,这样不会出现字段名出现错误的信息。构建LambdaQueryWrapper的时候泛型不能省。

3.2 多条件查询

在查询中,上述两种方式,任意哪一种都可以使用,上面都是单条件,现在我们开始使用多条件

	//案例1:查询user表中年龄在21-25岁的用户信息
	@Test
	void testConditionSearch3(){
		LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.gt(User::getAge,21);
		lambdaQueryWrapper.lt(User::getAge,25);
		List<User> users = userMapper.selectList(lambdaQueryWrapper);
		System.out.println(users);//[User{username='zhangsan', age=23, sex='男'}]
	}

也可以使用链式编程

@Test
	void testConditionSearch5(){
		LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.gt(User::getAge,21).lt(User::getAge,25);
		List<User> users = userMapper.selectList(lambdaQueryWrapper);
		System.out.println(users);//[User{username='zhangsan', age=23, sex='男'}]
	}
     //案例2:查询数据库表中,年龄小于21或年龄大于24的数据
	//or():相当于sql语句中的or关键字,不加默认是and
	@Test
	void testConditionSearch6(){
		LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		//生成的sql语句: SELECT username,age,sex FROM user WHERE (age > ? OR age < ?)
		lambdaQueryWrapper.gt(User::getAge,21).or().lt(User::getAge,25);
		List<User> users = userMapper.selectList(lambdaQueryWrapper);
		System.out.println(users);//[User{username='zhangsan', age=21, sex='男'}, User{username='zhangsan', age=21, sex='男'}, User{username='aaa', age=25, sex='男'}, User{username='zhangsan', age=21, sex='男'}, User{username='zhangsan', age=23, sex='男'}]
	}

or():相当于sql语句中的or关键字,不加默认是and

3.3 查询指定字段的值
3.3.1 使用Lambda
@Test
	void testConditionSearch7(){
		LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		//生成的sql语句:SELECT username,age FROM user
		lambdaQueryWrapper.select(User::getUsername,User::getAge);
		List<User> users = userMapper.selectList(lambdaQueryWrapper);
		System.out.println(users);//[User{username='zhangsan', age=21, sex='null'},User{username='zhangsan', age=21, sex='null'}, User{username='aaa', age=25, sex='null'}, User{username='zhangsan', age=21, sex='null'}, User{username='zhangsan', age=23, sex='null'}]

select(…)方法:用来设置查询的字段列,可以设置多个,用逗号分割

3.3.2 不使用Lambda,需要手动指定字段名
@Test
	void testConditionSearch8(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
		queryWrapper.select("username","age");
		List<User> users = userMapper.selectList(queryWrapper);
		System.out.println(users);//[User{username='zhangsan', age=21, sex='男'}, User{username='zhangsan', age=21, sex='男'}, User{username='aaa', age=25, sex='男'}, User{username='zhangsan', age=21, sex='男'}, User{username='zhangsan', age=23, sex='男'}]
	}
3.4 聚合查询

聚合查询函数一般常有的有:count(记录总条数),max(最大值),min(最小值),avg(平均数),sum(求和)

	//聚合函数
	@Test
	void testConditionSearch9() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<>();
		//生成的sql语句:SELECT count(*) as count FROM user
		queryWrapper.select("count(*) as count");
		//生成的sql语句:SELECT max(age) as max_age FROM user
		queryWrapper.select("max(age) as max_age");
		//生成的sql语句:SELECT min(age) as min_age FROM user
		queryWrapper.select("min(age) as min_age");
		//生成的sql语句:SELECT avg(age) as avg_age FROM user
		queryWrapper.select("avg(age) as avg_age");
		//生成的sql语句:SELECT sum(age) as sum_age FROM user
		queryWrapper.select("sum(age) as sum_age");
		//使用selectMaps方法使用键值对的方式看到结果,例如:[{sum_age=111}]
		List<Map<String, Object>> users = userMapper.selectMaps(queryWrapper);
		System.out.println(users);

	}
3.5 分组查询
@Test
	void testConditionSearch10(){
		QueryWrapper<User> queryWrapper = new QueryWrapper<>();
		//下面两行生成的sql语句:SELECT max(age) as max_age,age FROM user GROUP BY age
		queryWrapper.select("max(age) as max_age,age");
		queryWrapper.groupBy("age");
		List<User> users = userMapper.selectList(queryWrapper);
		System.out.println(users);//[User{id=0, username='null', age=21, sex='null'}, User{id=0, username='null', age=23, sex='null'}, User{id=0, username='null', age=25, sex='null'}]
	}

**注意:**聚合查询和分组查询无法使用lambda表达式完成

3.6 常用查询条件
  • gt():大于(>)

  • ge():大于等于(>=)

  • lt():小于(<)

  • lte():小于等于(<=)

  • between():between ? and ?

  • eq():等值查询

  • like():前后加百分号,如 %J%

  • likeLeft():前面加百分号,如 %J

  • likeRight():后面加百分号,如 J%

  • orderBy排序

    • condition:条件,true则添加排序,false则不添加排序
    • isAsc:是否为升序,true升序,false降序
    • columns:排序字段,可以有多个
  • orderByAsc/Desc(单个column):按照指定字段进行升序/降序

  • orderByAsc/Desc(多个column):按照多个字段进行升序/降序

  • orderByAsc/Desc

    • condition:条件,true添加排序,false不添加排序
    • 多个columns:按照多个字段进行排序

以上只是一些常用方法,其它具体情况可以参照:条件构造器 | MyBatis-Plus (baomidou.com)

4.数据库表和实体类映射匹配

4.1 字段名和属性名一致

从数据库表中取出数据后,需要封装到指定模型中去,当数据库表中的字段名和实体中的属性名一致时,可以直接成功进行操作

public class User {

    private int id;
    private String username;
    private Integer age;
    private String sex;
}

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` char(2) DEFAULT NULL,
  PRIMARY KEY (`id`)
)
4.2 字段名和属性名不相同

在实际业务中,可能会出现数据库表中的字段名和实体类中的属性名不一致的情况,为了解决这种情况,Mybatis-plus提供来一个@TableField 注解来解决这个问题。

名称@TableField
类型属性注解
位置实体类属性定义上方
作用设置当前属性对应的数据库表中的字段关系
相关属性value(默认):设置数据库表字段名称
exist:设置属性在数据库表字段中是否存在,默认为true,此属性不能与value合并使用
select:设置属性是否参与查询,此属性与select()映射配置不冲突
public class User {
    private int id;
    @TableField(value = "username",exist = true,select = true)
    private String uname;
    private Integer age;
    private String sex;
}

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` char(2) DEFAULT NULL,
  PRIMARY KEY (`id`)
)
4.3 实体中出现数据库表未定义字段

当实体类中出现一个数据库表中未定义的字段,查询就会报错,解决方案还是使用@TableField 这个注解,这个注解中有一个exist属性,表示属性在数据库中是否存在,如果值为true则表示存在,为false则不存在,值为false时,在进行查询时不会去查询此字段的值。

public class User {
    private int id;
    @TableField(value = "username",exist = true,select = true)
    private String uname;
    private Integer age;
    private String sex;
    @TableField(exist = false)
    private String status;
}
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` char(2) DEFAULT NULL,
  PRIMARY KEY (`id`)
)
4.4 返回固定的字段数据

实际业务中,有一些敏感数据可能不想让其它人看到,所以对数据的查看需要进行一些设置,使用@TableField 注解可以进行设置哪些属性不被查询,@TableField 有一个属性select,用于设置默认是否查询该字段的值,值为true则查询,值为false则不查询。

public class User {
    private int id;
    @TableField(value = "username",exist = true,select = true)
    private String uname;
    @TableField(select = false)
    private Integer age;
    private String sex;
}
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` char(2) DEFAULT NULL,
  PRIMARY KEY (`id`)
)
4.5 数据库表名和实体类名不一致

在实际业务中,可能会出现数据库表名和实体类名不一致的情况,为了解决这种情况,Mybatis-plus提供来一个@TableName 注解来解决这个问题。

名称@TableName
类型类注解
位置实体类定义上方
作用设置当前类对应于数据库表关系
相关属性value(默认):设置数据库表名称
@TableName("user")
public class User3 {
    private int id;
    private String username;
    private Integer age;
    private String sex;

}

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` char(2) DEFAULT NULL,
  PRIMARY KEY (`id`)
)
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值