SpringBoot+Mybatis-Plus+lombok整合

1.介绍篇

教程结合当前主流的springboot、Mybatis-Plus、lombok、mysql串起来重点、完整的学习Mybatis-Plus,场景比较简单,即通过对“工作招聘信息表(dy_job表)”进行CURD操作(下面详细介绍)。如有不清楚之处,可加微信或者qq问清楚。由于篇幅有限涉及的源代码会贴出80%保证各路新手朋友按照一下步骤一步一步往下做完全没问题,代码没有全部贴完有需要的朋友可以私信。本教程亮点,每一个章节都有总结和注意事项。

教程大纲(如果读到中间有点模糊,请回头看看这个大纲):
image.png

1.1. lombok插件介绍

Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,通过使用对应的注解,可以在编译源码的时候生成对应的方法。

为了代码简便,在这个培训教材中加入了这个小插件。比较好用,在实际项目中也推荐使用。要使用这个小插件,需要到官网上去下载,然后单独安装一下,安装方式很简单,下面有介绍。

1.2. Mybatis-Plus插件介绍

Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。这是官方给的定义,关于mybatis-plus的更多介绍及特性,可以参考mybatis-plus官网。那么它是怎么增强的呢?其实就是它已经封装好了一些crud方法,我们不需要再写xml了,直接调用这些方法就行,就类似于JPA。

1.3. lombok的安装

官方地址:https://projectlombok.org/

github地址:https://github.com/rzwitserloot/lombok

1)第一步:下载

下载安装很方便,打开https://projectlombok.org/,点击Download进入下载页面,并下载。
image.png

image.png
它是一个jar包文件,下载后直接点开安装即可。

2)第二步:安装

官网提供基于很多种开发工具的安装方法,我是在eclipse上安装,如下图所示:
image.png
以下是官网上提供的安装在eclipse上
image.png

安装完之后到开发工具上查看一下插件,如果有,则显示如下图上的信息
image

3.1. 注意事项 ️

1)lombok目前发现的问题:eclipse所在目录不要有中文,否则加载lombok是不成功的;

2)Mybatis-Plus不需要像lombok安装,只需要在Maven项目中引入依赖即可,非常方便;

2.创建项目

2.1. 创建过程

工程名称“mptest”,具体如下

1)第一步:创建Maven项目,如图:
image.png
2)第二步:在"create a simple project。。。"前打勾
image.png
3)第三步:输入项目名称相关信息
image.png
2.2. 项目结构
image.png

3.pom文件中引入相关的依赖

3.1. 拷贝这段贴入刚创建工程的pom.xml里

    <!-- Spring Boot的父级依赖 --> 
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> 
    </parent>
    <!-- java版本 1.8 --> 
    <properties>
        <java.version>1.8</java.version>
    </properties>

   <dependencies>
      <!-- spring boot 启动器-->
    	<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- spring boot web 启动器-->
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- spring boot test 启动器-->
        <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>
            <scope>runtime</scope>
     		 </dependency>
         <!--缓存管理器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <!-- spring集成AspectJ LTW织入器所需包-->
        <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
          <version>1.8.13</version>
		   </dependency>
  </dependencies>

3.1. 注意事项 ️

<!-- mybatis-plus插件 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.1.0</version>
</dependency>

如果在其它框架中引入依赖,只需要这个就可以了。

4.基础代码准备

4.1. 创建数据库表

这里用的是mysql数据库, 表名"dy_job"

表结构:

/*
 Navicat Premium Data Transfer

 Source Server         : localhost-MAMP
 Source Server Type    : MySQL
 Source Server Version : 50725
 Source Host           : localhost
 Source Database       : dydata

 Target Server Type    : MySQL
 Target Server Version : 50725
 File Encoding         : utf-8

 Date: 08/09/2019 00:19:41 AM
*/

SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
--  Table structure for `dy_job`
-- ----------------------------
DROP TABLE IF EXISTS `dy_job`;
CREATE TABLE `dy_job` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `position` varchar(200) DEFAULT NULL,
  `count` int(11) DEFAULT '0',
  `place` varchar(200) DEFAULT NULL,
  `deal` varchar(200) DEFAULT NULL,
  `addtime` date DEFAULT NULL,
  `useful_life` int(11) DEFAULT NULL,
  `content` longtext,
  `access` int(11) DEFAULT '0',
  `no_order` int(11) DEFAULT '0',
  `wap_ok` int(1) DEFAULT '0',
  `top_ok` int(1) DEFAULT '0',
  `email` varchar(255) DEFAULT NULL,
  `filename` varchar(255) DEFAULT NULL,
  `lang` varchar(50) DEFAULT NULL,
  `displaytype` int(11) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1021 DEFAULT CHARSET=utf8;

SET FOREIGN_KEY_CHECKS = 1;

4.2. 编写相关代码

4.2.1. 项目代码结构

image.png
以上4个是核心的。

4.2.2. 写一个Entity实体类

@Data
@EqualsAndHashCode(callSuper=false)
@TableName(value = "dy_job")
public class Job {
	//主键,指定自增策略
	@TableId(value = "id",type = IdType.AUTO)
	private Integer id;
	//职位
	private String position;
	//招聘人数
	private Integer count;
	//工作地点
	private String place;
	//待遇
	private String deal;
	//日期
	private LocalDateTime addtime;
	//备注信息
	private String content;	
	//email
	private String email;
	
	@TableField(exist=false)
	private String remark;
}

4.2.3. 写一个Mapper映射接口

package com.mptest.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mptest.entity.Job;

public interface JobMapper extends BaseMapper<Job>{

}

4.2.4. 写一个SpringBoot主程序

package com.mptest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @SpringBoot主程序
 * @author ming
 *
 */
@SpringBootApplication
@MapperScan("com.mptest.mapper")
public class MPApplication {

	public static void main(String[] args) {
		SpringApplication.run(MPApplication.class, args);
	}
}

4.2.5. 创建application.yml配置文件

server:
  port: 8018
spring:
    datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3309/dydata
        username: root
        password: ming821215
mybatis-plus:
  #信息输出设置
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  #配置mapper xml文件,自定义sql语句
  #mapper-locations: classpath*:mpProject/mp/mapper/*.xml  
#日志级别设置    
#logging:
#  level:
#    root: WARN        
#    org:
#      springframework:
#        security: DEBUG
#        web: ERROR

4.2.6. 启动工程,测试是否运行成功

运行成功后,显示如下日志
image.png

4.3. 注意事项 ️

1)实体类中,如果类名和数据库表明名称不一样,必须指定 @TableName(value = “dy_job”),否则启动报错找不到数据库表

2)实体类中,至少定义id,否则报错。如:

@TableId(value = "id",type = IdType.AUTO)
private Integer id;

3)必须定义mapper接口,否则启动主程序时,扫描不到映射接口会报错。

4)主程序要加上 @MapperScan(“com.mptest.mapper”)。

5)application.yml中要配置数据库连接,否则启动会报错

6)想让程序能跑起来,需要注意以上5点

5.准备就绪,开始真正体验Mybatis-Plus

5.1. 三种调用模式介绍

Mybatis-Plus有多种调用模式。例如:

1)ActiveRecord模式调用

普及:Active Record 是一种数据访问设计模式,它可以帮助你实现数据对象Object到关系数据库的映射。

应用Active Record 时,每一个类的实例对象唯一对应一个数据库表的一行(一对一关系),更多介绍看百度百科

[https://baike.baidu.com/item/Active Record/3106858](https://baike.baidu.com/item/Active Record/3106858)。

要使用它,需要Entity实体类继承Model即可,如:

@Data
@TableName(value = "dy_job")
public class Job extends Model<Job> {
   
}

调用例子:

/**
	 * 新增
	 */
	@Test
	public void add() {
		//创建job对象
		Job job = new Job();
		//设置job相关值
		job.setPosition("前端工程师");
		job.setDeal("9k/月");
		job.setPlace("重庆");
		job.setCount(5);
		job.setContent("技能要求:vue、jq、JavaScript、html、css等");
		job.setAddtime(LocalDateTime.now());
		//直接调用insert方法
		boolean rs = job.insert();	
		//打印结果 
		System.out.println("新增结果:"+rs);
	}

通用Model中所有的方法:
image.png

2)继承通用Mapper接口方式调用

