您好,登錄后才能下訂單哦!
今天小編給大家分享一下java Springboot集成mybatis-plus的方法是什么的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
Mybatis-plus是Mybatis的增強工具包,其官網的介紹如下:
潤物細無聲:只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑。
效率至上:只需簡單配置,即可快速進行單表CRUD操作,從而節省大量時間。
豐富功能:代碼生成、自動分頁、邏輯刪除、自動填充等功能一應俱全。
其優點如下:
無侵入:Mybatis-Plus 在 Mybatis 的基礎上進行擴展,只做增強不做改變,引入 Mybatis-Plus 不會對您現有的 Mybatis 構架產生任何影響,而且 MP 支持所有 Mybatis 原生的特性
依賴少:僅僅依賴 Mybatis 以及 Mybatis-Spring
損耗小:啟動即會自動注入基本CURD,性能基本無損耗,直接面向對象操作
通用CRUD操作:內置通用 Mapper、通用 Service,僅僅通過少量配置即可實現單表大部分 CRUD 操作,更有強大的條件構造器,滿足各類使用需求
多種主鍵策略:支持多達4種主鍵策略(內含分布式唯一ID生成器),可自由配置,完美解決主鍵問題
支持ActiveRecord:支持 ActiveRecord 形式調用,實體類只需繼承 Model 類即可實現基本 CRUD 操作
支持代碼生成:采用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支持模板引擎,更有超多自定義配置等您來使用(P.S. 比 Mybatis 官方的 Generator 更加強大!)
支持自定義全局通用操作:支持全局通用方法注入( Write once, use anywhere )
內置分頁插件:基于Mybatis物理分頁,開發者無需關心具體操作,配置好插件之后,寫分頁等同于寫基本List查詢
內置性能分析插件:可輸出Sql語句以及其執行時間,建議開發測試時啟用該功能,能有效解決慢查詢
內置全局攔截插件:提供全表 delete 、 update 操作智能分析阻斷,預防誤操作
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> </dependency>
注:如果是gradle,引入的方式如下:
implementation group: 'com.baomidou', name: 'mybatis-plus-boot-starter', version: '3.5.3.1'
創建對應的數據表 Schema 的表結構和表數據:
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `user_base_info` -- ---------------------------- DROP TABLE IF EXISTS `user_base_info`; CREATE TABLE `user_base_info` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '主鍵ID', `u_id` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用戶ID', `name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用戶名', `cn_name` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '中文名', `sex` char(3) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '性別', `alias` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '別名', `web_chat` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '微信號', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
表中插入數據
-- ---------------------------- -- Records of user_base_info -- ---------------------------- INSERT INTO `user_base_info` VALUES ('1', '001', 'holmium', '鈥', '1', '虎嘯山村', 'holmium'); INSERT INTO `user_base_info` VALUES ('2', '001', 'test', '測試', '0', '美女', '虎嘯山村');
#mybatis-plus mybatis-plus: ## 這個可以不用配置,因其默認就是這個路徑 mapper-locations: classpath:/mapper/*Mapper.xml #實體掃描,多個package用逗號或者分號分隔 typeAliasesPackage: com.holmium.springboot.repository.*.entity 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 #駝峰下劃線轉換 column-underline: true #數據庫大寫下劃線轉換 #capital-mode: true #邏輯刪除配置 logic-delete-value: 0 logic-not-delete-value: 1 db-type: h3 #刷新mapper 調試神器 refresh: true # 原生配置 configuration: map-underscore-to-camel-case: true cache-enabled: false
//BasePo,后續可以繼續擴展 @Data public class BasePo { @TableId(value = "id", type = IdType.AUTO) private Integer id; } package com.holmium.springboot.infra.user.entity; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Getter; import lombok.Setter; /** * @author holmium * @description: * @date 2023年04月20日16:19 */ @TableName(value = "user_base_info", autoResultMap = true) @Getter @Setter public class UserPo extends BasePo { /** * 用戶ID */ @TableField(value = "u_id") String uId; /** * 用戶名 */ @TableField(value = "name") String name; /** * 中文名稱 */ @TableField(value = "cn_name") String cnName; /** * 性別:1-男 0-女 */ @TableField(value = "sex") String sex; /** * 別名 */ @TableField(value = "alias") String alias; /** * 微信號 */ @TableField(value = "web_chat") String webChat; }
package com.holmium.springboot.infra.user.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.holmium.springboot.infra.user.entity.UserPo; import org.apache.ibatis.annotations.Mapper; @Mapper public interface UserMapper extends BaseMapper<UserPo> { }
//如果不理解,可以看之前的文章 @RestController @RequestMapping("/user/center") public class UserApi { @Resource UserAppImpl userApp; @GetMapping(value = "/userinfo") public UserVo gerUserInfo(@RequestParam("id") String id) throws Exception { return userApp.getUserInfoByUserId(id); } }
@MapperScan
注解,掃描 Mapper 文件夾@SpringBootApplication @MapperScan("com.holmium.springboot.infra.*.mapper") //添加mapper掃描 public class HolmiumApplication { public static void main(String[] args) { SpringApplication.run(HolmiumApplication.class, args); } }
通過以上的步驟,我們實現了對User表的查詢功能,可以看到對于簡單的CRUD操作,Mybatis-Plus
只需要定義一個Mapper
接口即可實現,真正做到如他所說的那樣,簡單配置、效率至上。
主鍵生成策略一共提供的五種:
AUTO(0),遞增策略,如果使用該策略必須要求數據表的列也是遞增。 NONE(1),沒有策略,必須人為的輸入id值 INPUT(2),沒有策略,必須人為的輸入id值 ASSIGN_ID(3), 隨機生成一個Long類型的值。該值一定是唯一。而且每次生成都不會相同。算法:雪花算法。 適合分布式主鍵。 ASSIGN_UUID(4); 隨機產生一個String類型的值。該值也是唯一的。
通過配置文件中,配置id-type
屬性:
mybatis-plus: global-config: # 數據庫相關配置 db-config: #主鍵類型 AUTO:"數據庫ID自增", INPUT:"用戶輸入ID",ID_WORKER:"全局唯一ID (數字類型唯一ID)", UUID:"全局唯一ID UUID"; id-type: AUTO
也可在對象屬性上進行注解設置:
@Data public class BasePo { //配置為數據庫ID自增 @TableId(value = "id", type = IdType.AUTO) private Integer id; }
實際開發過程中,對數據都不會直接刪除,都會采用邏輯刪除的方式。所謂的邏輯刪除,只是將數據置為一個狀態,這個狀態代表數據為刪除狀態,一般自己程序中寫的話,就設置一個狀態字段,給字段賦值為0
或 D
代表刪除。而Mybatis-plus提供了@TableLogic
注解,實現邏輯刪除。 只對自動注入的 sql 起效:
插入: 不作限制
查找: 追加 where 條件過濾掉已刪除數據,且使用 wrapper.entity 生成的 where 條件會忽略該字段
更新: 追加 where 條件防止更新到已刪除數據,且使用 wrapper.entity 生成的 where 條件會忽略該字段
刪除: 轉變為 更新
@Data public class BasePo { /** * 主鍵 */ @TableId(value = "id", type = IdType.AUTO) private Integer id; /** * 是否刪除:0表示未刪除 1表示刪除. */ @TableLogic private Boolean deleted; }
實際開發中,我們會在表中記錄數據創建時間、創建人、修改時間、修改人幾個字段,但是幾個字段如果我們每次都要進行賦值,代碼比較冗余,Mybatis-plus
提供的自動填充功能。
@Data public class BasePo { /** * 主鍵 */ @TableId(value = "id", type = IdType.AUTO) private Integer id; /** * 創建時間 */ @TableField(fill = FieldFill.INSERT) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; /** * 最后更新時間 */ @TableField(fill = FieldFill.INSERT_UPDATE) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date updateTime; /** * 創建者,默認系統User 的 id 編號 * <p> * 使用 String 類型的原因是,未來可能會存在非數值的情況,留好拓展性。 */ @TableField(fill = FieldFill.INSERT, jdbcType = JdbcType.VARCHAR) private String creator; /** * 更新者,默認系統User 的 id 編號 * <p> * 使用 String 類型的原因是,未來可能會存在非數值的情況,留好拓展性。 */ @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.VARCHAR) private String updater; /** * 是否刪除 */ @TableLogic private Boolean deleted; }
public class DefaultDbFieldHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { if (Objects.nonNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity) { BaseEntity baseDO = (BaseEntity) metaObject.getOriginalObject(); Date current = new Date(); // 創建時間為空,則以當前時間為插入時間 if (Objects.isNull(baseDO.getCreateTime())) { baseDO.setCreateTime(current); } // 更新時間為空,則以當前時間為更新時間 if (Objects.isNull(baseDO.getUpdateTime())) { baseDO.setUpdateTime(current); } Long userId = WebUtils.getLoginUserId(); // 當前登錄用戶不為空,創建人為空,則當前登錄用戶為創建人 if (Objects.nonNull(userId) && Objects.isNull(baseDO.getCreator())) { baseDO.setCreator(userId.toString()); } // 當前登錄用戶不為空,更新人為空,則當前登錄用戶為更新人 if (Objects.nonNull(userId) && Objects.isNull(baseDO.getUpdater())) { baseDO.setUpdater(userId.toString()); } } } @Override public void updateFill(MetaObject metaObject) { // 更新時間為空,則以當前時間為更新時間 Object modifyTime = getFieldValByName("updateTime", metaObject); if (Objects.isNull(modifyTime)) { setFieldValByName("updateTime", new Date(), metaObject); } // 當前登錄用戶不為空,更新人為空,則當前登錄用戶為更新人 Object modifier = getFieldValByName("updater", metaObject); Long userId = WebUtils.getLoginUserId(); if (Objects.nonNull(userId) && Objects.isNull(modifier)) { setFieldValByName("updater", userId.toString(), metaObject); } } }
Wrapper:封裝了關于查詢的各種條件方法。
有三個子類最常用: LambdaQueryWrapper
查詢條件 LambdaUpdateWrapper
修改條件 LambdaQueryWrapper
查詢使用lambda表達式條件
LambdaQueryWrapper
selectPage(userDo, new LambdaQueryWrapperX<UserPo>() .likeIfPresent(UserPo::getName, userDo.getName()) .likeIfPresent(UserPo::getSex, userDo.getSex()) .betweenIfPresent(UserPo::getCreateTime, userDo.getCreateTime()) .orderByDesc(UserPo::getId))
LambdaUpdateWrapper
update(update, new LambdaUpdateWrapper<UserPo>() .eq(UserPo::getId, id).eq(UserPo::getName, name))
LambdaQueryWrapper
new LambdaQueryWrapper<UserDo>() .eq(UserPo::getId, id) .eq(UserPo::getName, name);
添加分頁攔截器
@Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); // 分頁插件 mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return mybatisPlusInterceptor; }
分頁查詢
Page<UserPo> page = userMapper.selectPage(page, wrapper);//把查詢的結果自動封裝到Page對象中
到此簡單的查詢基本已介紹完畢,可滿足他80%的日常開發需求。
從上述代碼中可以看到,我們從數據庫查詢出來的結果是轉換為一個想XXXPo
的對象,而接口返回的是XXXVo
對象。在實際項目中,一般一個project都會分很多層,每層都會定義自己的對象,如:PO、VO、DAO、BO、DTO、POJO等等。
DO(Data Object):此對象與數據庫表結構一一對應,通過 DAO 層向上傳輸數據源對象。
DTO(Data Transfer Object):數據傳輸對象,Service 或 Manager 向外傳輸的對象。
BO(Business Object):業務對象,由 Service 層輸出的封裝業務邏輯的對象。
AO(ApplicationObject):應用對象,在Web層與Service層之間抽象的復用對象模型, 極為貼近展示層,復用度不高。
VO(View Object):顯示層對象,通常是 Web 向模板渲染引擎層傳輸的對象。
POJO是DO/DTO/BO/VO的統稱,禁止命名成xxxPOJO。
這些對象在傳遞過程中,需要相互轉換,如果手工書寫,往往會通過getxxx
,再setxxx
,操作起來非常繁瑣,那有沒有一種方式比較簡單實現能?下面我們介紹一個對象轉換的組件mapstruct
。
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct --> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.5.4.Final</version> </dependency>
package com.holmium.springboot.app.user.convert; import com.holmium.springboot.api.user.vo.UserVo; import com.holmium.springboot.common.user.app.dto.UserDto; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; /** * @author holmium * @date 2023年04月16日 20:24 */ @Mapper public interface UserAppConvert { UserAppConvert INSTANCES = Mappers.getMapper(UserAppConvert.class); UserVo voToDto(UserDto userDto); }
避坑
這里的
@Mapper
注解和上述Mybatis-plus
中的@Mapper
注解相同,很容易引入錯誤,導致會報錯。這里的
Mapper
是import org.mapstruct.Mapper;
mybatis-plus
中的@Mapper
,import org.apache.ibatis.annotations.Mapper;
一定要注意看清楚引入的類
@Service public class UserAppImpl implements UserApp { @Resource public UserDomain userDomain; @Override public UserVo getUserInfoByUserId(String userId) throws Exception { //這樣就實現了對象轉換 return UserAppConvert.INSTANCES.voToDto(userDomain.getUserInfoByUid(userId)); } }
上述是兩個對象中屬性相同話,可以不用做其他任何操作,就可以事項對象互轉,但實際在開發中,兩個對象屬性不可能完全一樣。而上述操作只能將相同屬性做轉換,不同的屬性沒法互相轉換,導致對象有部分數據丟失?那怎么解決,可在轉換方法上加入@Mappings
注解,如下:
@Mapper public interface UserAppConvert { UserAppConvert INSTANCES = Mappers.getMapper(UserAppConvert.class); @Mappings({ //屬性不一致轉換 @Mapping(source = "name", target = "userName"), //類型不一致轉換 @Mapping(target = "createTime", expression = "java(com.java.mmzsblog.util.DateTransform.strToDate(source.getCreateTime()))"), }) UserVo voToDto(UserDto userDto); }
這樣就解決了不同對象屬性和屬性類型不一致轉換問題。
以上就是“java Springboot集成mybatis-plus的方法是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。