欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MyBatis-Plus —— 入门

程序员文章站 2024-03-03 20:00:22
...

目录

 

一、MyBatis-Plusd的 简介及特性:

1、简介:

2、特性介绍:

二、lombok简介及安装

三、Mybatis-Plus 的使用准备

1、创建新的  maven 工程,并在 application.yml中配置数据库连接

2、创建实体类User 和对应数据库表

3、创建原始 Mapper 类并继承通用 Mapper

4、在启动类中添加 mapper 的包扫描路径

5、配置pom.xml

四、Mybatis-Plus 的基本使用

1、通用mapper新增方法

2、常用注解

3、排除非表字段的三种方式

五、Mybatis-Plus 查询方法

1、普通查询

2、条件构造器查询

3、Select 不列出全部字段

4、condition作用

5、实体作为条件构造器构造方法的参数

6、AllEq用法

7、其他使用条件构造器的方法

8、lambda条件构造器

六、自定义 sql

1、在 application.yml 中  配置映射文件地址:

2、第一种:

3、第二种:

七、分页查询

1、分页插件配置类: 创建 MybatisPlusConfig类,注入到 Spring中进行管理

2、分页查询的两种方式:

八、更新与删除

1、更新方法

2、删除方法

九、ActiveRecord 模式

AR模式的使用需要满足两个条件,如下:

条件1:必须存在对应的原始mapper并继承Model 泛型类,并配置相应类注解,

条件2: 在 mapper 接口 中要 继承 BaseMapper 泛型类


一、MyBatis-Plusd的 简介及特性:

1、简介:

它在Mybatis 的基础上进行加强,不对Mybatis 做结构性改变,有利于提高基于MyBatis 的项目开发效率

2、特性介绍:

特性一:

  • 无侵入、损耗少、强大的CRUD 操作
  • 支持Lambda 形式调用、支持多种数据库
  • 支持主键自动生成、支持ActiveRecord模式

特性二:

  • 支持自定义全局通用操作、支持关键词自动转义
  • 内置代码生成器、内置分页插件、内置性能分析插件
  • 内置全局拦截插件、内置sql 注入剥离器

二、lombok简介及安装

Lombok 会在编译时加入 GET/SET 、hashcode 等方法,其生成的方法会根据当前被标记的javabean属性的注解等动态生成,避免手动生成GET/SET方法时,当属性需求发生变化删改时 频繁的 修改 javabean中的GET/SET 、EQUALS等带来不必要的工作量 ;有利于提高开发的效率

MyBatis-Plus —— 入门

三、Mybatis-Plus 的使用准备

1、创建新的  maven 工程,并在 application.yml中配置数据库连接

MyBatis-Plus —— 入门

配置数据库和日志输出

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3333/mp?useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: root
    
logging:
  level:
    root: warn
    com.mp.dao: trace
  pattern: 
    console: '%p%m%n'

2、创建实体类User 和对应数据库表

import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
public class User extends Model<User>{
	private Long id;
    //用户名

	private String name;
	//年龄
	private Integer age;
	//邮箱
	private String email;
	//管理id
	private Long managerId;
	//创建时间
	private LocalDateTime createTime;	
}

因为使用了lombok插件,因此不需要手动创建 GET/SET 方法以及 hashcode等方法,前面已经做过解释。

3、创建原始 Mapper 类并继承通用 Mapper

public interface UserMapper extends BaseMapper<User>{
	
}

4、在启动类中添加 mapper 的包扫描路径

@SpringBootApplication
@MapperScan("com.mp.dao")
public class Bootstrap 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}

5、配置pom.xml

 <parent>
  	<groupId>org.springframework.boot</groupId>
  	<artifactId>spring-boot-starter-parent</artifactId>
  	<version>2.1.3.RELEASE</version>
  	<relativePath></relativePath>
  </parent>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <!-- springboot启动器 -->
    <dependency>    	
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter</artifactId>
    </dependency>
     <!-- springboot测试启动器 -->
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-test</artifactId>
    	<scope>test</scope>
    </dependency>
    <!-- lombok 简化 java 代码 -->
    <dependency>
    	<groupId>org.projectlombok</groupId>
    	<artifactId>lombok</artifactId>
    	<optional>true</optional>
    </dependency>
    <!-- Mybatis- Plus 启动器 -->
    <dependency>
    	<groupId>com.baomidou</groupId>
    	<artifactId>mybatis-plus-boot-starter</artifactId>
    	<version>3.1.0</version>
    </dependency>
    <!-- MySql jdbc 驱动 -->
    <dependency>
    	<groupId>mysql</groupId>
    	<artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

