一. MyBatis-Plus簡介
簡介:
MyBatis-Plus(簡稱 MP)是一個 MyBatis 的增強工具,在 MyBatis 的基礎上只做增強不做改變,爲簡化開發、提高效率而生。
另最新的3.x版本支持lambda()語法糖, 方便以代碼方式組織SQL語句.
核心特性
賣點 | 說明 |
---|---|
無侵入 |
只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑 |
損耗小 |
啓動即會自動注入基本 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 操作智能分析阻斷,也可自定義攔截規則,預防誤操作 |
支持數據庫
mysql 、 mariadb 、 oracle 、 db2 、 h2 、 hsql 、 sqlite 、 postgresql 、 sqlserver
達夢數據庫 、 虛谷數據庫 、 人大金倉數據庫
MP框架結構
代碼託管
學習教程
官方教程:
非官方視頻教程:
二. springboot2集成mybatis-plus
2.1 項目構建
傳送門: -IDEA創建SpringBoot項目
2.2 項目環境
軟件 | 版本 |
---|---|
JDK | 1.8 |
SpringBoot | 2.2.6.RELEASE |
MyBatis-Plus | 3.1.0 |
2.3 項目結構
2.4 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>mybatisplus</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot_mybatisplus</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!--<version>5.1.47</version>-->
<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>
<!-- mybatisPlus 核心庫 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<!-- 引入阿里數據庫連接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--swagger start-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!--swagger end-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.5 springboot2 配置文件
# 配置端口
server:
port: 8080
spring:
# 配置數據源
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://{IP}:{PORT}/user?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull
username: xxxx
password: xxxx
type: com.alibaba.druid.pool.DruidDataSource
# mybatis 相關 configurations
mybatis-plus:
# xml掃描,多個目錄用逗號或者分號分隔(告訴 Mapper 所對應的 XML 文件位置)
mapper-locations: classpath:mapper/*.xml
# 以下配置均有默認值,可以不設置
global-config:
db-config:
# 主鍵類型,大小寫不敏感 AUTO:"數據庫ID自增", INPUT:"用戶輸入ID", ID_WORKER:"全局唯一ID (數字類型唯一ID)", UUID:"全局唯一ID UUID"
id-type: auto
# 字段策略 IGNORED:"忽略判斷" NOT_NULL:"非 NULL 判斷") NOT_EMPTY:"非空判斷"
field-strategy: not_empty
#數據庫類型, 大小寫不敏感
db-type: mysql
configuration:
# 是否開啓自動駝峯命名規則映射:從數據庫列名到Java屬性駝峯命名的類似映射
map-underscore-to-camel-case: true
# 如果查詢結果中包含空值的列,則 MyBatis 在映射的時候,不會映射這個字段
call-setters-on-nulls: true
# 這個配置會將執行的sql打印出來,在開發或測試的時候可以用
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
2.6 構建測試data
-- 建表
CREATE TABLE `user_info` (
`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` varchar(32) DEFAULT NULL COMMENT '姓名',
`age` int(11) DEFAULT NULL COMMENT '年齡',
`skill` varchar(32) DEFAULT NULL COMMENT '技能',
`evaluate` varchar(64) DEFAULT NULL COMMENT '評價',
`fraction` bigint(11) DEFAULT NULL COMMENT '分數',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COMMENT='學生信息表';
-- 插入數據
INSERT INTO `user_info` VALUES (1, '小明', 20, '畫畫', '該學生在畫畫方面有一定天賦', 89);
INSERT INTO `user_info` VALUES (2, '小蘭', 19, '遊戲', '近期該學生由於遊戲的原因導致分數降低了', 64);
INSERT INTO `user_info` VALUES (3, '張張', 18, '英語', '近期該學生參加英語比賽獲得二等獎', 90);
INSERT INTO `user_info` VALUES (4, '大黃', 20, '體育', '該學生近期由於參加籃球比賽,導致腳傷', 76);
INSERT INTO `user_info` VALUES (5, '大白', 17, '繪畫', '該學生參加美術大賽獲得三等獎', 77);
INSERT INTO `user_info` VALUES (7, '小龍', 18, 'JAVA', '該學生是一個在改BUG的碼農', 59);
INSERT INTO `user_info` VALUES (9, 'Sans', 18, '睡覺', 'Sans是一個愛睡覺,並且身材較矮骨骼巨大的骷髏小胖子', 60);
INSERT INTO `user_info` VALUES (10, 'papyrus', 18, 'JAVA', 'Papyrus是一個講話大聲、個性張揚的骷髏,給人自信、有魅力的骷髏小瘦子', 58);
INSERT INTO `user_info` VALUES (11, '刪除數據1', 3, '畫肖像', NULL, 61);
INSERT INTO `user_info` VALUES (12, '刪除數據2', 3, NULL, NULL, 61);
INSERT INTO `user_info` VALUES (13, '刪除數據3', 3, NULL, NULL, 61);
INSERT INTO `user_info` VALUES (14, '刪除數據4', 5, '刪除', NULL, 10);
INSERT INTO `user_info` VALUES (15, '刪除數據5', 6, '刪除', NULL, 10);
2.7 編寫類
①. SpringBoot2 啓動類
Usage:
加載Spring容器上下文, 解析配置文件, 解析註解, 反射進行Object生成, DI依賴注入等.
注意:
spring boot 可以管理同級目錄下的註解, 也可以管理下級目錄的註解, 如果位置不對,可以用@ComponentScan(basePackages = {"","",""})去定義包的位置,但是如果使用該方法,spring boot 就不能再去訪問同級目錄,或者未定義包位置的下級目錄.
具體到開發中, 需要注意:
- 啓動類不能放置在main/java下.
- 啓動類不能放置在下級目錄中. 如dao/service等package中.
package com.example;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(basePackages = {"com.example.dao"})
@EnableSwagger2
public class MybatisPlusDemoApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPlusDemoApplication.class, args);
}
}
②. MyBatis-Plus 配置類
Usage:
MyBatis-Plus 配置增強選項, 實現以下功能:
- 1.debug等開發環境下,提供SQL執行效率的輸出信息, 幫助檢查優化sql, 揪出slow query問題.
- 2.簡易的代碼, 提供強大的分頁Page查詢功能.
package com.example.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* User: Administrator
* Date: 2020/4/7
* Time: 16:00
* Desc:
*/
@Configuration
public class MybatisPlusConfig {
/**
* mybatis-plus SQL執行效率插件【生產環境可以關閉】
*/
@Bean
public PerformanceInterceptor performanceInterceptor() {
return new PerformanceInterceptor();
}
/**
* 分頁插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
③. Entity實例類
Usage:
實體Pojo類構建, 對象封裝, 數據承載
package com.example.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
/**
* User: Administrator
* Date: 2020/4/7
* Time: 16:03
* Desc:
*/
@Data //lombok提供簡單的實體Pojo類構建
@TableName("user_info") // @TableName中的值, 對應着數據庫中的表名
public class UserInfoEntity {
/**
* 主鍵
* @TableId中可以決定主鍵的類型,不寫會採取默認值,默認值可以在yml中配置
* AUTO: 數據庫ID自增
* INPUT: 用戶輸入ID
* ID_WORKER: 全局唯一ID,Long類型的主鍵
* ID_WORKER_STR: 字符串全局唯一ID
* UUID: 全局唯一ID,UUID類型的主鍵
* NONE: 該類型爲未設置主鍵類型
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 姓名
*/
private String name;
/**
* 年齡
*/
private Integer age;
/**
* 技能
*/
private String skill;
/**
* 評價
*/
private String evaluate;
/**
* 分數
*/
private Long fraction;
}
④. Dao層接口
Usage:
該接口繼承了BaseMapper<EntityObject>
, 集成了基礎的CURD
功能.
說明
:
- 1.如上所述, 無須做複雜配置或寫DbUtils工具, 即可進行基礎的CURD操作(如果僅實現CURD功能, 此接口甚至無法定義任何方法, 即可開箱即用;
本接口中定義的方法爲所謂的"複雜業務"服務, 無須添加此方法,簡單CURD操作即可完成操作
); - 2.複雜的sql邏輯, 提供傳統的xxxMapper.xml映射文件支持;
- 3.注意:接口方法第二個參數fraction前, 需加上註解
@Param("fraction")
, 將入參與xxxMapper.xml中的如下紅色部分的parameterType入參類型相匹配, 否則將會報錯:"nested exception is org.apache.ibatis.binding.BindingException: Parameter 'fraction' not found. Available parameters are [arg1, arg0, param1, param2]"
.
<select id=“selectUserInfoByGtFraction” resultType=“com.example.entity.UserInfoEntity”
parameterType="long"
>
注意:
很多開發者dao
層習慣於命名爲mapper
層, 道理是一樣的, 相應的, 接口名UserInfoDao
需要 同步調整爲 UserInfoMapper
.
package com.example.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.entity.UserInfoEntity;
/**
* User: Administrator
* Date: 2020/4/7
* Time: 16:06
* Desc: 用戶信息DAO
*/
public interface UserInfoDao extends BaseMapper<UserInfoEntity> {
/**
* 查詢大於該分數的學生
* @Param page 分頁參數
* @Param fraction 分數
* @Return IPage<UserInfoEntity> 分頁數據
*/
IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page, @Param("fraction") Long fraction);
}
⑤. service接口
Usage:
用戶業務接口
類的接口定義, 用於定義非基礎CURD的"複雜業務邏輯"
方法定義.
5.1 service: 接口定義
類定義模板:
interfaceBIZService
extendsIService<BIZEntity>
其中:
IService<BIZEntity>
爲 框架中類.
package com.example.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.entity.UserInfoEntity;
/**
* User: Administrator
* Date: 2020/4/7
* Time: 16:06
* Desc: 用戶業務接口
*/
public interface UserInfoService extends IService<UserInfoEntity> {
/**
* 查詢大於該分數的學生
* @Param page 分頁參數
* @Param fraction 分數
* @Return IPage<UserInfoEntity> 分頁數據
*/
IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page, Long fraction);
}
5.2 serviceImpl: 接口實現類
類定義模板:
BIZSerivceImpl
extendsServiceImpl<BIZDao, BIZEntity>
implementsBIZService
其中:
ServiceImpl<BIZDao, BIZEntity>
爲 框架中類.
package com.example.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dao.UserInfoDao;
import com.example.service.UserInfoService;
import com.example.entity.UserInfoEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* User: Administrator
* Date: 2020/4/7
* Time: 16:20
* Desc: 用戶業務實現
*/
@Service
@Transactional
public class UserInfoSerivceImpl extends ServiceImpl<UserInfoDao, UserInfoEntity> implements UserInfoService{
/**
* 查詢大於該分數的學生
* @Param page 分頁參數
* @Param fraction 分數
* @Return IPage<UserInfoEntity> 分頁數據
*/
@Override
public IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page, Long fraction) {
return this.baseMapper.selectUserInfoByGtFraction(page, fraction);
}
}
⑥. controller 類
Usage:
控制層的作用:接收客戶端的請求,然後調用Service層業務邏輯,獲取到數據,傳遞數據給視圖層(客戶端)用於視覺呈現.
6.1 MyBatis-Plus 基礎CURD功能Demo
Usage:
這裏我們看到,service中我們沒有寫任何方法,MyBatis-Plus官方封裝了許多基本CRUD的方法,可以直接使用大量節約時間,MyBatis-Plus共通方法詳見IService,ServiceImpl,BaseMapper源碼,寫入操作在ServiceImpl中已有事務綁定,這裏我們舉一些常用的方法演示.
package com.example.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.service.UserInfoService;
import com.example.entity.UserInfoEntity;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* User: Administrator
* Date: 2020/4/7
* Time: 16:23
* Desc: MP基礎CURD功能DEMO
*/
@RestController
@RequestMapping("/userInfo")
public class UserInfoController {
@Autowired
private UserInfoService userInfoService;
/**
* 根據ID獲取用戶信息
* TODO
* /
@ApiOperation("根據用戶ID獲取用戶信息")
@PostMapping("/getInfo")
public UserInfoEntity getInfo(@RequestBody String userId){
UserInfoEntity userInfoEntity = userInfoService.getById(userId);
return userInfoEntity;
}
/**
* 根據ID獲取用戶信息
* /
@ApiOperation("查詢全部信息")
@PostMapping("/getList")
public List<UserInfoEntity> getList(){
List<UserInfoEntity> list = userInfoService.list();
return list;
}
/**
* 分頁查詢全部數據
* @Return IPage<UserInfoEntity> 分頁數據
*/
@ApiOperation("分頁查詢全部數據")
@PostMapping("/getInfoListPage")
public IPage<UserInfoEntity> getInfoListPage(){
//需要在Config配置類中配置分頁插件
IPage<UserInfoEntity> page = new Page<>();
page.setCurrent(1); //當前頁
page.setSize(5); //每頁條數
page = userInfoService.page(page);
return page;
}
/**
* 根據指定字段查詢用戶信息集合
* @Return Collection<UserInfoEntity> 用戶實體集合
*/
@ApiOperation("根據指定字段查詢用戶信息集合")
@PostMapping("/getListMap")
public Collection<UserInfoEntity> getListMap(){
Map<String,Object> map = new HashMap<>();
//kay是字段名 value是字段值
map.put("age",20);
Collection<UserInfoEntity> userInfoEntityList = userInfoService.listByMap(map);
return userInfoEntityList;
}
/**
* 新增用戶信息
*/
@ApiOperation("新增用戶信息")
@PostMapping("/saveInfo")
public void saveInfo(){
UserInfoEntity userInfoEntity = new UserInfoEntity();
userInfoEntity.setName("小龍");
userInfoEntity.setSkill("JAVA");
userInfoEntity.setAge(18);
userInfoEntity.setFraction(59L);
userInfoEntity.setEvaluate("該學生是一個在改BUG的碼農");
userInfoService.save(userInfoEntity);
}
/**
* 批量新增用戶信息
*/
@ApiOperation("批量新增用戶信息")
@PostMapping("/saveInfoList")
public void saveInfoList(){
//創建對象
UserInfoEntity sans = new UserInfoEntity();
sans.setName("Sans");
sans.setSkill("睡覺");
sans.setAge(18);
sans.setFraction(60L);
sans.setEvaluate("Sans是一個愛睡覺,並且身材較矮骨骼巨大的骷髏小胖子");
UserInfoEntity papyrus = new UserInfoEntity();
papyrus.setName("papyrus");
papyrus.setSkill("JAVA");
papyrus.setAge(18);
papyrus.setFraction(58L);
papyrus.setEvaluate("Papyrus是一個講話大聲、個性張揚的骷髏,給人自信、有魅力的骷髏小瘦子");
//批量保存
List<UserInfoEntity> list =new ArrayList<>();
list.add(sans);
list.add(papyrus);
userInfoService.saveBatch(list);
}
/**
* 更新用戶信息
*/
@ApiOperation("更新用戶信息")
@PostMapping("/updateInfo")
public void updateInfo(){
//根據實體中的ID去更新,其他字段如果值爲null則不會更新該字段,參考yml配置文件
UserInfoEntity userInfoEntity = new UserInfoEntity();
userInfoEntity.setId(1L);
userInfoEntity.setAge(19);
userInfoService.updateById(userInfoEntity);
}
/**
* 新增或者更新用戶信息
*/
@ApiOperation("新增或者更新用戶信息")
@PostMapping("/saveOrUpdateInfo")
public void saveOrUpdate(){
//傳入的實體類userInfoEntity中ID爲null就會新增(ID自增)
//實體類ID值存在,如果數據庫存在ID就會更新,如果不存在就會新增
UserInfoEntity userInfoEntity = new UserInfoEntity();
userInfoEntity.setId(1L);
userInfoEntity.setAge(20);
userInfoService.saveOrUpdate(userInfoEntity);
}
/**
* 根據ID刪除用戶信息
*/
@ApiOperation("根據ID刪除用戶信息")
@PostMapping("/deleteInfo")
public void deleteInfo(String userId){
userInfoService.removeById(userId);
}
/**
* 根據ID批量刪除用戶信息
*/
@ApiOperation("根據ID批量刪除用戶信息")
@PostMapping("/deleteInfoList")
public void deleteInfoList(){
List<String> userIdlist = new ArrayList<>();
userIdlist.add("12");
userIdlist.add("13");
userInfoService.removeByIds(userIdlist);
}
/**
* 根據指定字段刪除用戶信息
*/
@ApiOperation("根據指定字段刪除用戶信息")
@PostMapping("/deleteInfoMap")
public void deleteInfoMap(){
//kay是字段名 value是字段值
Map<String,Object> map = new HashMap<>();
map.put("skill","刪除");
map.put("fraction",10L);
userInfoService.removeByMap(map);
}
}
6.2 MyBatis-Plus 中 QueryWrapper條件構造器功能Demo
Usage:
當查詢條件複雜的時候,我們可以使用MP的條件構造器,請參考下面的QueryWrapper條件參數說明.
package com.example.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.entity.UserInfoEntity;
import com.example.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* User: Administrator
* Date: 2020/4/7
* Time: 19:14
* Desc: MP 提供的QueryWrapper條件選擇器功能DEMO
*/
@RestController
@RequestMapping("/userInfoPlus")
public class UserInfoPlusController {
@Autowired
private UserInfoService userInfoService;
@RequestMapping("/getInfoListPlus")
public Map<String, Object> getInfoListPage() {
//初始化返回類
Map<String, Object> result = new HashMap<>(100);
//查詢年齡等於18的學生
//等價sql: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE age=18;
QueryWrapper<UserInfoEntity> queryWrapper1 = new QueryWrapper<>();
queryWrapper1.lambda().eq(UserInfoEntity::getAge, 18);
List<UserInfoEntity> userInfoEntityList1 = userInfoService.list(queryWrapper1);
result.put("studentAge18", userInfoEntityList1);
//查詢年齡大於5歲的學生且小於等於18歲的學生
//等價SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE age > 5 AND age <= 18
QueryWrapper<UserInfoEntity> queryWrapper2 = new QueryWrapper<>();
queryWrapper2.lambda().ge(UserInfoEntity::getAge, 5);
queryWrapper2.lambda().le(UserInfoEntity::getAge, 18);
List<UserInfoEntity> userInfoEntityList2 = userInfoService.list(queryWrapper2);
result.put("studentAge5", userInfoEntityList2);
//模糊查詢技能字段帶有"畫"的數據,並按照年齡降序
//等價SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE skill LIKE '%畫%' ORDER BY age DESC
QueryWrapper<UserInfoEntity> queryWrapper3 = new QueryWrapper<>();
queryWrapper3.lambda().like(UserInfoEntity::getSkill, "畫");
queryWrapper3.lambda().orderByDesc(UserInfoEntity::getAge);
List<UserInfoEntity> userInfoEntityList3 = userInfoService.list(queryWrapper3);
result.put("studentAgeSkill", userInfoEntityList3);
//模糊查詢名字帶有"小"或者年齡大於18的學生
//等價SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE name LIKE '%小%' OR age > 18
QueryWrapper<UserInfoEntity> queryWrapper4 = new QueryWrapper<>();
queryWrapper4.lambda().like(UserInfoEntity::getName, "小");
queryWrapper4.lambda().or().gt(UserInfoEntity::getAge, 18);
List<UserInfoEntity> userInfoEntityList4 = userInfoService.list(queryWrapper4);
result.put("studentOr", userInfoEntityList4);
//查詢評價不爲null的學生,並且分頁
//等價SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE evaluate IS NOT NULL LIMIT 0,5
IPage<UserInfoEntity> page = new Page<>();
page.setCurrent(1);
page.setSize(5);
QueryWrapper<UserInfoEntity> queryWrapper5 = new QueryWrapper<>();
queryWrapper5.lambda().isNotNull(UserInfoEntity::getEvaluate);
page = userInfoService.page(page, queryWrapper5);
result.put("studentPage", page);
return result;
}
public IPage<UserInfoEntity> getInfoListSQL() {
//查詢大於60分以上的學生,並且分頁。
IPage<UserInfoEntity> page = new Page<>();
page.setCurrent(1);
page.setPages(5);
page = userInfoService.selectUserInfoByGtFraction(page, 60L);
return page;
}
}
6.3 MyBatis-Plus 中 自定義SQL Demo
Usage:
項目中引入Mybatis-Plus組件, 將不會對項目現有的 Mybatis 構架產生任何影響,而且Mybatis-Plus支持所有 Mybatis 原生的特性.
由於某些業務邏輯複雜, 我們可能要自己去寫一些比較複雜的SQL語句.
我們舉一個簡單的例子來演示自定義SQL.
示例:查詢大於設置分數的學生(分數爲動態輸入,且有分頁)
6.3.1 構建 xxxMapper.xml 文件
<?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.example.dao.UserInfoDao">
<!-- 通用查詢映射結果 -->
<!--<resultMap id="BaseResultMap" type="com.example.entity.UserInfoEntity">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="skill" property="skill"/>
<result column="evaluate" property="evaluate"/>
<result column="fraction" property="fraction"/>
</resultMap>-->
<select id="selectUserInfoByGtFraction" resultType="com.example.entity.UserInfoEntity"
parameterType="long">
SELECT
*
FROM user_info
WHERE fraction > #{fraction}
</select>
</mapper>
6.3.2 dao 層中加入方法
詳見:
/**
* 查詢大於該分數的學生
* @Param page 分頁參數
* @Param fraction 分數
* @Return IPage<UserInfoEntity> 分頁數據
*/
IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page, @Param("fraction") Long fraction);
6.3.3 service 層中加入方法
詳見:
/**
* 查詢大於該分數的學生
* @Param page 分頁參數
* @Param fraction 分數
* @Return IPage<UserInfoEntity> 分頁數據
*/
IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page, Long fraction);
6.3.4 serviceImpl 層中加入方法
詳見:
/**
* 查詢大於該分數的學生
* @Param page 分頁參數
* @Param fraction 分數
* @Return IPage<UserInfoEntity> 分頁數據
*/
@Override
public IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page, Long fraction) {
return this.baseMapper.selectUserInfoByGtFraction(page, fraction);
}
6.3.5 Controller中進行測試
詳見:
package com.example.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.entity.UserInfoEntity;
import com.example.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* User: Administrator
* Date: 2020/4/7
* Time: 19:14
* Desc:
*/
@RestController
@RequestMapping("/userInfoPlus")
public class UserInfoPlusController {
@Autowired
private UserInfoService userInfoService;
/**
* MyBatis-Plus自定義SQL
* @Return IPage<UserInfoEntity> 分頁數據
*/
@RequestMapping("/getInfoListSQL")
public IPage<UserInfoEntity> getInfoListSQL() {
//查詢大於60分以上的學生,並且分頁。
IPage<UserInfoEntity> page = new Page<>();
page.setCurrent(1);
page.setPages(5);
page = userInfoService.selectUserInfoByGtFraction(page, 60L);
return page;
}
}
三. Postman測試
Postman調用接口效果如下:
四. Swagger2 在線文檔
地址 : http://localhost:8080/swagger-ui.html
五 代碼生成器(AutoGenerator
)
5.1 說明
AutoGenerator 是 MyBatis-Plus 的代碼生成器,通過 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各個模塊的代碼,極大的提升了開發效率。
特別說明:
自定義模板有哪些可用參數?Github Gitee AbstractTemplateEngine 類中方法 getObjectMap 返回 objectMap 的所有值都可用。
5.2 pom.xml 改造
1. 爲避免generator包衝突, 需把mybatis-plus-boot-starter 包中關聯的generator包給移除掉, 再重新在mybatis-plus-boot-starter 平級包中重新導入;
2. 代碼生成器, 底層使用了 Freemarker 或 Velocity 等模板自動化生成引擎, 故需將其包添加進來;
<!-- mybatisPlus 核心庫 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.1.0</version>
</dependency>
<!-- mybatisPlus 關聯的模板引擎&文本生成輸出框架(如生成XML,JSP,JAVA等) freemarker-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<!-- mybatisPlus 關聯的模板引擎&文本生成輸出框架(如生成XML,JSP,JAVA等) velocity-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
5.3 代碼生成器
演示例子
執行 main 方法控制檯輸入模塊表名回車自動生成對應項目目錄中
package com.example.util.generator;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* User: Administrator
* Date: 2020/4/9
* Time: 18:39
* Desc: 演示例子,執行 main 方法控制檯輸入模塊表名回車自動生成對應項目目錄中
*/
public class CodeGenerator {
private static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("請輸入" + tip + ": ");
System.out.println(help.toString());
while (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotEmpty(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("請輸入正確的" + tip + "!");
}
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("jobob");
gc.setOpen(false);
gc.setSwagger2(true); //實體屬性 Swagger2 註解
mpg.setGlobalConfig(gc);
// 數據源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://{DBMS_IP}:{DBMS_PORT}/user?useUnicode=true&useSSL=false&characterEncoding=utf8");
// dsc.setSchemaName("user");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("XXXX");
dsc.setPassword("XXXX");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName(scanner("模塊名"));
pc.setParent("com.baomidou.generatorPKG");
mpg.setPackageInfo(pc);
//自定義配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板是freemarker
String templatePath = "/templates/mapper.xml.ftl";
// 如果模板是velocity
// String templatePath = "/templates/mapper.xml.vm";
// 自定義輸出配置
List<FileOutConfig> focList = new ArrayList<>();
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML);
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>D:\IdeaProjects-6\springboot_mybatisplus/src/main/resources/mapper/user/InfoMapper.xml
return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
/*
cfg.setFileCreate(new IFileCreate() {
@Override
public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
// 判斷自定義文件夾是否需要創建
checkDir("調用默認方法創建的目錄");
return false;
}
});
*/
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
//配置模板
TemplateConfig templateConfig = new TemplateConfig();
// 配置自定義輸出模板
//指定自定義模板路徑,注意不要帶上.ftl/.vm, 會根據使用的模板引擎自動識別
// templateConfig.setEntity("templates/entity2.java");
// templateConfig.setService();
// templateConfig.setController();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
//策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// strategy.setSuperEntityClass("你自己的父類實體, 沒有就不用設置");
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
// 公共父類
// strategy.setSuperControllerClass("你自己的父類控制器, 沒有就不用設置");
// 寫於父類的公共字段
strategy.setSuperEntityColumns("id");
strategy.setInclude(scanner("表名, 多個英文逗號分割").split(","));
strategy.setControllerMappingHyphenStyle(true);
strategy.setTablePrefix(pc.getModuleName() + "_");
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}
演示效果圖:
參考列表:
-SpringBoot 整合MyBatis-Plus3.1詳細教程
-MyBatis-Plus 官方文檔
-代碼生成器
-解決org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)問題
-springMVC中的controller層
-FreeMarker使用 & 與spring4集成