網(wǎng)站開(kāi)發(fā)廈門廣告營(yíng)銷案例100例
MybatisPlus
- 快速入門
- 入門案例
- 常見(jiàn)注解
- 常用配置
- 核心功能
- 條件構(gòu)造器
- 自定義SQL
- Service接口
快速入門
入門案例
使用MybatisPlus的基本步驟:
1.引入MybatisPlus的起步依賴
MybatisPlus官方提供了starter,其中集成了Mybatis和MybatisPlus的所有功能,并且實(shí)現(xiàn)了自動(dòng)裝配效果。因此,可以使用MybatisPlus的starter代替Mybatis的starter。
pom.xml
<!--mybatisplus依賴-->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version>
</dependency>
2.自定義的Mapper繼承MybatisPlus提供的BaseMapper接口
public interface UserMapper extends BaseMapper<User> {
}
3.在實(shí)體類上添加注解聲明表信息
4.在application.yml中根據(jù)需要添加配置
注:如果application.yml沒(méi)有顯示綠葉,可以按照以下步驟進(jìn)行添加:
File --> Project Structure --> Facets --> “+” Spring --> 右上角小綠葉 Customize Spring Boot --> 將項(xiàng)目中的application.yml添加進(jìn)去即可
常見(jiàn)注解
MybatisPlus是如何獲取實(shí)現(xiàn)CRUD的數(shù)據(jù)庫(kù)信息的?
- 默認(rèn)以類名駝峰轉(zhuǎn)下劃線作為表名
- 默認(rèn)把名為id的字段作為主鍵
- 默認(rèn)把變量名駝峰轉(zhuǎn)下劃線作為表的字段名
MybatisPlus通過(guò)掃描實(shí)體類,并基于反射獲取實(shí)體類信息作為數(shù)據(jù)庫(kù)表信息。
MybatisPlus中比較常用的幾個(gè)注解如下:
-
@TableName
:用來(lái)指定表名 -
@TableId
:用來(lái)指定表中的主鍵字段信息
IdType
枚舉:
①AUTO
:數(shù)據(jù)庫(kù)自增長(zhǎng)
②INPUT
:通過(guò)set
方法自行輸入
③ASSIGN_ID
:分配ID,接口IdentifierGenerator
的方法nextId
來(lái)生成id -
@TableField
:用來(lái)指定表中的普通字段信息
使用場(chǎng)景:
①成員變量名與數(shù)據(jù)庫(kù)字段名不一致
②成員變量名以is開(kāi)頭,且是布爾值
③成員變量名與數(shù)據(jù)庫(kù)關(guān)鍵字沖突,如“order”,在@TableField
中要用轉(zhuǎn)義字符括起來(lái)
⑩成員變量不是數(shù)據(jù)庫(kù)字段,@TableField(exist = false)
常用配置
MyBatisPlus的配置項(xiàng)繼承了MyBatis原生配置和一些自己特有的配置。
application.yml
mybatis-plus:type-aliases-package: com.wmy.mp.domain.po # 別名掃描包mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址 默認(rèn)值configuration:map-underscore-to-camel-case: true # 是否開(kāi)啟下劃線和駝峰的映射cache-enabled: false # 是否開(kāi)啟二級(jí)緩存global-config: # 全局配置 優(yōu)先級(jí)低于局部的配置db-config:id-type: assign_id # id為雪花算法生成update-strategy: not_null # 更新策略:只更新非空字段
MybatisPlus官方文檔
核心功能
條件構(gòu)造器
MybatisPlus支持各種復(fù)雜的where條件,可以滿足日常開(kāi)發(fā)的所有需求。在MybatisPlus中BaseMapper接口是用來(lái)提供增刪改查功能的,其中一些比較特殊的方法的參數(shù)都不再是簡(jiǎn)單的id,而是一個(gè)Wrapper類型的參數(shù),所謂的Wrapper就是條件構(gòu)造器,用以構(gòu)造復(fù)雜的sql語(yǔ)句。Wrapper并不是一個(gè)簡(jiǎn)單的類,而是類似于Collection,具備一個(gè)復(fù)雜的繼承體系。
比如說(shuō):
QueryWrapper
就是在父類基礎(chǔ)上拓展了select相關(guān)的功能,允許構(gòu)造SQL語(yǔ)句時(shí)能指定select哪些字段;
UpdateWrapper
就是在父類基礎(chǔ)上拓展了set相關(guān)的功能,它的setSql(boolean , String ) : UpdateWrapper<T>
方法允許將set部分的字符串當(dāng)做參數(shù)傳遞進(jìn)去,后邊可以拼接到SQL語(yǔ)句中。
基于QueryWrapper的查詢案例
需求
①查詢出名字中帶"o"的,存款大于等于1000元的人的id、username、info、balance字段。
SQL語(yǔ)句
SELECT id,username,info,balance
FROM user
WHERE username LIKE ? AND balance >= ?
QueryWrapper查詢:UserMapperTest.java
@Test
void testQueryWrapper(){//1.構(gòu)件查詢條件QueryWrapper<User> wrapper = new QueryWrapper<User>().select("id", "username", "info", "balance").like("username", "o").ge("balance", 1000);//2.查詢List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);
}//或者
@Test
void testLambdaQueryWrapper(){//1.構(gòu)件查詢條件LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>().select(User::getId, User::getUsername, User::getInfo, User::getBalance).like(User::getUsername, "o").ge(User::getBalance, 1000);//2.查詢List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);
}
加粗樣式
②更新用戶名為jack的用戶的余額為2000。
SQL語(yǔ)句
UPDATE userSET balance = 2000WHERE (username = "jack")
QueryWrapper查詢
@Test
void testUpdateByQueryWrapper() {//1.要更新的數(shù)據(jù)User user = new User();user.setBalance(2000);//2.更新的條件QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "jack");//3.執(zhí)行更新userMapper.update(user, wrapper);
}
基于UpdateWrapper的更新案例
需求
更新id為1,2,4的用戶的余額,扣200
SQL語(yǔ)句
UPDATE userSET balance = balance - 200WHERE id in (1, 2, 4)
UpdateWrapper查詢:UserMapperTest.java
@Test
void testUpdateWrapper(){List<Long> ids = List.of(1L ,2L ,4L);UpdateWrapper<User> wrapper = new UpdateWrapper<User>().setSql("balance = balance - 200").in("id" , ids);userMapper.update(null , wrapper);
}
小結(jié)
- QueryWrapper和LambdaQueryWrapper通常用來(lái)構(gòu)建select、delete、update的where條件部分
- UpdateWrapper和LambdaUpdateWrapper通常只有在set語(yǔ)句比較特殊才使用
- 盡量使用LambdaQueryWrapper和LambdaUpdateWrapper,避免硬編碼
自定義SQL
從條件構(gòu)造器的學(xué)習(xí)中可以看出,雖然MybatisPlus提供了非常靈活的關(guān)于Where條件的SQL語(yǔ)句拼接方式,但是它是在業(yè)務(wù)邏輯層完成的,違背了企業(yè)開(kāi)發(fā)的一些規(guī)范,如果不使用的話自己在xml文件中編寫(xiě)完整的SQL語(yǔ)句又會(huì)很麻煩。因此,我們可以利用MyBatisPlus的Wrapper來(lái)構(gòu)建復(fù)雜的Where條件,然后自定義SQL語(yǔ)句中剩下的部分。我們需要想一種辦法把mp構(gòu)建好的條件往下傳遞給mapper層,在xml中最終實(shí)現(xiàn)SQL語(yǔ)句的組裝。
步驟:
1.基于Wrapper構(gòu)建where條件
UserMapperTest.java
@Test
void testCustomSqlUpdate() {//1.更新條件List<Long> ids = List.of(1L , 2L , 4l);int amount = 200;//2.定義條件QueryWrapper<User> wrapper = new QueryWrapper<User>().in("id" , ids);//3.調(diào)用自定義SQL方法userMapper.updateBalanceByIds(wrapper, amount);
}
2.在mapper方法參數(shù)中用Param注解聲明wrapper變量名稱,必須是ew
UserMapper.java
void updateBalanceByIds(@Param("ew") QueryWrapper<User> wrapper, @Param("amount") int amount);
3.自定義SQL,并使用Wrapper條件
UserMapper.xml
<update id="updateBalanceByIds">UPDATE tb_user SET balance = balance - #{amount} ${ew.customSqlSegment}
</update>
Service接口
Service接口類似于BaseMapper接口,包含了一些基本的增刪改查的代碼,跟BaseMapper相比,只多不少。
基本用法
自定義接口需要實(shí)現(xiàn)IService
接口,自定義實(shí)現(xiàn)類需要繼承IService
的實(shí)現(xiàn)類ServiceImpl
。
IUserService.java
public interface IUserService extends IService<User>{
}
UserServiceImpl.java
@Service
public class UserServiceImpl extends IServiceImpl<UserMapper, User> implements IUserService {
}
批量新增
IUserServiceTest.java
//方式一:普通for循環(huán)插入 提交了100000次網(wǎng)絡(luò)請(qǐng)求
@Test
void testSaveOneByOne(){long b = System.currentTimeMillis();for(int i = 1; i <= 100000 ; i++ ){userService.save(builderUser(i));}long e = System.currentTimeMillis();System.out.println("耗時(shí):" + (e - b));
}//方式二:IService的批量插入 每次批量插入1000條數(shù)據(jù) 插入100次即10萬(wàn)條數(shù)據(jù)
@Test
void testSaveBatch(){//1.準(zhǔn)備一個(gè)容量為1000的集合List<User> list = new ArrayList<>(1000);long b = System.currentTimeMillis();for (int i = 1; i <= 100000 ; i++){//2.添加一個(gè)userlist.add(buildUser(i));//3.每1000條批量插入一次if (i % 1000 == 0){userService.saveBatch(list);//4.清空集合 準(zhǔn)備下一批數(shù)據(jù)list.clear(); }}
}
方式二相較于方式一,采用的是批處理的方式,速度快了近十倍,方拾貳需要向網(wǎng)絡(luò)請(qǐng)求100次,但是由于在預(yù)編譯的過(guò)程中,每次的1000條數(shù)據(jù)是被編譯成了1000條SQL語(yǔ)句,所以MySQL在執(zhí)行的過(guò)程中就是逐條執(zhí)行的,所以方式二仍然有改進(jìn)空間,可以通過(guò)配置jdbc參數(shù),在application.yaml的url后面拼接上一個(gè)參數(shù)rewriteBatchedStatements=true
,開(kāi)啟該參數(shù)之后,相當(dāng)于把100000條插入語(yǔ)句變成了一個(gè)包含了100000條插入值的語(yǔ)句,只需要執(zhí)行一次,速度上會(huì)快很多,這才是真正意義上的批處理。