四、Mybatis-Plus 的基本使用

  • 包含: 新增方法、常用注解、排除非表字段的三种方式

1、通用mapper新增方法

package com.mp;


@RunWith(SpringRunner.class)
@SpringBootTest
public class InsertTest {
	
	@Autowired
	private UserMapper userMapper;
	
	@Test
	public void insert() {
		
		User  u = new User();
                u.setId(1168737089097060324L);
		u.setName("陈庆");
		u.setAge(22);
		u.setEmail("aaa@qq.com");
		u.setManagerId(1088248166370832385L);
		u.setCreateTime(LocalDateTime.now());
		u.setRemark("我是一个备注信息");
		User.setPostil("我是批注");
		
		int rows = userMapper.insert(u);
		System.out.print("影响记录数"+ rows +"条");
		
	}
}

当userMapper调用insert方法时,其实际上并不需要我们编写SQL 语句,而是交由通用Mapper调用其封装的方法:

MyBatis-Plus —— 入门

从而实现映射关系,执行数据的插入。

控制台执行结果:

 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ 
     /               |         
                        3.1.0 
DEBUG==>  Preparing: INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? ) 
DEBUG==> Parameters: 1168737089097060324(Long), 陈庆(String), 22(Integer), aaa@qq.com(String)
DEBUG<==    Updates: 1
影响记录数1条

由以上结果,可知,当通用Mapper进行映射执行插入请求时,其底层进行了SQL语句 的编码生成

2、常用注解

(1)@TableName("表名")

MyBatis-Plus —— 入门

当表名为 mp_user 时,在不改变 实体类的名字的情况下,通过添加 @TableName(“表名mp_user”)的方式来指定对应的数据库表名,以此解决在不编写sql语句的情况下,实体类的名字与数据库表名不一致而导致无法进行表操作的问题。

@Data
@TableName("mp_user") //此注解用于标识当前实体类所对应的表,编译时生效
public class User{
	
        .....................
}

@Test测试结果:


 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ 
     /               |         
                        3.1.0 
DEBUG==>  Preparing: INSERT INTO mp_user ( id, name, age, email ) VALUES ( ?, ?, ?, ? ) 
DEBUG==> Parameters: 1168737089092060324(Long), 陈庆(String), 22(Integer), aaa@qq.com(String)
DEBUG<==    Updates: 1
影响记录数1条

(2)@TableField("表字段名")

	private Long id;
    //用户名
	@TableField("name")//当前注解用于指定属性对应的表字段
//	private String name;
	private String username;
	//年龄

@Test测试结果;

 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ 
     /               |         
                        3.1.0 
DEBUG==>  Preparing: INSERT INTO mp_user ( id, name, age, email ) VALUES ( ?, ?, ?, ? ) 
DEBUG==> Parameters: 1168732089092060324(Long), 陈庆(String), 22(Integer), aaa@qq.com(String)
DEBUG<==    Updates: 1
影响记录数1条

由结果可知:使用 @TableField("name")来直接指定  user 实体类中某一个属性所对应的数据库表中的哪一列

(3)@TableId

当前注解用于标注 javabean 中哪个字段是 主键 id

	//主键
	@TableId //主键策略
	private Long id;

3、排除非表字段的三种方式

(1)第一种: 添加 transient

说明:

  • 添加 transient 标识 某一字段不参与实例化过程,一般用于过渡字段,在数据库表中没有对应的字段,如果直接添加而进行实例化的排除, 会被自动进行映射到数据库表中,而由于没有对应的字段,会报错。
        //备注
	private transient String Remark;

@Test测试方法:

                u.setRemark("我是一个备注信息");
		User.setPostil("我是批注");
		
		int rows = userMapper.insert(u);

执行结果:

 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ 
     /               |         
                        3.1.0 
DEBUG==>  Preparing: INSERT INTO mp_user ( id, name, age, email, manager_id, create_time ) VALUES ( ?, ?, ?, ?, ?, ? ) 
DEBUG==> Parameters: 1268732089092060324(Long), 陈庆(String), 22(Integer), aaa@qq.com(String), 1168737089097060354(Long), 2019-09-03 16:22:38.945(Timestamp)
DEBUG<==    Updates: 1
影响记录数1条