如:public interface JobMapper extends BaseMapper<Job>{
  
}

调用例子:

  @Autowired
	private JobMapper jobMapper;

  /**
	 * 查询全部
	 */
	@Test
	public void getJobList() {
		//查询所有
		List<Job> list = jobMapper.selectList(null);
		//输出结果
		list.forEach(System.out::println);
	}

通用Mapper中所有方法:
image.png

3)继承通用IService接口方式调用

如:public interface JobService extends IService<Job> {

}

如果是定义接口继承通用IService,那么需要写实现类,如:

@Service
public class JobServiceImpl extends ServiceImpl<JobMapper, Job> implements JobService{

}

调用例子:

 @Autowired
	private JobService jobService;
  /**
	 * 查询所有
	 */
	@Test
	public void getList()
	{
		List<Job> list = jobService.list();
		//打印输出
		list.forEach(System.out::println);
	}

通用IService中所有的方法:
image.png

)经验及建议

一般正式的项目中,建议采用第三种方式,第三种比较全面,可以结合第一种,因为第一种最简单。

5.2. 插入、更新操作

如果包名、类名跟我的命名一样,可以直接贴过去。

package com.mptest.test;

import java.io.Serializable;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import javax.swing.plaf.synth.SynthSeparatorUI;

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.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.UpdateChainWrapper;
import com.mptest.entity.Job;
import com.mptest.mapper.JobMapper;

