MyBatis-Plus官網(wǎng)地址:https://mp.baomidou.com/
一、mybatis-plus簡介:
Mybatis-Plus(簡稱MP)是一個(gè) Mybatis 的增強(qiáng)工具籍琳,在 Mybatis 的基礎(chǔ)上只做增強(qiáng)不做改變奥裸,為簡化開發(fā)怯晕、提高效率而生十厢。這是官方給的定義,關(guān)于mybatis-plus的更多介紹及特性右核,可以參考mybatis-plus官網(wǎng)销凑。那么它是怎么增強(qiáng)的呢丛晌?其實(shí)就是它已經(jīng)封裝好了一些crud方法,我們不需要再寫xml了斗幼,直接調(diào)用這些方法就行澎蛛,就類似于JPA。
二蜕窿、mybatis-plus特性:
- 無侵入:只做增強(qiáng)不做改變谋逻,引入它不會(huì)對(duì)現(xiàn)有工程產(chǎn)生影響,如絲般順滑
- 損耗小:啟動(dòng)即會(huì)自動(dòng)注入基本 CURD桐经,性能基本無損耗毁兆,直接面向?qū)ο蟛僮?/li>
- 強(qiáng)大的 CRUD 操作:內(nèi)置通用 Mapper、通用 Service阴挣,僅僅通過少量配置即可實(shí)現(xiàn)單表大部分 CRUD 操作气堕,更有強(qiáng)大的條件構(gòu)造器,滿足各類使用需求
- 支持 Lambda 形式調(diào)用:通過 Lambda 表達(dá)式,方便的編寫各類查詢條件送巡,無需再擔(dān)心字段寫錯(cuò)
- 支持主鍵自動(dòng)生成:支持多達(dá) 4 種主鍵策略(內(nèi)含分布式唯一 ID 生成器 - Sequence),可自由配置盒卸,完美解決主鍵問題
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式調(diào)用骗爆,實(shí)體類只需繼承 Model 類即可進(jìn)行強(qiáng)大的 CRUD 操作
- 支持自定義全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 內(nèi)置代碼生成器:采用代碼或者 Maven 插件可快速生成 Mapper 、 Model 蔽介、 Service 摘投、 Controller 層代碼,支持模板引擎虹蓄,更有超多自定義配置等您來使用
- 內(nèi)置分頁插件:基于 MyBatis 物理分頁犀呼,開發(fā)者無需關(guān)心具體操作,配置好插件之后薇组,寫分頁等同于普通 List 查詢
- 分頁插件支持多種數(shù)據(jù)庫:支持 MySQL外臂、MariaDB、Oracle律胀、DB2宋光、H2、HSQL炭菌、SQLite罪佳、Postgre、SQLServer 等多種數(shù)據(jù)庫
- 內(nèi)置性能分析插件:可輸出 Sql 語句以及其執(zhí)行時(shí)間黑低,建議開發(fā)測(cè)試時(shí)啟用該功能赘艳,能快速揪出慢查詢
- 內(nèi)置全局?jǐn)r截插件:提供全表 delete 、 update 操作智能分析阻斷克握,也可自定義攔截規(guī)則蕾管,預(yù)防誤操作
三、MyBatis-Plus VS JPA
MyBatis-Plus優(yōu)勢(shì):
- SQL語句可以自由控制菩暗,更靈活娇掏,性能較高
- SQL于代碼分離,易于閱讀和維護(hù)
- 提供XML標(biāo)簽勋眯,支持編寫動(dòng)態(tài)SQL語句
JPA優(yōu)勢(shì):
- JPA移植性比較好
- 提供了很多 CRUD方法婴梧、開發(fā)效率高
- 對(duì)象化程度更高
MyBatis-Plus劣勢(shì):
- 簡單的CURD都要寫SQL
- XML中有大量的SQL要維護(hù)
- MyBatis自身功能很有限,但支持PLlugin
四客蹋、常用注解
- @TableName:對(duì)數(shù)據(jù)表名注解
- @TableId:表主鍵標(biāo)識(shí)
- @TableId(value = “id”, type = IdType.AUTO):自增
- @TableId(value = “id”, type = IdType.ID_WORKER_STR):分布式全局唯一ID字符串類型
- @TableId(value = “id”, type = IdType.INPUT):自行輸入
- @TableId(value = “id”, type = IdType.ID_WORKER):分布式全局唯一ID 長整型類型
- @TableId(value = “id”, type = IdType.UUID):32位UUID字符串
- @TableId(value = “id”, type = IdType.NONE):無狀態(tài)
- @TableField:表字段標(biāo)識(shí)
- @TableField(exist = false):表示該屬性不為數(shù)據(jù)庫表字段塞蹭,但又是必須使用的。
- @TableField(exist = true):表示該屬性為數(shù)據(jù)庫表字段讶坯。
- @TableField(condition = SqlCondition.LIKE):表示該屬性可以模糊搜索番电。
- @TableField(fill = FieldFill.INSERT):注解填充字段 ,生成器策略部分也可以配置!
- @Version:樂觀鎖注解漱办、標(biāo)記
- @EnumValue:通枚舉類注解
- @TableLogic:表字段邏輯處理注解(邏輯刪除)
- @SqlParser:租戶注解
- @KeySequence:序列主鍵策略
五这刷、普通查詢
增:
@Autowired
private RentDetailMapper rentDetailMapper;
@Override
public void insert(String userId, String dealerId, String strategyId) {
RentDetail rentDetail=new RentDetail();
//插入
rentDetail.setUserId(userId);
rentDetail.setDealerId(dealerId);
rentDetail.setStrategyId(strategyId);
rentDetailMapper.insert(rentDetail);
}
刪:
@Autowired
private RentDetailMapper rentDetailMapper;
@Override
public void delete(String Id) {
//刪除
rentDetailMapper.deleteById(Id);
}
改:
@Autowired
private RentDetailMapper rentDetailMapper;
@Override
public void update(String userId, String dealerId, String strategyId) {
RentDetail rentDetail=new RentDetail();
//更新
rentDetail.setUserId(userId);
rentDetail.setDealerId(dealerId);
rentDetail.setStrategyId(strategyId);
rentDetailMapper.updateById(rentDetail);
}
查:
@Autowired
private RentDetailMapper rentDetailMapper;
@Override
public void select(String Id) {
//查找
rentDetailMapper.selectById(Id);
}
六、自定義SQL查詢
接口示例:
@Mapper
@Repository
public interface IUserDao extends BaseMapper<User> {
/**
* 根據(jù)電話查找id娩井、昵稱
* @param mobile
* @param sourceId
* @return
*/
List<UserMobileVO> findId(@Param("mobile")String mobile,@Param("sourceId")String sourceId);
}
xml示例:
ps:MyBatisPlus是有駝峰命名的暇屋,不需要一個(gè)一個(gè)字段進(jìn)行映射
<?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.netx.web.dao.IUserDao">
<select id="findId" resultType="com.netx.web.vo.UserMobileVO" >
SELECT
id,
mobile,
real_name
FROM
`user`
WHERE
mobile like '%${mobile}%'and
deleted = 0
and register_source=#{sourceId}
</select>
</mapper>
動(dòng)態(tài)SQL示例:
PS:若是排序的動(dòng)態(tài)查詢需要注意不用#{字段名}而是用${字段名}
<select id="pageStrategy" resultType="com.app.entity.Strategy">
select * from strategy
<where>
<!--若傳入的參數(shù)為空,則不做對(duì)應(yīng)的篩選-->
<if test="search.house != null and search.house != ''">
house = #{search.house}
</if>
<if test="search.currncy != null and search.currncy != ''">
and currncy = #{search.currncy}
</if>
and deleted = 0 order by
<choose>
<!--若某一參數(shù)不為空洞辣,則做對(duì)應(yīng)的排序(這里要前端傳desc或asc來做降升序控制)-->
<when test="search.yiedlRate != null and search.yiedlRate != ''">
yiedl_rate ${search.yiedlRate}
</when>
<when test="search.winRate != null and search.winRate != ''">
win_rate ${search.winRate}
</when>
<when test="search.totalRentedCount != null and search.totalRentedCount != ''">
total_rented_count ${search.totalRentedCount}
</when>
<otherwise>
create_time desc
</otherwise>
</choose>
</where>
</select>
七咐刨、條件構(gòu)造器
更多詳細(xì)用法盡在官方文檔:https://mp.baomidou.com/guide/wrapper.html#select
查:
/**
* 條件構(gòu)造器 查詢操作
* 年齡在 18~50 之間性別為男且姓名為 xx 的所有用戶
*SELECT id AS id,last_name AS lastName,email,gender,age FROM tbl_employee WHERE (age BETWEEN ? AND ? AND gender = ? AND last_name = ?)
*/
@Test
public void testSelectPage(){
Page<Employee> page=new Page<>(0,2);
EntityWrapper<Employee> entityWrapper=new EntityWrapper<>();
entityWrapper.between("age",18,50).eq("gender",1).eq("last_name","Tom");
List<Employee> list = employeeMapper.selectPage(page, entityWrapper);
System.out.println(list);
}
刪:
/**
* 條件構(gòu)造器 刪除操作
*刪除名字為Tom并且性別為女年齡為45
*DELETE FROM tbl_employee WHERE (last_name = ? AND gender = ? AND age = ?)
*/
@Test
public void testDelete(){
EntityWrapper<Employee> entityWrapper=new EntityWrapper<>();
entityWrapper.eq("last_name","Tom").eq("gender",0).eq("age",45);
Integer row = employeeMapper.delete(entityWrapper);
System.out.println(row);
}
改:
/**
* 條件構(gòu)造器 修改操作
*名字為xiaohong并且性別為女年齡為10的人名字改為honghonglaoshi,郵箱改為120@qq.com
* UPDATE tbl_employee SET last_name=?, email=? WHERE (last_name = ? AND gender = ? AND age = ?)
*/
@Test
public void testUpdate(){
Employee employee=new Employee();
employee.setLastName("honghonglaoshi");
employee.setEmail("120@qq.com");
EntityWrapper<Employee> entityWrapper=new EntityWrapper<>();
entityWrapper.eq("last_name","xiaohong").eq("gender",0).eq("age",10);
Integer row = employeeMapper.update(employee, entityWrapper);
System.out.println(row);
}
八扬霜、分頁查詢
官方文檔:https://mybatis.plus/guide/page.html
XML 自定義分頁
public interface UserMapper {//可以繼承或者不繼承BaseMapper
/**
* <p>
* 查詢 : 根據(jù)state狀態(tài)查詢用戶列表定鸟,分頁顯示
* </p>
*
* @param page 分頁對(duì)象,xml中可以從里面進(jìn)行取值,傳遞參數(shù) Page 即自動(dòng)分頁,必須放在第一位(你可以繼承Page實(shí)現(xiàn)自己的分頁對(duì)象)
* @param state 狀態(tài)
* @return 分頁對(duì)象
*/
IPage<User> selectPageVo(Page<?> page, Integer state);
}
- UserMapper.xml 等同于編寫一個(gè)普通 list 查詢,mybatis-plus 自動(dòng)替你分頁
<select id="selectPageVo" resultType="com.baomidou.cloud.entity.UserVo">
SELECT id,name FROM user WHERE state=#{state}
</select>
- UserServiceImpl.java 調(diào)用分頁方法
public IPage<User> selectUserPage(Page<User> page, Integer state) {
// 不進(jìn)行 count sql 優(yōu)化著瓶,解決 MP 無法自動(dòng)優(yōu)化 SQL 問題联予,這時(shí)候你需要自己查詢 count 部分
// page.setOptimizeCountSql(false);
// 當(dāng) total 為小于 0 或者設(shè)置 setSearchCount(false) 分頁插件不會(huì)進(jìn)行 count 查詢
// 要點(diǎn)!! 分頁返回的對(duì)象與傳入的對(duì)象是同一個(gè)
return userMapper.selectPageVo(page, state);
}
九、AR策略 (Active Record活動(dòng)記錄)
- Active Record(活動(dòng)記錄)材原,簡稱AR躯泰,是一種領(lǐng)域模型模式,特點(diǎn)就是一個(gè)模型類對(duì)應(yīng)關(guān)系型數(shù)據(jù)庫中的一個(gè)表华糖,而模型類的一個(gè)實(shí)例對(duì)應(yīng)表中的一條記錄麦向;
參考文章:https://blog.csdn.net/xiaofeivip_top/article/details/94871238
開啟AR模式的方法很簡單,就是讓我們的實(shí)體類繼承Model類客叉,并實(shí)現(xiàn)其抽象方法诵竭,指定主鍵即可,如下:
@Data
public class Employee extends Model<Employee> {
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
@TableField
private String lastName;
private String email;
private Integer gender;
private Integer age;
/**
* 通過exit設(shè)置當(dāng)前字段不存在數(shù)據(jù)庫里面
*/
@TableField(exist = false)
private Double salary;
/**
* 指定當(dāng)前實(shí)體類的 主鍵屬性
* @return
*/
@Override
protected Serializable pkVal() {
return id;
}
}
測(cè)試:
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootMybatisplusARTests {
/**
* 添加
*/
@Test
public void insertAR() {
Employee employee = new Employee();
employee.setLastName("AR");
employee.setEmail("ar@xiaofei.com");
employee.setGender(1);
employee.setAge(22);
boolean insert = employee.insert();
System.err.println(insert);
System.err.println(employee.getId());
}
/**
* 修改
*/
@Test
public void updateAR() {
Employee employee = new Employee();
employee.setId(10);
employee.setGender(0);
employee.setAge(0);
boolean b = employee.updateById();
System.err.println(b);
}
/**
* 查詢
*/
@Test
public void selectAR() {
// 根據(jù)Id查詢
Employee employee = new Employee();
Employee employee1 = employee.selectById(1);
// System.err.println(employee1);
// 查詢?nèi)? List<Employee> employeesAll = employee.selectAll();
// System.err.println(employeesAll);
// 查詢名字帶有M的
List<Employee> employees = employee.selectList(new EntityWrapper().like("last_name", "M"));
// System.err.println(employees);
// 查詢總數(shù)量
int count = employee.selectCount(null);
// System.err.println(count);
// 分頁
Page<Employee> page = employee.selectPage(
new Page<Employee>(1, 2), null);
System.err.println(page);
/**
* Page:{ [Pagination { total=0 ,size=2 ,pages=0 ,current=1 }], records-size:2 }
*/
List<Employee> emps = page.getRecords();
System.err.println("數(shù)據(jù):" + emps);
}
/**
* 刪除
* <p>
* 注意:刪除不存在的數(shù)據(jù)在邏輯上也是成功的兼搏;
*/
@Test
public void deleteAR() {
Employee employee = new Employee();
boolean b = employee.deleteById(10);
System.err.println(b);
}
}
注意點(diǎn):刪除不存在的數(shù)據(jù)在邏輯上也是成功的卵慰;
十、基本配置
官方文檔:https://mp.baomidou.com/config/#基本配置
使用方式:
Spring Boot:
mybatis-plus:
......
configuration:
......
global-config:
......
db-config:
......
Configuration
mapUnderscoreToCamelCase
- 類型:
boolean
- 默認(rèn)值:
true
是否開啟自動(dòng)駝峰命名規(guī)則(camel case)映射佛呻,即從經(jīng)典數(shù)據(jù)庫列名 A_COLUMN(下劃線命名) 到經(jīng)典 Java 屬性名 aColumn(駝峰命名) 的類似映射裳朋。
?注意
?此屬性在 MyBatis 中原默認(rèn)值為 false,在 MyBatis-Plus 中吓著,此屬性也將用于生成最終的 SQL 的 select body
?如果您的數(shù)據(jù)庫命名符合規(guī)則無需使用@TableField
注解指定數(shù)據(jù)庫字段名
#defaultEnumTypeHandler
- 類型:
Class<? extends TypeHandler
- 默認(rèn)值:
org.apache.ibatis.type.EnumTypeHandler
默認(rèn)枚舉處理類,如果配置了該屬性,枚舉將統(tǒng)一使用指定處理器進(jìn)行處理
- org.apache.ibatis.type.EnumTypeHandler : 存儲(chǔ)枚舉的名稱
- org.apache.ibatis.type.EnumOrdinalTypeHandler : 存儲(chǔ)枚舉的索引
- com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler : 枚舉類需要實(shí)現(xiàn)IEnum接口或字段標(biāo)記@EnumValue注解.(3.1.2以下版本為EnumTypeHandler)
其他就不一一列舉鲤嫡,有興趣可以在官方文檔查閱