(2)第二种: 使用 static 

说明:

  • 将要排除的字段声明为静态变量,手动创建 对应的静态GET/SET 方法,静态的属性的静态方法只能使用类进行调用,此时,实例化的过程会将该静态字段排除掉,在调用 MP  进行映射时不会被映射进去
        //批注
	private static String Postil;
	
	public static void setPostil(String Postil) {
		Postil = Postil;
	}
	
	public static String getPostil() {
		return Postil;
	}

@Test测试方法:

                User.setPostil("我是批注");
		
		int rows = userMapper.insert(u);

执行结果:

 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ 
     /               |         
                        3.1.0 
DEBUG==>  Preparing: INSERT INTO mp_user ( id, name, age, email, manager_id, create_time ) VALUES ( ?, ?, ?, ?, ?, ? ) 
DEBUG==> Parameters: 1263732089092060324(Long), 陈庆(String), 22(Integer), aaa@qq.com(String), 1168737089097060354(Long), 2019-09-03 16:22:38.945(Timestamp)
DEBUG<==    Updates: 1
影响记录数1条

(3)第三种: 使用 @TableField(exist=false)

说明:

  • 使用 @TableField(exist=false)标识当前变量不是数据库表中的字段,这种情况下,该属性不会被映射到数据库中
        @TableField(exist=false)
	private transient String Remark;

测试结果:

 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ 
     /               |         
                        3.1.0 
DEBUG==>  Preparing: INSERT INTO mp_user ( id, name, age, email, manager_id, create_time ) VALUES ( ?, ?, ?, ?, ?, ? ) 
DEBUG==> Parameters: 1263732089192060324(Long), 陈庆(String), 22(Integer), aaa@qq.com(String), 1168737089097060354(Long), 2019-09-03 16:22:38.945(Timestamp)
DEBUG<==    Updates: 1
影响记录数1条

五、Mybatis-Plus 查询方法

1、普通查询

@RunWith(SpringRunner.class)
@SpringBootTest
public class RetrieveTest {
	
	@Autowired
	private UserMapper userMapper;
		
        //根据单个id查询用户
//	@Test
	public void selectBy() {
		User user = userMapper.selectById(1168440364299722753L);
		System.out.println(user);
	}
	
	//根据 id  的 List<Long> 查询多个用户
//	@Test 
	public void selectIds() {
		List<Long> idsList = Arrays.asList(1168440364299722753L,1094592041087729666L,1094590409767661570L);
		List<User> userList = userMapper.selectBatchIds(idsList);
		userList.forEach(System.out::println);
	}
	
	//根据 map 的 key-value 中的属性和值 查询 用户
//	@Test
	public void selectByMap() {
		//map.put("name","王天风")
		//map.put("age",30)
		//where namem = "王天风" and age = 30
		Map<String,Object> columnMap = new HashMap<String,Object>();
		columnMap.put("name", "王天风");
		columnMap.put("age", 25);
		List<User> userList = userMapper.selectByMap(columnMap);
		userList.forEach(System.out::println);
	}

2、条件构造器查询

使用 QueryWrapper<>(); 的实例来创建  sql ,通过 拼接 like 进行模糊查询,使用  lt 进行小于 的判断

        /*
	 * 1、名字中包含与并且年龄小于40
	 *  name like `%雨%` and age <40
	 * */
//	@Test
	public void selectByWrapper() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
//		QueryWrapper<User> queryWrapper = Wrappers.<User>query();
		queryWrapper.like("name", "雨").lt("age",40);
		List<User> userList = userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	/*
	 * 2、名字中包含雨 并且年龄大于等于20 且小于等于40 并且email 不为空
	 *  name like `%雨%`` and age between 20 and 40 and email is not null
	 * */
//	@Test
	public void selectByWrapper2() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.like("name", "雨").between("age", 20, 40).isNotNull("email");
		
		List<User> userList = userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	/*
	 * 名字为王姓或者年龄大于等于25,按照年龄降序排列,年龄相同按照 id 升序排列
	 * name like `王%` or age>=40 order by age desc id asc
	 * */
//	@Test 
	public void selectByWrapper3() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.likeRight("name", "王").or().ge("age",25).orderByDesc("age")
		              .orderByDesc("id");
		
		List<User> userList = userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	
	}
	
	/*
	 * 4、创建日期为 2019年2月14日 并且质数上级为名字为王姓
	 * date_format(create_time,'%Y-%m-%d') and manager_id
	 *  in (select id from user where name like '王%' )
	 * */