/**
 * spring boot测试类
 * @author ming
 *
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class JobInsertOrUpdateTest {
	
	@Autowired
	private JobMapper jobMapper;
	
	/**
	 * 查询全部
	 */
	@Test
	public void getJobList() {
		//查询所有
		List<Job> list = this.jobMapper.selectList(null);
		//输出结果
		list.forEach(System.out::println);
	}
	
	/**
	 * 新增单条记录
	 * @throws ParseException
	 */
	@Test
	public void add() throws ParseException {
		//创建job对象
		Job job = new Job();
		//设置job相关值
		job.setPosition("Python");
		job.setDeal("25k/月");
		job.setPlace("深圳");
		job.setCount(1);
		job.setContent("技能要求:精通Python常用算法,会大数据架构Hadoop");
		job.setAddtime(LocalDateTime.now());
		//调用插入方法
		int rs = this.jobMapper.insert(job);
		//打印结果 
		System.out.println("执行结果:"+rs);
	}
	
	/**
	 * 更新记录
	 * @throws ParseException
	 */
	@Test
	public void updateByID() throws ParseException {
		//创建job对象
		Job job = new Job();
		job.setId(9);
		//设置job相关值
		job.setPosition("PHP工程师");
		job.setDeal("12k/月");
		job.setPlace("北京");
		job.setCount(8);
		job.setContent("技能要求:熟悉使用PHP");
		//调用更新方法
		int rs = this.jobMapper.updateById(job);
		//打印结果 
		System.out.println("更新结果:"+rs);
	}
	
	/**
	 * 更新记录
	 * @throws ParseException
	 */
	@Test
	public void updateByWrapper() throws ParseException {
		LambdaUpdateWrapper<Job> updateWrapper = new  UpdateWrapper<Job>().lambda();
		updateWrapper.eq(Job::getId, 10);
		//创建job对象
		Job job = new Job();
		//job.setId(9);
		//设置job相关值
		job.setPosition("C++工程师");
		job.setDeal("18k/月");
		job.setPlace("广州");
		job.setCount(3);
		job.setContent("技能要求:精通C++");
		//调用更新方法
		
		int rs = this.jobMapper.update(job, updateWrapper);
		//打印结果 
		System.out.println("更新结果:"+rs);
	}
	
	/**
	 * 更新记录
	 * @throws ParseException
	 */
	@Test
	public void updateByWrapperAndByEntity() throws ParseException {
		Job jobWhere = new Job();
		jobWhere.setId(10);
		//System.out.println(jobWhere.toString());
		
		//updateWrapper
		LambdaUpdateWrapper<Job> updateWrapper = new  UpdateWrapper<Job>(jobWhere).lambda();
		//updateWrapper.eq(Job::getId, 10);
		//创建job对象
		Job job = new Job();
		//job.setId(9);
		//设置job相关值
		job.setPosition("C++工程师");
		job.setDeal("20k/月");
		job.setPlace("广州");
		job.setCount(3);
		job.setContent("技能要求:精通C++");
		//调用更新方法
		
		int rs = this.jobMapper.update(job, updateWrapper);
		//打印结果 
		System.out.println("更新结果:"+rs);
	}
	
	/**
	 * 更新记录
	 * @throws ParseException
	 */
	@Test
	public void updateByWrapperSg() throws ParseException {
		//updateWrapper
		LambdaUpdateWrapper<Job> updateWrapper = new  UpdateWrapper<Job>().lambda();
		//设置
		updateWrapper
		  .set(Job::getPosition, "Python算法工程师")
		  .set(Job::getCount, 2)
		  .eq(Job::getId, 13);
		//执行update更新方法
		int rs = this.jobMapper.update(null, updateWrapper);
		//打印结果 
		System.out.println("更新结果:"+rs);
	}
	
	/**
	 * 更新记录Chain
	 * @throws ParseException
	 */
	@Test
	public void updateByWrapperChain() throws ParseException {
		//updateWrapper
		LambdaUpdateChainWrapper<Job> updateWrapper = new LambdaUpdateChainWrapper<Job>(jobMapper);
		//设置
		boolean rs = updateWrapper
		  .set(Job::getPosition, "Python工程师")
		  .set(Job::getCount, 5)
		  .eq(Job::getId, 13)
		  .update();
		System.out.println("更新结果:"+rs);
	}
	
	/**
	 * 通过id删除数据
	 */
	@Test
	public void deleteById() {
		Integer id = 3 ;
		//调用删除方法deleteById
		int rs = this.jobMapper.deleteById(id);
		//打印结果
		System.out.println("更新结果:"+rs);
	}
	
	/**
	 * 通过多个id删除数据
	 */
	@Test
	public void deleteByIds() {
		//调用删除方法deleteById
		
		Collection<Integer> idList = new ArrayList<Integer>() ;
		idList.add(2);
		idList.add(4);
		//第一种传递参数
		//int rs = this.jobMapper.deleteBatchIds(idList);
		//第二种传递参数
		int rs = this.jobMapper.deleteBatchIds(Arrays.asList("2","4","12"));
		//打印结果
		System.out.println("更新结果:"+rs);
	}
	
	/**
	 * 通过Wrapper删除数据
	 */
	@Test
	public void deleteByWrapper() {
		//外部传来的逗号分割id
		String params = "2,4,6,7"; 
		List<String> paramsList = Arrays.asList(params.split(","));
		//LambdaQueryWrapper对象
		LambdaQueryWrapper<Job> wrapper = new QueryWrapper<Job>().lambda();
		//条件
		wrapper
			.like(Job::getPosition,"工程师")
			.in(Job::getId, paramsList);
		//调用删除方法
		int rs = this.jobMapper.delete(wrapper);
		//打印结果
		System.out.println("更新结果:"+rs);
	}
}

5.4. 查询语句、查询条件

 package com.mptest.test;

import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.plaf.synth.SynthSeparatorUI;

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.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.UpdateChainWrapper;
import com.mptest.entity.Job;
import com.mptest.mapper.JobMapper;
 

