前面用了7篇博客,講完了mybatis。掌握了前面7篇博客的內容,便可以自如應對spring下的mybatis開發了。
然而,很多時候Mybatis的表現並不是那麼完美,比如很多簡單的CURD語句還需要開發者手動完成;不支持分頁功能,需要開發者寫代碼實現分頁邏輯等等。。。。
這時候,就不得不提MyBatis-Plus了,MyBatis-Plus正是爲簡化Mybatis的開發而誕生的。
1. MyBatis-Plus介紹
官網關於MyBatis-Plus簡介的第一句話就是:
MyBatis-Plus(簡稱 MP)是一個 MyBatis 的增強工具,在 MyBatis 的基礎上只做增強不做改變,爲簡化開發、提高效率而生。
只做增強,不做改變。這意味着原來寫的MyBatis代碼可以直接拿來用在MyBatis-Plus上,而幾乎不用做任何修改。
就像 魂鬥羅 中的 1P、2P,基友搭配,效率翻倍。
在這裏直接貼上官網對MP的特性介紹:
- 無侵入:只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑
- 損耗小:啓動即會自動注入基本 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 操作智能分析阻斷,也可自定義攔截規則,預防誤操作
本文將演示一下SpringBoot + MyBatis-Plus項目環境的搭建,以及使用MyBatis-Plus內置的CRUD,以及演示分頁。
2. SpringBoot整合MyBatis-Plus
2.1 新建SpringBoot項目
第一步:新創建SpringBoot項目,這一步前面已經做了很多次了,不詳細說了。
新創建好的項目的目錄結構:
2.2 添加依賴
需要添加的依賴有:
- mysql-connector-java:數據庫驅動
- lombok:可自動生成Getter、Setter、toString方法
- mybatis-plus-boot-starter:mybatis-plus啓動器
添加依賴:
<!--mysql驅動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--自動生成Getter、Setter、toString方法的插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--mybatis-plus啓動器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
2.3 配置數據源以及mybatis-plus
spring:
datasource:
username: root
password: 123
#mysql8以上的驅動包需要指定以下時區
url: jdbc:mysql://127.0.0.1:23306/study-mybatis?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
# 指定實體類所有包
type-aliases-package: com.yky.springboot.entities
# 指定xml映射配置文件掃描路徑
mapper-locations: classpath:mapper/*.xml
2.4 創建實體類
在entities包下創建User類,代碼爲下:
package com.yky.springboot.entities;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class User implements Serializable {
//指定一下主鍵id
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private String phone;
private Date birthday;
}
2.5 創建Mapper接口
package com.yky.springboot.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yky.springboot.entities.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
在這裏,只需要繼承BaseMapper接口,甚至不用寫mapper映射配置文件,便可直接使用MP內部的CRUD操作接口。
MP默認提供了以下操作CRUD接口:
/**
* 插入一條記錄
*
* @param entity 實體對象
*/
int insert(T entity);
/**
* 根據 ID 刪除
*
* @param id 主鍵ID
*/
int deleteById(Serializable id);
/**
* 根據 columnMap 條件,刪除記錄
*
* @param columnMap 表字段 map 對象
*/
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
/**
* 根據 entity 條件,刪除記錄
*
* @param wrapper 實體對象封裝操作類(可以爲 null)
*/
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
/**
* 刪除(根據ID 批量刪除)
*
* @param idList 主鍵ID列表(不能爲 null 以及 empty)
*/
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
/**
* 根據 ID 修改
*
* @param entity 實體對象
*/
int updateById(@Param(Constants.ENTITY) T entity);
/**
* 根據 whereEntity 條件,更新記錄
*
* @param entity 實體對象 (set 條件值,可以爲 null)
* @param updateWrapper 實體對象封裝操作類(可以爲 null,裏面的 entity 用於生成 where 語句)
*/
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
/**
* 根據 ID 查詢
*
* @param id 主鍵ID
*/
T selectById(Serializable id);
/**
* 查詢(根據ID 批量查詢)
*
* @param idList 主鍵ID列表(不能爲 null 以及 empty)
*/
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
/**
* 查詢(根據 columnMap 條件)
*
* @param columnMap 表字段 map 對象
*/
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
/**
* 根據 entity 條件,查詢一條記錄
*
* @param queryWrapper 實體對象封裝操作類(可以爲 null)
*/
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根據 Wrapper 條件,查詢總記錄數
*
* @param queryWrapper 實體對象封裝操作類(可以爲 null)
*/
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根據 entity 條件,查詢全部記錄
*
* @param queryWrapper 實體對象封裝操作類(可以爲 null)
*/
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根據 Wrapper 條件,查詢全部記錄
*
* @param queryWrapper 實體對象封裝操作類(可以爲 null)
*/
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根據 Wrapper 條件,查詢全部記錄
* <p>注意: 只返回第一個字段的值</p>
*
* @param queryWrapper 實體對象封裝操作類(可以爲 null)
*/
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根據 entity 條件,查詢全部記錄(並翻頁)
*
* @param page 分頁查詢條件(可以爲 RowBounds.DEFAULT)
* @param queryWrapper 實體對象封裝操作類(可以爲 null)
*/
<E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根據 Wrapper 條件,查詢全部記錄(並翻頁)
*
* @param page 分頁查詢條件
* @param queryWrapper 實體對象封裝操作類
*/
<E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
開發者可直接調用這些接口方法操作數據庫,而無須關心接口的內部實現,大大簡化了開發,提高了開發效率。
2.6 創建Service層
在Web開發中,Controller層調用Service層代碼,業務邏輯寫在Service層;Service層調用Dao層代碼(這裏的Dao層就是Mapper接口),Dao層操作數據庫。所以,一般情況下還需要開發Service層。
Service接口需要這樣寫:
package com.yky.springboot.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yky.springboot.entities.User;
public interface UserService extends IService<User> {
}
光有Service接口還不夠,還需要有接口實現:
package com.yky.springboot.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yky.springboot.entities.User;
import com.yky.springboot.mapper.UserMapper;
import com.yky.springboot.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
只需要繼承ServiceImpl類便可直接調用Mapper接口的方法了,因爲Service層是面向接口編程,所以我們還繼承了前面寫的UserService接口。
至此,Dao層、Service層均已創建好了。
如果想在Service層的實現類中調用Mapper代碼,直接用baseMapper即可(所繼承的ServiceImpl中有注入Mapper進來):
3. 單元測試
@SpringBootTest
class UserServiceTest {
@Autowired
UserService userService;
/**
* 新增或修改數據(如果主鍵id不爲空,且id已在數據庫中存在了,則進行更新操作)
*/
@Test
public void insert() throws ParseException {
User user = new User();
user.setName("法外狂徒張三");
user.setPhone("11111111111");
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1996-07-18"));
userService.saveOrUpdate(user);
}
/**
* 刪除數據
*/
@Test
public void delete() {
userService.removeById(1);
}
/**
* 獲取所有
*/
@Test
public void selectAll() {
List<User> users = userService.list();
System.out.println(users);
}
/**
* 根據id獲取
*/
@Test
public void getById() {
User user = userService.getById(1);
System.out.println(user);
}
}
至此,我們沒有寫任何的xml映射配置代碼,就已經完成了對數據庫的大部分操作。接下來,我們來完成一下分頁。
4. 分頁查詢
分頁查詢的實現步驟:
- 配置分頁插件
- 在Mapper接口編寫分頁查詢接口
- 編寫SQL語句,查詢數據庫
- Service層調用分頁查詢接口
4.1 配置分頁插件
新創建config.MybatisPlusConfig並寫入以下代碼:
package com.yky.springboot.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* mybatisPlus配置
*/
@EnableTransactionManagement//開啓事務管理
//@MapperScan("com.mengxuegu.web.mapper")//掃描Mapper接口,就不需要在Mapper接口上加Mapper註解了
@Configuration
public class MybatisPlusConfig {
/**
* 分頁插件
* @return
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
4.2 編寫分頁查詢接口
/**
* 分頁查詢接口
* @param page 分頁對象
* @param user 用於查詢的實體對象
* @return 分頁數據
*/
IPage<User> selectPage(Page<User> page,@Param("user") User user);
Page對象的屬性:
public class Page<T> implements IPage<T> {
/**
* 查詢數據列表
*/
private List<T> records = Collections.emptyList();
/**
* 總數
*/
private long total = 0;
/**
* 每頁顯示條數,默認 10
*/
private long size = 10;
/**
* 當前頁
*/
private long current = 1;
/**
* 排序字段信息
*/
private List<OrderItem> orders = new ArrayList<>();
/**
* 自動優化 COUNT SQL
*/
private boolean optimizeCountSql = true;
/**
* 是否進行 count 查詢
*/
private boolean isSearchCount = true;
/**
* 是否命中count緩存
*/
private boolean hitCount = false;
}
我們可以設置page對象的size、current屬性來進行分頁查詢,查詢結果封裝在records中。
4.3 編寫xml映射配置文件
在resources/mapper目錄下創建UserMapper.xml文件,並寫入以下代碼:
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace對應Mapper接口的全類名,這樣就可以自動匹配上-->
<mapper namespace="com.yky.springboot.mapper.UserMapper">
<select id="selectPage" resultType="User">
SELECT
*
FROM `user`
<where>
<if test="user.name != null and user.name != ''">
name LIKE CONCAT('%',#{user.name},'%')
</if>
<if test="user.phone != null and user.phone != ''">
AND `phone` = #{user.phone}
</if>
</where>
</select>
</mapper>
在這裏,都不需要寫LIMIT語句,MyBatis-Plus會自動幫我們添加上(根據傳入的Page對象,自動生成LIMIT語句)。
4.4 單元測試測試Dao層代碼
@Autowired
UserMapper userMapper;
@Test
public void selectPage() {
User user = new User();
user.setName("小");
IPage<User> userPage = userMapper.selectPage(new Page<User>(),user);
System.out.println(userPage.getRecords());
}
4.5 編寫Service層分頁查詢代碼
編寫Service接口:
/**
* 分頁查詢數據
* @param size 單頁大小
* @param current 當前頁碼
* @param user 用於查詢的實體對象
* @return 分頁數據
*/
IPage<User> selectPage(long size, long current, User user);
編寫接口實現:
@Override
public IPage<User> selectPage(long size, long current, User user) {
Page page = new Page();
page.setSize(size);
page.setCurrent(current);
return baseMapper.selectPage(page,user);
}
單元測試Service層代碼
@Test
public void selectPage() {
User user = new User();
user.setName("小");
IPage<User> page = userService.selectPage(3, 1, user);
System.out.println(page.getRecords());
System.out.println(page.getTotal());
}
至此,使用MyBatis-Plus進行分頁查詢的功能開發完成,相比於手寫分頁簡單多了。關於使用MyBatis-Plus簡化MyBatis開發就講到這裏了,如果想了解更多可移步MyBatis-Plus官網。如果有什麼問題,歡迎大家在評論區指出。