//	@Test
	public void selectByWrapper4() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.apply("date_format(create_time,'%Y-%m-%d')={0}","2019-02-14 " )
//		queryWrapper.apply("date_format(create_time,'%Y-%m-%d')={2019-02-14" ) //当前行与上一行效果是一样的,但是当前行存在SQL注入的风险,如下列行
//		queryWrapper.apply("date_format(create_time,'%Y-%m-%d')=2019-02-14 or true or true" )  // 当前行存在SQL 注入的风险,在日期时间末尾添加了or true or true 后会见所有的结果都查询出来,会让用户看到不该看到的东西
		 .inSql("manager_id", "select id from mp_user where name like '王%'");
		
		List<User> userList = userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	/*
	 * 5、名字为王姓并且 (年龄小于40或邮箱不为空)
	 * name like '王%'  and (age<40 or email is not null)
	 * */
//	@Test 
	public void selectByWrapper5() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.likeRight("name", "王").and(wq->wq.lt("age",40).or().isNotNull("email"));
		
		List<User> userList = userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	/*
	 * 6、名字为王姓或者(年龄小于40 并且年龄大于20 并且 邮箱不为空)
	 * name like'王%' or (age <40 and age>20 and email is notNull)
	 * */
//	@Test
	public void selectByWrapper6() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.likeRight("name", "王").or(wq->wq.lt("age", 40).gt("age",20)
				.isNotNull("email"));
		List<User> userList = userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
		
	/*
	 * 7、(年龄小于40或邮箱不为空) 并且名字为王姓
	 * (age<40 or email is not null) and name like '王%'
	 * */
//	@Test 
	public void selectByWrapper7() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.nested(wq->wq.lt("age", 40).or().isNotNull("email")
		.likeRight("name", "王"));
		
		List<User> userList = userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	/*
	 * 8、年龄为 30、31、34、35
	 * age in (30、31、34、35)
	 * */
//	@Test
	public void selectByWrapper8() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.in("age", Arrays.asList(30,31,34,35)).last("limit 1");
		
		List<User> userList = userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	

3、Select 不列出全部字段

/*
	 * 1、名字中包含雨并且年龄小于40
	 *  name like '%雨%' and age<40
	 * */
//	@Test 
	public void selectByWrapperSupper() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.select("id","name").like("name", "雨").lt("age", 40)
			.select(User.class,info->!info.getColumn().equals("create_time")&&
					!info.getColumn().equals("manager_id"));
		
		List<User> userList = userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
//	@Test
	public void testCondition() {
		String name = "王";
		String email = "";
		condition(name,email);
	}
	

4、condition作用

private void condition(String name,String email) {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
//		if(StringUtils.isNotEmpty(name)) {
//			queryWrapper.like("name", name);
//		}
//		if(StringUtils.isNotEmpty(email)) {
//			queryWrapper.like("email", email);
//		}
		queryWrapper.like(StringUtils.isNotEmpty(name), "name",name)
		  .like(StringUtils.isNotEmpty(email), "email",email);
		
		List<User> userList = userMapper.selectList(queryWrapper);
	    userList.forEach(System.out::println);
	}

5、实体作为条件构造器构造方法的参数

	@Test
	public void selectByWrapperEntity() {
		User whereUser = new User();
		whereUser.setName("刘红雨");
		whereUser.setAge(32);
		
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>(whereUser);
//		queryWrapper.like("name", "雨").lt("age",40);
		
		List<User> userList = userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}

6、AllEq用法

        @Test
	public void selectByWrapperAllEq() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("name", "王天风");
		params.put("age", 25);
		queryWrapper.allEq(params);
		
		List<User> userList = userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}

7、其他使用条件构造器的方法

        @Test
	public void selectByWrapperMaps() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.like("name","雨").lt("age",40);
		
		List<Map<String,Object>> userList = userMapper.selectMaps(queryWrapper);
		userList.forEach(System.out::println);
				
	}