/**
 * spring boot测试类
 * @author ming
 *
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class JobSelectTest {
	
	@Autowired
	private JobMapper jobMapper;
	
	/**
	 * 查询全部
	 */
	@Test
	public void getJobList() {
		//查询所有
		List<Job> list = jobMapper.selectList(null);
		//输出结果
		list.forEach(System.out::println);
	}
	
	/**
	 * 以map作为条件查询
	 */
	@Test
	public void getByMap() {
		//定义map
		Map<String,Object> columnMap = new HashMap<String,Object>();
		//设置id值
		columnMap.put("id", 1);
		//调用查询方法
		List<Job> list = this.jobMapper.selectByMap(columnMap);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * 以Wrapper作为条件查询
	 */
	@Test
	public void getByWrapper() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.<Job>query();
		//开始设置查询条件
		queryWrapper
		  .like("position", "工程")
		  .lt("id", 10);

		//调用查询
		List<Job> list = this.jobMapper.selectList(queryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}

	/**
	 * 以Wrapper作为复杂条件查询
	 */
	@Test
	public void getByWrapper2() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.<Job>query();
		//开始设置查询条件
		queryWrapper
		  .like("position", "工")
		  .between("count", 1, 2)
		  .isNull("email");
			

		//调用查询
		List<Job> list = this.jobMapper.selectList(queryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	
	/**
	 * 以Wrapper作为复杂条件查询
	 */
	@Test
	public void getByWrapper3() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.query();
		//开始设置查询条件
		queryWrapper
		  .likeRight("position", "软")
		  .or().ge("count", 3)
		  .orderByDesc("addtime")
		  .orderByAsc("id");
		
		//调用查询
		List<Job> list = this.jobMapper.selectList(queryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * 带子查询
	 */
	@Test
	public void getByWrapper4() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.query();
		//开始设置查询条件
		queryWrapper
			.apply("date_format(addtime,'%Y-%m-%d')={0}", "2019-08-02")
			.inSql("id", "select id from dy_job where count>1");
		
		//调用查询
		List<Job> list = this.jobMapper.selectList(queryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * and lambda表达式查询 
	 */
	@Test
	public void getByWrapper5() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.query();
		//开始设置查询条件
		queryWrapper
			.like("position", "工程师")
			.and(
				sql->sql.le("count", 10).or().isNull("email")
				)
			.ge("id", 2);
		
		//调用查询
		List<Job> list = this.jobMapper.selectList(queryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * or lambda表达式查询 
	 */
	@Test
	public void getByWrapper6() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.query();
		//开始设置查询条件
		queryWrapper
			.like("position", "工程师")
			.or(
				sql->sql.le("count", 10).isNull("email")
				)
			.ge("id", 2);
		
		//调用查询
		List<Job> list = this.jobMapper.selectList(queryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * 	前面是带() lambda表达式查询 
	 */
	@Test
	public void getByWrapper7() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.query();
		//开始设置查询条件
		queryWrapper
			.nested(sql->sql.like("position", "java").or().ge("count", 3))
			.apply("date_format(addtime,'%Y-%m-%d')={0}", "2019-08-02")
			.last("limit 2");
			//.in("id", Arrays.asList(1,2,3,5,8));
		
		//调用查询
		List<Job> list = this.jobMapper.selectList(queryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * 	查询指定字段
	 */
	@Test
	public void getByWrapper8() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.query();
		//开始设置查询条件
		queryWrapper.select("id","position","addtime")
			.nested(sql->sql.like("position", "java").or().ge("count", 3))
			.apply("date_format(addtime,'%Y-%m-%d')={0}", "2019-08-02")
			.in("id", Arrays.asList(1,2,3,5,6,7,8,9,10))
			.last("limit 2");
			
		
		//调用查询
		List<Job> list = this.jobMapper.selectList(queryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * 判断参数是否为空
	 */
	@Test
	public void getByWrapper9() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.query();
		String positionKey = "C#";
		String countKey = null;
		//开始设置查询条件
		queryWrapper
		  .like(StringUtils.isNotEmpty(positionKey),"position", positionKey)
		  .ge(StringUtils.isNotEmpty(countKey),"count", countKey)
		  .orderByDesc("addtime")
		  .orderByAsc("id")
		  .select("id","position","addtime");
		
		//调用查询
		List<Job> list = this.jobMapper.selectList(queryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * 实体Entity作为参数查询
	 */
	@Test
	public void getByWrapperEntity() {

		Job whereJob = new Job();
		whereJob.setId(11);
		whereJob.setPosition("C#架构师");
		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.query(whereJob);
		//queryWrapper.eq("", "C#");
		
		//调用查询
		List<Job> list = this.jobMapper.selectList(queryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * map押入条件
	 * 
	 */
	@Test
	public void getByWrapperAllEq() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.query();
		//创建map对象,并装入条件列
		Map<String,Object> whereMap = new HashMap<String,Object>();
		whereMap.put("position", "C#架构师");
		queryWrapper.allEq(whereMap);
		
		//调用查询
		List<Job> list = this.jobMapper.selectList(queryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * 返回map类型
	 * 
	 */
	@Test
	public void getByWrapperMaps() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.query();
		queryWrapper
			.select("addtime as 招聘时间","count(*) as 职位数量")
			.gt("id", 1)
			.like("position", "师")
			.groupBy("招聘时间")
			.having("职位数量>{0} and 职位数量<{1}", 1,10);
		
		//调用查询
		List<Map<String,Object>> list = this.jobMapper.selectMaps(queryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * 返回Object对象类型
	 * 
	 */
	@Test
	public void getByWrapperObjs() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.query();
		queryWrapper
			.select("count(*) as 职位数量")
			.gt("id", 1)
			.like("position", "师")
			.groupBy("addtime")
			.having("职位数量>{0} and 职位数量<{1}", 1,10);
		
		//调用查询
		List<Object> list = this.jobMapper.selectObjs(queryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * 返回查询记录数量
	 * 
	 */
	@Test
	public void getByWrapperCount() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.query();
		queryWrapper
			.gt("id", 1)
			.like("position", "师");
			
		//调用查询
		int count = this.jobMapper.selectCount(queryWrapper);
		//打印输出
		System.out.println(count);
	}
	
	/**
	 * 返回一条记录
	 * 
	 */
	@Test
	public void getByWrapperOne() {

		//查询条件
		QueryWrapper<Job> queryWrapper = Wrappers.query();
		queryWrapper
			.eq("id", 5)
			.like("position", "师");
			
		//调用查询
		Job rs = this.jobMapper.selectOne(queryWrapper);
		//打印输出
		System.out.println(rs);
	}
	
	/**
	 * LambdaQueryWrapper
	 * lambda语法查询
	 */
	@Test
	public void getByLambda() {

		LambdaQueryWrapper<Job> lambdaQueryWrapper =  new QueryWrapper<Job>().lambda();
		lambdaQueryWrapper
			.like(Job::getPosition, "工程师")
			.gt(Job::getCount, 3)
			.and(sql->sql.gt(Job::getId, 2).or().isNull(Job::getEmail));
			
		//调用查询
		List<Job> list = this.jobMapper.selectList(lambdaQueryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * LambdaQueryWrapper
	 * lambda语法查询
	 */
	@Test
	public void getByLambdaQueryChain() {

		//外部参数
		String positionKey = "工程师";
		String countKey = "3";
		//查询条件及查询结果集
		List<Job> list = new  LambdaQueryChainWrapper<Job>(jobMapper)
			.like(StringUtils.isNotEmpty(positionKey),Job::getPosition, positionKey)
			.gt(StringUtils.isNotEmpty(countKey),Job::getCount, countKey)
			.and(sql->sql.gt(Job::getId, 2).or().isNull(Job::getEmail))
			.select(Job::getId,Job::getPosition,Job::getCount,Job::getAddtime)
		    .list();  
		//打印输出
		list.forEach(System.out::println);
	}
	
	
	/**
	 * 查询自己定义的方法
	 */
	@Test
	public void getByMyFunction() {

		LambdaQueryWrapper<Job> lambdaQueryWrapper =  new QueryWrapper<Job>().lambda();
		lambdaQueryWrapper
			.like(Job::getPosition, "工程师")
			.gt(Job::getCount, 3)
			.and(sql->sql.gt(Job::getId, 2).or().isNull(Job::getEmail));
			
		//调用查询
		List<Job> list = this.jobMapper.getMyJobsList(lambdaQueryWrapper);
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * 分页查询,调用通用分页方法
	 */
	@Test
	public void getPage() {

		LambdaQueryWrapper<Job> lambdaQueryWrapper =  new QueryWrapper<Job>().lambda();
		lambdaQueryWrapper
			.like(Job::getPosition, "师")
			.gt(Job::getCount, 3)
			.and(sql->sql.gt(Job::getId, 2).or().isNull(Job::getEmail));
		//每页显示10条
		//当前页
		long current =1;
		long size = 10;
		Page<Job> page = new Page<Job>(current,size);	
		//返回IPage对象
		IPage<Job> iPage = this.jobMapper.selectPage(page, lambdaQueryWrapper);
		//获取关键信息
		System.out.println("总页数:"+iPage.getPages());
		System.out.println("总记录:"+iPage.getTotal());
		//当前页数据列表
		List<Job> list = iPage.getRecords();
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * 分页查询,调用自己定义的方法
	 */
	@Test
	public void getMyPage() {

		LambdaQueryWrapper<Job> lambdaQueryWrapper =  new QueryWrapper<Job>().lambda();
		lambdaQueryWrapper
			.like(Job::getPosition, "师")
			.gt(Job::getCount, 3)
			.and(sql->sql.gt(Job::getId, 2).or().isNull(Job::getEmail));
		//每页显示10条
		//当前页
		long current =1;
		long size = 5;
		Page<Job> page = new Page<Job>(current,size);	
		//返回IPage对象
		IPage<Job> iPage = this.jobMapper.getMyJobsPage(page, lambdaQueryWrapper);
		//获取关键信息
		System.out.println("总页数:"+iPage.getPages());
		System.out.println("总记录:"+iPage.getTotal());
		//当前页数据列表
		List<Job> list = iPage.getRecords();
		//打印输出
		list.forEach(System.out::println);
	}
	
	/**
	 * 分页查询,多表关联
	 */
	@Test
	public void getMyMorePage() {

		//外部参数
		String positionKey = "工程师";
		
		LambdaQueryWrapper<Job> lambdaQueryWrapper =  new QueryWrapper<Job>().lambda();
		//参数
		lambdaQueryWrapper.like(StringUtils.isNotEmpty(positionKey),Job::getPosition, positionKey);
		//....
		
		//每页显示10条
		//当前页
		long current =1;
		long size = 5;
		Page<Map<String,Object>> page = new Page<Map<String,Object>>(current,size);	
		//返回IPage对象
		IPage<Map<String,Object>> iPage = this.jobMapper.getMyJobsMorePage(page, lambdaQueryWrapper);
		//获取关键信息
		System.out.println("总页数:"+iPage.getPages());
		System.out.println("总记录:"+iPage.getTotal());
		//当前页数据列表
		List<Map<String,Object>> list = iPage.getRecords();
		//打印输出
		list.forEach(System.out::println);
	}
}

5.5. 注意事项 ️

有3种查询构造器:

1) QueryWrapper

2)LambdaQueryWrapper

3)LambdaQueryChainWrapper

更新构造器,也有3种:

1)UpdateWrapper

2) LambdaUpdateWrapper

3)LambdaUpdateChainWrapper

不管是查询构造器还是更新构造器,我建议使用Lambda的方式,如果从上往下做过示例的朋友会看到,Lambda的方式编译只要不出错,运行时出错率是很低的。

如果想用浏览器请求SpringBoot的API接口,可以在com.mptest.controller里写,如:

package com.mptest.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * test 
 * @author ming
 *
 */
@RestController
public class MPController {
	
	@RequestMapping("/say")
	public String say() {
		return "你好,我是张三";
	}
  //你可以在这里写调用Mybatis-Plus的CURD方法以及更多,跟test的做法一样。
  //正式的项目中,建议是将逻辑处理再提取一层,这里更多的是接收参数,处理、调用相关的
  //接口方法、以及返回数据。。。。
}

更多的Mybatis-Plus使用其实还有很多,例如:枚举、多表关联复杂查询、自定义查询、高性能的批量操作及优化、防止注入攻击、逻辑删除、代码生成器等。这里对入门很有帮助,需更多的了解,可加微信留言,我有空的时候可以一起研究。

原文地址:https://www.cnblogs.com/cnbzys/p/12157452.html