1-5 MyBatisPlus整合
接下來我們完成一個品牌的CRUD操作、我們會整合MyBatisPlus來實現。
1、MyBatis Plus介紹MyBatis-Plus(簡稱 MP)是一個 MyBatis 的增強工具,在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生。
MyBatis Plus特性:
無侵入:只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑損耗小:啟動即會自動注入基本 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 、presto 、Gauss 、FirebirdPhoenix 、clickhouse 、Sybase ASE 、 OceanBase 、達夢資料庫 、虛谷資料庫 、人大金倉資料庫 、南大通用資料庫 、2、MyBatisPlus整合1)引入依賴包在mall-service-dependency中引入如下依賴(這個依賴包之前已經引入了,這裡無需再次引入):
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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>mall-api</artifactId> <groupId>com.bobo.vip.mall</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>goods-api</artifactId> <description> shop_goods資料庫表對應的JavaBean </description></project>
在goods-api中建立com.bobo.vip.mall.goods.Brand,程式碼如下:
package com.bobo.vip.mall.goods.model;import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.annotation.TableId;import com.baomidou.mybatisplus.annotation.TableName;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data@AllArgsConstructor@NoArgsConstructor// MyBatisPlus 表對映註解@TableName(value = "brand")public class Brand { // 品牌ID // MyBatisPlus主鍵策略註解 @TableId(type= IdType.AUTO) private Integer id; // 品牌名字 private String name; // 品牌圖片 private String image; // 品牌首字母 private String initial; // 品牌排序 private Integer sort;}
主鍵生成策略
AUTO資料庫ID自增NONE無狀態,該型別為未設定主鍵型別(註解裡等於跟隨全域性,全局裡約等於 INPUT)INPUTinsert前自行set主鍵值ASSIGN_ID分配ID(主鍵型別為Number(Long和Integer)或String)(since 3.3.0),使用介面IdentifierGenerator的方法nextId(預設實現類為DefaultIdentifierGenerator雪花演算法)ASSIGN_UUID分配UUID,主鍵型別為String(since 3.3.0),使用介面IdentifierGenerator的方法nextUUID(預設default方法)ID_WORKER分散式全域性唯一ID 長整型型別(please use ASSIGN_ID) ,已過時UUID32位UUID字串(please use ASSIGN_UUID) ,已過時ID_WORKER_STR分散式全域性唯一ID 字串型別(please use ASSIGN_ID) ,已過時
專案工程結構如下:
3)商品微服務在mall-service中建立mall-goods-service微服務,用於操作shop_goods資料庫。
pom.xml程式碼如下:
server: port: 8081spring: application: name: mall-goods datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.100.140:3306/shop_goods?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC username: root password: 123456 cloud: nacos: config: file-extension: yaml server-addr: 192.168.100.140:8848 discovery: #Nacos的註冊地址 server-addr: 192.168.100.140:8848# ====================MybatisPlus====================mybatis-plus: mapper-locations: mapper/*.xml type-aliases-package: com.bobo.vip.mall.*.model configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl#日誌配置logging: pattern: console: "%msg%n"
配置說明:
type-aliases-package:指定JavaBean的別名包,和MyBatis用法一樣。mapper-locations:複雜的操作可能需要自己寫SQL,SQL可以寫到xml檔案中,這裡指定和Dao對應的xml檔案,此時我們需要在resources中建立一個mapper目錄。map-underscore-to-camel-case:開啟駝峰功能,資料庫表列名如果有_,可以自動按駝峰命名規則轉換。log-impl:日誌開啟,方便測試。
建立啟動類com.bobo.vip.mall.MallGoodsServiceApplication:
@SpringBootApplication@MapperScan(basePackages = {"com.bobo.vip.mall.goods.mapper"})public class MallGoodsServiceApplication { public static void main(String[] args) { SpringApplication.run(MallGoodsServiceApplication.class,args); }}
此時啟動程式,檢視Nacos控制檯:http://192.168.100.140:8848/nacos 賬號和密碼都是nacos,效果如下:
3、MyBatisPlus操作案例我們建立一個品牌操作的功能,實現品牌增刪改查,分別建立model、mapper、service、controller。
MyBatisPlus提供了很多通用方法:
mapper(介面)->extends BaseMapper【增刪改查】service(介面)->extends IService【增刪改查】serviceImpl->extends ServiceImpl【增刪改查】
3.1 Mapper建立
在mall-goods-service建立com.bobo.vip.mall.goods.mapper.BrandMapper介面,程式碼如下:
public interface BrandMapper extends BaseMapper<Brand> {}
程式碼說明:BaseMapper中已經存在了很多常見資料庫操作方法,可以大幅提升開發速度。
3.2 Service建立在mall-goods-service建立com.bobo.vip.mall.goods.service.BrandService介面,程式碼如下:
public interface BrandService extends IService<Brand>{}
在mall-goods-service建立com.bobo.vip.mall.goods.service.impl.BrandServiceImpl實現類,程式碼如下:
@Servicepublic class BrandServiceImpl extends ServiceImpl<BrandMapper,Brand> implements BrandService {}
程式碼說明:IService和ServiceImpl中已經建立好了很多常用的增刪改查方法,我們寫常用的增刪改查,幾乎不用寫方法。
3.3 增刪改功能增刪改功能在IService和ServiceImpl中已經全部存在, 不需要額外新增方法,只需要在Controller呼叫即可。
在mall-goods-service建立com.bobo.vip.mall.goods.controller.BrandController,程式碼如下:
@RestController@RequestMapping("/brand")public class BrandController { @Autowired private BrandService service; /** * 新增品牌 * @param brand * @return */ @PostMapping public RespResult save(@RequestBody Brand brand){ service.save(brand); return RespResult.ok(); } /**** * 修改 */ @PutMapping public RespResult update(@RequestBody Brand brand){ //修改品牌 service.updateById(brand); return RespResult.ok(); } /**** * 刪除品牌 */ @DeleteMapping("/{id}") public RespResult delete(@PathVariable(value = "id") Integer id){ //刪除品牌 service.removeById(id); return RespResult.ok(); }}
重啟服務然後我們透過Postman來測試即可
表結構中原有資料
Postman中的資料
操作成功
4.4 條件查詢/分頁條件查詢需要封裝條件資訊,MyBatis Plus提供了條件封裝物件Wrapper(它的子類QueryWrapper可以直接使用),我們可以用它的子類QueryWrapper實現封裝查詢條件。
4.4.1 條件查詢在BrandService中建立如下方法:
List<Brand> queryList(Brand brand);
在BrandServiceImpl中建立條件查詢方法實現(不要忘了注入brandMapper):
/** * 多條件查詢 * @param brand * @return */ @Override public List<Brand> queryList(Brand brand) { // 多條件構造器 QueryWrapper<Brand> queryWrapper = new QueryWrapper<>(); if(brand != null){ if(!StringUtils.isEmpty(brand.getName())){ queryWrapper.like("name",brand.getName()); } if(!StringUtils.isEmpty(brand.getInitial())){ queryWrapper.eq("initial",brand.getInitial()); } } return mapper.selectList(queryWrapper); }
程式碼說明:
like:表示模糊查詢eq:表示等值查詢
在BrandController中建立條件查詢方法:
/**** * 條件查詢 */@PostMapping(value = "/list")public RespResult<List<Brand>> list(@RequestBody(required = false) Brand brand){ // 查詢 List<Brand> brands = brandService.queryList(brand); return RespResult.ok(brands);}
不帶引數查詢所有的資料
帶引數查詢
4.4.2 分頁查詢在BrandService中建立如下方法:
Page<Brand> queryPageList(Long currentPage,Long size,Brand brand);
在BrandServiceImpl中建立條件查詢方法實現(不要忘了注入brandMapper):
/*** * 分頁查詢 * @param brand * @return */@Overridepublic Page<Brand> queryPageList(Long currentPage, Long size, Brand brand) { // 封裝查詢條件 Page<Brand> page = brandMapper.selectPage( new Page<Brand>(currentPage, size), new QueryWrapper<Brand>() .like("name", brand.getName())); return page;}
程式碼說明:
like:表示模糊查詢
在BrandController中建立條件查詢方法:
/**** * 條件分頁查詢 */@PostMapping(value = "/list/{page}/{size}")public RespResult<Page<Brand>> list( @PathVariable(value = "page")Long currentPage, @PathVariable(value = "size")Long size, @RequestBody(required = false) Brand brand){ // 分頁查詢 Page<Brand> brandPage = brandService.queryPageList(currentPage,size,brand); return RespResult.ok(brandPage);}
我們還在往Spring容器中注入一個分頁的攔截器,不然分頁效果不會有效
package com.bobo.vip.mall;import com.baomidou.mybatisplus.annotation.DbType;import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.Bean;@SpringBootApplication@MapperScan(basePackages = {"com.bobo.vip.mall.goods.mapper"})public class MallGoodsServiceApplication { public static void main(String[] args) { SpringApplication.run(MallGoodsServiceApplication.class,args); } /** * 往容器中注入分頁的攔截器 * @return */ @Bean public PaginationInterceptor paginationInterceptor(){ PaginationInterceptor interceptor = new PaginationInterceptor(); // 設定資料庫的型別 interceptor.setDbType(DbType.MYSQL); return interceptor; }}
分頁查詢的效果如下
搞定~