/*
	 * 11、按照直属上级分组,查询每组的平均年龄,最大年龄、最小年龄
	 * 并且只取年龄综合小于500的组
	 * 
	 * select avg(age) avg_age,min(age) min_age,max(age) max_age
	 * from user
	 * group by manager_id
	 * having sum(age)<500
	 * */
	@Test
	public void selectByWrapperMaps2() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.select("avg(age) avg_age","min(age) min_age","max(age) max_age")
		      .groupBy("manager_id").having("sum(age)<{0}",500);
		
		List<Map<String,Object>> userList = userMapper.selectMaps(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	@Test 
	public void selectByWrapperObjs() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.select("id","name").like("name", "雨").lt("age", 40);
		
		List<Object> userList = userMapper.selectObjs(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	@Test
	public void selectByWrapperCount() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.like("name", "雨").lt("age", 40);
		
		Integer count = userMapper.selectCount(queryWrapper);
		System.out.println("总记录数" + count);
		
	}
	
	@Test 
	public void selectByWrapperOne() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.like("name", "刘红雨").lt("age", 40);
		
		User user = userMapper.selectOne(queryWrapper);
		System.out.println(user);
	}

8、lambda条件构造器

	@Test
	public void selectLambda() {
		LambdaQueryWrapper<User> lambdaQuery = Wrappers.<User>lambdaQuery();
		lambdaQuery.like(User::getName, "雨").lt(User::getAge, 40);
		//where name like '%雨'
		List<User> userList = userMapper.selectList(lambdaQuery);
		userList.forEach(System.out::println);
				
	}
	
	/*
	 * 5、名字为王姓并且(年龄小于40 或邮箱不为空)
	 *  name like '王%' and (age<40 or email is not null)
	 *  
	 * */
	@Test
	public void selectLambda2() {
		LambdaQueryWrapper<User> lambdaQuery = Wrappers.<User>lambdaQuery();
		lambdaQuery.likeRight(User::getName, "王")
			.and(lqw->lqw.lt(User::getAge,40).or().isNotNull(User::getEmail));
		List<User> userList = userMapper.selectList(lambdaQuery);
		userList.forEach(System.out::println);
	}
	

六、自定义 sql

自定义SQL的两种方式:

  • 第一种: 使用自定义注解 的方式实现,在 dao 层的方法上使用@Select (“sql 语句”)的方式编写 sql 语句,会自动映射到数据库表中
  • 第二章: 使用创建 mapper.xml 的方式来创建 配置文件,通过在配置文件中 创建  sql 语句,并配置  namespace 名称空间,指向有效的 dao 层,从而实现数据的映射

1、在 application.yml 中  配置映射文件地址:

mybatis-plus:
  mapper-locations:
  - com/mp/mapper/*

2、第一种:

public interface UserMapper extends BaseMapper<User>{
	
	@Select("select * from user ${ew.customSqlSegment}")
	List<User> selectAll(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
	
}

3、第二种:

    需要创建映射文件 UserMapper.xml

MyBatis-Plus —— 入门

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.mp.dao.UserMapper">
  
  <select id="selectAll" resultType="com.mp.entity.User">
    	select * from mp_user ${ew.customSqlSegment}
  </select>
    
</mapper>
        @Test
	public void selectMy() {
		LambdaQueryWrapper<User> lambdaQuery = Wrappers.<User>lambdaQuery();
		lambdaQuery.likeRight(User::getName, "王")
		 	.and(lqw->lqw.lt(User::getAge, 40).or().isNotNull(User::getEmail));
		List<User> userList = userMapper.selectAll(lambdaQuery);
		userList.forEach(System.out::println);
	}

七、分页查询

简介: Mybatis-Plus 提供了一个物理分页的插件

1、分页插件配置类: 创建 MybatisPlusConfig类,注入到 Spring中进行管理

package com.mp.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;

@Configuration
public class MybatisPlusConfig {
	
	@Bean
	public PaginationInterceptor paginationInterceptor() {
		return new PaginationInterceptor();
	}

}

2、分页查询的两种方式:

方式一:使用userMapper.selectPage(page,data);返回结果为 实体类 javabean

	@Test
	public void selectPage() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.ge("age",22);
		
		Page<User> page = new Page<User>(1,3);
		
		IPage<User> iPage = userMapper.selectPage(page,queryWrapper);
		System.out.println("总页数"+iPage.getPages());
		System.out.println("总记录数" + iPage.getTotal());
		List<User> userList = iPage.getRecords();
		
		userList.forEach(System.out::println);
	}

方式二:使用userMapper.selectPage(page,data);返回结果为 Map<String,Object>集合类

        @Test
	public void selectPage2() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.ge("age",26);
		
		Page<User> page = new Page<User>(1,2);
		
		IPage<Map<String,Object>> iPage = userMapper.selectMapsPage(page, queryWrapper);
		System.out.println("总页数"+iPage.getPages());
		System.out.println("总记录数" + iPage.getTotal());
		List<Map<String,Object>> userList = iPage.getRecords();
		
		userList.forEach(System.out::println);
	}

方式三: 自定义分页查询方法,可实现多表联合查询返回分页数据

创建 自定义方法 :

IPage<User> selectUserPage(Page<User> page,@Param(Constants.WRAPPER) Wrapper<User> wrapper);

UserMapper.xml

  
  <select id="selectUserPage" resultType="com.mp.entity.User">
    	select * from mp_user ${ew.customSqlSegment}
  </select>

测试方法:

        @Test
	public void selectMyPage3() {
		QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
		queryWrapper.ge("age",26);
		
		Page<User> page = new Page<User>(1,2);
		
		IPage<User> iPage = userMapper.selectUserPage(page, queryWrapper);
		System.out.println("总页数"+iPage.getPages());
		System.out.println("总记录数" + iPage.getTotal());
		List<User> userList = iPage.getRecords();
		
		userList.forEach(System.out::println);
	}

八、更新与删除

1、更新方法

package com.mp;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mp.dao.UserMapper;
import com.mp.entity.User;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UpdateTest {

	
	@Autowired
	private UserMapper userMapper;
	
	@Test
	public void updateById() {
		User user = new User();
		user.setId(1168443892250533890L);
		user.setAge(26);
		user.setEmail("aaa@qq.com");
		int rows = userMapper.updateById(user);
		System.out.println("影响记录数:" + rows + "条");
	}
	
	@Test
	public void updateByWrapper() {
		UpdateWrapper<User> updateWrapper = new  UpdateWrapper<User>();
		updateWrapper.eq("name", "李艺伟").eq("age", 28);
		User user = new User();
		user.setEmail("aaa@qq.com");
		user.setAge(29);
		int rows = userMapper.update(user, updateWrapper);
		System.out.println("影响记录数:" + rows + "条");
	}
	
	@Test
	public void updateByWrapperLambda() {
		LambdaUpdateWrapper<User> lambdaUpdate = new LambdaUpdateWrapper<User>();
		lambdaUpdate.eq(User::getName, "李艺伟").eq(User::getAge,29).set(User::getAge, 31);
		
		int rows = userMapper.update(null, lambdaUpdate);
		System.out.println("影响记录数: " + rows);
	}
}

2、删除方法

package com.mp;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.mp.dao.UserMapper;
import com.mp.entity.User;

@RunWith(SpringRunner.class)
@SpringBootTest
public class DeleteTest {

	@Autowired
	private UserMapper userMapper;
	
	@Test
	public void deleteById() {
		int rows = userMapper.deleteById(1168439950892429314L);
		System.out.println("影响记录数:"+ rows +"条");
	}
	
	@Test
	public void deleteByMap() {
		Map<String,Object> columnMap = new HashMap<>();
		columnMap.put("name", "向后");
		columnMap.put("age", 25);
		int rows = userMapper.deleteByMap(columnMap);
		System.out.println("删除条数:" + rows + "条");
	}
	
	@Test
	public void deleteBatchIds() {
		int rows = userMapper.deleteBatchIds(Arrays.asList(1168440364299722753L,1168444966134968322L));
		System.out.println("删除条数:" +rows);
	}
	
	@Test
	public void deleteByWrapper() {
		LambdaQueryWrapper<User> lambdaQuery = Wrappers.<User>lambdaQuery();
		lambdaQuery.eq(User::getAge, 34).or().gt(User::getAge, 41);
		int rows = userMapper.delete(lambdaQuery);
		System.out.println("删除条数:" + rows);
	}
}

九、ActiveRecord 模式

AR模式的使用需要满足两个条件,如下:

条件1:必须存在对应的原始mapper并继承Model<User> 泛型类,并配置相应类注解,

同时申明***  serialVersionUID = 1L

@Data
@TableName("mp_user")
@EqualsAndHashCode(callSuper=false)
public class User extends Model<User>{	

	private static final long serialVersionUID = 1L;
	//主键
        private Long id;

条件2: 在 mapper 接口 中要 继承 BaseMapper<Object.class> 泛型类

package com.mp.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mp.entity.User;

public interface UserMapper extends BaseMapper<User>{
	
	
}

代码:https://github.com/wushaopei/MyBatis/tree/master/first-CRUD