MyBatis-Plus實(shí)用篇超完整教程
一、基礎(chǔ)組件
簡介
- MyBatis-Plus (opens new window)(簡稱 MP)是一個(gè) MyBatis (opens new window)的
增強(qiáng)工具
- 在MyBatis 的基礎(chǔ)上
只做增強(qiáng)不做改變
,為簡化開發(fā)、提高效率而生
1、BaseMapper接口API
- BaseMapper是MyBatis-Plus提供的模板mapper,其中包含了基本的CRUD方法,泛型為操作的實(shí)體類型
- Mapper繼承該接口后,無需編寫 mapper.xml 文件,即可獲得CRUD功能
- BaseMapper接口,增刪改返回影響數(shù)據(jù)條數(shù)的Integer
BaseMapper中提供的CRUD方法
增加:insert
刪除:delete
- 修改:update
- update方法:entity實(shí)體對象某屬性為null,則不會(huì)修改此屬性
查詢:select
- selectObjs方法:只返回第一個(gè)字段的值
- selectPage方法:分頁需要添加分頁插件,否則不生效
2、IService接口API
- 封裝IService接口,進(jìn)一步封裝CRUD采用
get查詢單行、remove刪除、list查詢集合、page分頁前綴
命名方式 - IService接口,增刪改返回是否操作成功的boolean
- 泛型 T 為任意實(shí)體對象
IService中提供的CRUD方法
增加:save
刪除:remove
修改:update
新增或修改:主鍵存在則根據(jù)主鍵修改,主鍵不存在則新增
- 查詢:單個(gè)get,集合listgetOne方法,多個(gè)拋出異常,第二個(gè)參數(shù)
throwEx設(shè)置為false
則獲取第一條數(shù)據(jù)
查詢記錄數(shù):count
分頁查詢:page
- 集合查詢:listlistObjs方法,可以將查詢結(jié)果T類型轉(zhuǎn)換成V類型返回List<V>
3、創(chuàng)建Service層操作數(shù)據(jù)
Mapper接口:創(chuàng)建UserMapper對象并繼承BaseMapper
@Mapper public interface UserMapper extends BaseMapper<User> {}
Service接口:創(chuàng)建UserService并繼承IService
/** * UserService繼承IService模板提供的基礎(chǔ)功能 */ public interface UserService extends IService<User> {}
Service實(shí)現(xiàn)類:創(chuàng)建UserService的實(shí)現(xiàn)類并繼承ServiceImpl
/** * ServiceImpl實(shí)現(xiàn)了IService,提供了IService中基礎(chǔ)功能的實(shí)現(xiàn) * 若ServiceImpl無法滿足業(yè)務(wù)需求,則可以使用自定的UserService定義方法,并在實(shí)現(xiàn)類中實(shí)現(xiàn) */ @Service public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService{}
二、常用注解
1、@TableName
- 在實(shí)體類類型上添加@TableName(“t_user”),標(biāo)識(shí)實(shí)體類對應(yīng)的表
- 不加注解,默認(rèn)駝峰轉(zhuǎn)下劃線則是表明,如實(shí)體OrderInfo,則默認(rèn)對應(yīng)表名order_info
@Data @TableName("t_user") public class User { private Long id; private String name; private Integer age; private String email; }
為實(shí)體類所對應(yīng)的表名設(shè)置默認(rèn)的前綴,那么就不需要在每個(gè)實(shí)體類上通過@TableName標(biāo)識(shí)實(shí)體類對應(yīng)的表
mybatis-plus: global-config: db-config: # 設(shè)置實(shí)體類所對應(yīng)的表的統(tǒng)一前綴 table-prefix: t_
2、@TableId
2.1、value屬性
不加注解,默認(rèn)情況Long id就是主鍵如果想其他字段作為主鍵,且實(shí)體與數(shù)據(jù)庫字段不一致,則添加@TableId(value = “tid”)
@Data public class User { @TableId(value = "tid") private Long uid; private String name; private Integer age; private String email; }
2.2、type屬性
常用主鍵策略:
枚舉值 | 描述 |
---|---|
IdType.AUTO | 數(shù)據(jù)庫ID自增;該類型請確保數(shù)據(jù)庫設(shè)置了ID自增,否則無效 |
IdType.INPUT | 用戶輸入ID;該類型可以通過自己注冊自動(dòng)填充插件進(jìn)行填充 |
IdType.ASSIGN_ID(默認(rèn)) | 主鍵類型為number或string的雪花算法;只有當(dāng)插入對象ID 為空,才自動(dòng)填充 |
IdType.ASSIGN_UUID | 主鍵類型為string,UUID.replace(“-”,“”);只有當(dāng)插入對象ID 為空,才自動(dòng)填充 |
IdType.NONE | 沒有設(shè)置主鍵類型;跟隨全局;全局的主鍵策略如果沒有設(shè)置,默認(rèn)是雪花算法 |
@Data public class User { @TableId(type = IdType.AUTO) private Long uid; private String name; private Integer age; private String email; }
Mybatis-plus中的內(nèi)置雪花算法
- 在某些情況下,我們想提前獲取這個(gè)ID,調(diào)用
com.baomidou.mybatisplus.core.toolkit.IdWorker.getId()
方法即可
3、@TableField
3.1、value屬性
- 解決對象中字段名和數(shù)據(jù)庫不匹配(沒有遵循小駝峰或者完全不匹配)
//指定數(shù)據(jù)庫字段名稱 @TableField(value = "email") private string mail
解決關(guān)鍵字報(bào)錯(cuò)
// 執(zhí)行的sql語句就變成`關(guān)鍵字`,這樣sql就不會(huì)報(bào)錯(cuò)了 @TableField(value = "`desc`") private string desc
3.2、exist屬性
解決對象中的屬性字段在表中不存在的問題
@TableField(exist = false) private Boolean checked;
3.3、select屬性
在查詢操作中某個(gè)字段值不想被查詢展示出來(比如密碼password),可使用此注解
@TableField(select = false) private String password;
3.4、condition屬性
預(yù)處理where查詢條件
// 實(shí)體注解-實(shí)現(xiàn)模糊查詢 @TableField(condition = SqlCondition.LIKE) private String name; // 業(yè)務(wù)代碼 User user = new User(); user.setName("張"); userService.lambdaQuery(user).list(); // 打印sql SELECT id,user_name,age FROM user WHERE name LIKE CONCAT('%',?,'%')
鏈?zhǔn)讲樵儾簧В]有模糊查詢)
userService.lambdaQuery().eq(User::getName,"張").list();
3.5、update屬性
- 預(yù)處理update set 部分
- 方式一:@TableField(update="%s+1") update 表 set 字段=字段+1 where …
- 方式二:@TableField(update="now()") 使用數(shù)據(jù)庫時(shí)間,update 表 set 字段=now() where …
// 方式三: // 實(shí)體注解-實(shí)現(xiàn)修改字段時(shí)候,前后添加“**” 其中 %s 會(huì)填充為字段 @TableField(update = "CONCAT('**',%s,'**')") private String name; // 業(yè)務(wù)代碼 User user = new User(); user.setId(1); user.setName("張三"); userService.updateById(user); // 打印sql UPDATE user SET name=CONCAT('**',name,'**') WHERE id=?
鏈?zhǔn)讲樵儾簧Вㄇ昂鬀]有填充**)
userService.lambdaQuery().eq(User::getName,"張").list();
3.6、fill屬性
解決每個(gè)數(shù)據(jù)庫表都有create_time 和 update_time字段,我們可以使用自動(dòng)填充功能維護(hù)這兩個(gè)字段
// 實(shí)體字段注解 @TableField(fill = FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; // 枚舉類 public enum FieldFill { /** * 默認(rèn)不處理 */ DEFAULT, /** * 插入填充字段 */ INSERT, /** * 更新填充字段 */ UPDATE, /** * 插入和更新填充字段 */ INSERT_UPDATE }
創(chuàng)建MyMetaObjectHandler配置類,實(shí)現(xiàn)MetaObjectHandler
接口
@Component public class MyMetaObjectHandler implements MetaObjectHandler { Date date = new Date(); @Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, "createTime", Date.class, date); this.strictInsertFill(metaObject, "updateTime", Date.class, date); } @Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, "updateTime", Date.class, date); } }
3.7、insertStrategy、updateStrategy、whereStrategy屬性
- insertStrategy:當(dāng)insert操作時(shí),該字段拼接insert語句時(shí)的策略
- updateStrategy:當(dāng)更新操作時(shí),該字段拼接set語句時(shí)的策略
- whereStrategy:表示該字段在拼接where條件時(shí)的策略
public enum FieldStrategy { /** * 忽略判斷,所有字段都進(jìn)行更新和插入 * 無論什么值,直接拼接,沒有值,則拼接null */ IGNORED, /** * 只更新和插入非NULL值 * 相當(dāng)于添加if判斷,不為null才操作 * <if test="columnProperty != null">column=#{columnProperty}</if> */ NOT_NULL, /** * 只更新和插入非NULL值且非空字符串 * 相當(dāng)于添加if判斷,不為null而且不是空字符串才操作 * <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if> */ NOT_EMPTY, /** * 默認(rèn)NOT_NULL */ DEFAULT, /** * 永遠(yuǎn)不進(jìn)行更新和插入 */ NEVER }
3.8、typeHandler屬性
- 類型處理器,設(shè)置存入數(shù)據(jù)庫的類型
- 設(shè)置mysql數(shù)據(jù)庫字段info為json類型,@TableField(typeHandler = JacksonTypeHandler.class)表示將UserInfo對象轉(zhuǎn)為json對象入庫
- 此時(shí)user出現(xiàn)對象嵌套List<Address>,需要設(shè)置resultMap響應(yīng)對象,@TableName(autoResultMap = true)表示自動(dòng)映射resultMap
4、@TableLogic
- 物理刪除:真實(shí)刪除,將對應(yīng)數(shù)據(jù)從數(shù)據(jù)庫中刪除,之后查詢不到此條被刪除的數(shù)據(jù)
- 邏輯刪除:假刪除,將對應(yīng)數(shù)據(jù)中代表是否被刪除字段的狀態(tài)修改為“被刪除狀態(tài)”,之后在數(shù)據(jù)庫中仍舊能看到此條數(shù)據(jù)記錄
實(shí)現(xiàn)邏輯刪除
數(shù)據(jù)庫中創(chuàng)建邏輯刪除狀態(tài)列,設(shè)置默認(rèn)值為0
實(shí)體類中添加邏輯刪除屬性
測試刪除功能,真正執(zhí)行的是修改
public void testDeleteById(){ int result = userMapper.deleteById(1527472864163348482L); System.out.println(result > 0 ? "刪除成功!" : "刪除失??!"); System.out.println("受影響的行數(shù)為:" + result); }
此時(shí)執(zhí)行查詢方法,查詢的結(jié)果為自動(dòng)添加條件is_deleted=0
public void testSelectList(){ List<User> users = userMapper.selectList(null); }
三、條件構(gòu)造器
1、wapper介紹
- Wrapper:條件構(gòu)造抽象類,最頂端父類
- AbstractWrapper:用于查詢條件封裝,生成sql的where條件
- QueryWrapper:查詢條件封裝
- UpdateWrapper:update條件封裝
- AbstractLambdaWrapper:使用Lambda語法
- LambdaQueryWrapper:用于Lambda語法使用的查詢Wrapper
- LambdaUpdateWrapper:用于Lambda語法更新Wrapper
- AbstractWrapper:用于查詢條件封裝,生成sql的where條件
2、構(gòu)造器常用方法
函數(shù)名 | 說明 | 說明/例子 |
---|---|---|
eq | 等于= | 例:eq(“name”,“zhangsan”) —> name = ‘zhangsan’ |
ne | 不等于<> | 例:ne(“name”,“zhangsan”) —> name <> ‘zhangsan’ |
gt | 大于> | 例:gt(“age”,18) —> age > 18 |
ge | 大于等于>= | 例:ge(“age”,18) —> age >= 18 |
lt | 小于< | 例:lt(“age”,18) —> age < 18 |
le | 小于等于<= | 例:le(“age”,18) —> age <= 18 |
between | between 值1 and 值2 | 例:between(“age”,10,20) —> age between 10 and 20 |
notBetween | not between 值1 and 值2 | 例:notBetween(“age”,10,20) —> age not between 10 and 20 |
like | like ‘%值%’ | 例:like(“name”,“強(qiáng)”) —> name like ‘%強(qiáng)%’ |
notLike | not like ‘%值%’ | 例:notLike(“name”,“強(qiáng)”) —> name not like ‘%強(qiáng)%’ |
likeLeft | like ‘%值’ | 例:like(“name”,“飛”) —> name like ‘%強(qiáng)’ |
likeRight | like ‘值%’ | 例:like(“name”,“王”) —> name like ‘王%’ |
isNull | 字段 is null | 例:isNull(“emal”) —> email is null |
isNotNull | 字段 is not null | 例:isNotNull(“emal”) —> email is not null |
in | 字段 in (值1,值2…) | 例:in(“age”,{10,18,30}) —> age in (10,18,30) |
notIn | 字段 not in (值1,值2…) | 例:notIn(“age”,{10,18,30}) —> age not in (10,18,30) |
inSql | 字段 in ( sql語句 ) | inSql(“id”, “select id from table where name like ‘%J%’”) —> id in (select id from table where name like ‘%J%’) |
notInSql | 字段 not in ( sql語句 ) | notInSql(“id”, “select id from table where name like ‘%J%’”) —> id not in (select id from table where name like ‘%J%’) |
groupBy | 分組 group by 字段,… | 例:groupBy(“id”,“name”) —> group by id,name ?? 注意:如果不查詢聚合函數(shù),默認(rèn)返回第一條數(shù)據(jù) |
orderBy | 排序 ordery by 字段,… | 例:orderBy(true,true,“id”,“name”) —> order by id asc,name asc |
orderByAsc | 升排序 order by 字段,… asc | 例:orderByAsc(“id”,“name”) —> order by id,name |
orderByDesc | 降排序 order by 字段,… desc | 例:orderByDesc(“id”,“name”) —> order by id desc,name desc |
having | having (sql語句) | having(“sum(age) > {0}”,18) —> having sum(age) > 18 |
or | 拼接or | 例:eq(“id”,1).or().eq(“name”,“老王”) —> id =1 or name = ‘老王’ |
and | and 嵌套 | 例:and(i -> i.eq(“name”,“李白”).ne(“status”,“活著”)) —> and (name = ’李白‘ and status <> ‘活著’) |
apply | 拼接sql | **例:apply(“date_format(date_time,‘%Y-%m-%d’) = {0}”,“2002-08-08”) —> date_fromat(date_time,‘%Y-%m-%d’) = ‘2008-08-08’ ?? 注意:動(dòng)態(tài)入?yún)?yīng){index}部分,直接寫sql語句,有sql注入風(fēng)險(xiǎn) |
last | 拼接到sql的最后 | 例:last(“limit 5”) 注意事項(xiàng):只能調(diào)用一次,多次調(diào)用以最后一次為準(zhǔn),有sql注入風(fēng)險(xiǎn) |
exists | 拼接exists (sql語句) | 例:exists(“select id from table where age = 1”) |
not exists | 拼接not exists (sql語句) | 例:not exists(“select id from table where age = 1”) |
nested | 正常嵌套 不帶and和or | 例:nested(i-> i.eq(“name”,“李華”).gt(“age”,20)) —> (name = “李華” and age > 20) |
3、組裝條件示例
條件的優(yōu)先級
sql語句規(guī)則:and和or一起用,and優(yōu)先級高
/** 組裝修改條件 將(年齡大于20并且用戶名中包含有a)或郵箱為null的用戶信息修改 **/ @Test public void test01() { /* UPDATE t_user SET user_name=?, email=? age > ? AND user_name LIKE ? OR email IS NOT NULL */ QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.gt("age", 20) .like("user_name", "a") .or() .isNotNull("email"); User user = new User(); user.setName("小明"); user.setEmail("test@atguigu.com"); int result = userMapper.update(user, queryWrapper); System.out.println("result = " + result); } /** 條件優(yōu)先級 將用戶名中包含a并且(年齡大于20或郵箱為null)的用戶信息修改 **/ @Test public void test02() { // lambda中條件優(yōu)先級 /* UPDATE t_user SET user_name=?, email=? WHERE user_name LIKE ? AND (age > ? OR email IS NULL) */ QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.like("user_name", "a") .and(i -> i.gt("age", 20).or().isNull("email")); User user = new User(); user.setName("小紅"); user.setEmail("test@atguigu.com"); int result = userMapper.update(user, queryWrapper); System.out.println("result = " + result); }
Lambda表達(dá)式
@Test public void test3() { /* SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE user_name LIKE ? AND age <= ? */ String username = "a"; Integer ageBegin = null; Integer ageEnd = 30; //組裝set子句 LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>(); //避免使用字符串表示字段,防止運(yùn)行時(shí)錯(cuò)誤 queryWrapper.like(StringUtils.isNotBlank(username), User::getName, username) .gt(ageBegin != null, User::getAge, ageBegin) .le(ageEnd != null, User::getAge, ageEnd); List<User> list = userMapper.selectList(queryWrapper); list.forEach(System.out::println); } @Test public void test4() { /* UPDATE t_user SET user_name=?,email=? WHERE user_name LIKE ? AND (age > ? OR email IS NULL) */ LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.like(User::getName, "a") //lambda表達(dá)式內(nèi)的邏輯優(yōu)先運(yùn)算 .and(i -> i.gt(User::getAge, 20).or().isNull(User::getEmail)); updateWrapper.set(User::getName, "小黑").set(User::getEmail, "abc@atguigu.com"); int result = userMapper.update(null, updateWrapper); System.out.println("result = " + result); }
四、擴(kuò)展功能
1、鏈?zhǔn)讲樵兣c修改
IService接口中提供
- 鏈?zhǔn)讲樵儯嚎梢源鴮懚鄠€(gè)條件
- .one()結(jié)尾:查詢單條數(shù)據(jù)
- .list()結(jié)尾:查詢多條數(shù)據(jù)
- .count()結(jié)尾:查詢記錄數(shù)
@Test public void test1(){ // 單個(gè)查詢,多個(gè)報(bào)錯(cuò) User user = userService.lambdaQuery().eq(User::getName, "Tom").one(); // 集合查詢 List<User> userList = userService.lambdaQuery().like(User::getName, "J").eq(User::getAge,20).list(); // 記錄數(shù)查詢 Integer count = userService.lambdaQuery().like(User::getAge, 20).select(User::getName, User::getAge).count(); }
- 鏈?zhǔn)叫薷模嚎梢源鴮懚鄠€(gè)條件
- .update()結(jié)尾:修改set的字段(只修改set的字段,fill屬性更新填充屬性不會(huì)修改)
- .update(entity)結(jié)尾:修改entity數(shù)據(jù)的字段
- .remove()結(jié)尾:刪除數(shù)據(jù)
@Test public void test2() { // set修改某些屬性 userService.lambdaUpdate().eq(User::getName, "Tom").set(User::getId, 110).set(User::getAge, 15).update(); // 修改整個(gè)對象 User user = new User(); user.setId(110L); user.setAge(15); userService.lambdaUpdate().eq(User::getName, "Tom").update(user); // 根據(jù)名稱刪除 userService.lambdaUpdate().eq(User::getName, "Jack").remove(); }
2、靜態(tài)工具類Db
Service之間也會(huì)相互調(diào)用,為了避免出現(xiàn)循環(huán)依賴問題,MybatisPlus提供一個(gè)靜態(tài)工具類:Db
@Test void testDbGet() { User user = Db.getById(1L, User.class); System.out.println(user); } ? @Test void testDbList() { // 利用Db實(shí)現(xiàn)復(fù)雜條件查詢 List<User> list = Db.lambdaQuery(User.class) .like(User::getUsername, "o") .ge(User::getBalance, 1000) .list(); } ? @Test void testDbUpdate() { Db.lambdaUpdate(User.class) .set(User::getBalance, 2000) .eq(User::getUsername, "Rose"); }
這樣就可以在任意serviceImpl中都可以使用任意的service,而不需要依賴注入了
4、自定義sql
4.1、自定義xml分頁sql
UserMapper中定義接口方法
page 分頁對象,xml中可以從里面進(jìn)行取值,傳遞參數(shù) Page 即自動(dòng)分頁,必須放在第一位
/** * 根據(jù)年齡查詢用戶列表,分頁顯示 */ Page<User> selectPageVo(@Param("page") Page<User> page,@Param("age") Integer age);
UserMapper.xml中編寫SQL
<select id="selectPageVo" resultType="User"> select id,username as name,age,email from t_user where age > #{age} </select>
測試方法
- xml中沒有分頁語句,mybatisplus自動(dòng)分頁
- 前提必須有分頁插件,否則沒有分頁效果
@Test public void testSelectPageVo(){ //設(shè)置分頁參數(shù) Page<User> page = new Page<>(1, 5); userMapper.selectPageVo(page, 20); //獲取分頁數(shù)據(jù) List<User> list = page.getRecords(); list.forEach(System.out::println); System.out.println("當(dāng)前頁:"+page.getCurrent()); System.out.println("每頁顯示的條數(shù):"+page.getSize()); System.out.println("總記錄數(shù):"+page.getTotal()); System.out.println("總頁數(shù):"+page.getPages()); System.out.println("是否有上一頁:"+page.hasPrevious()); System.out.println("是否有下一頁:"+page.hasNext()); }
4.2、@Select注解自定義sql
普通sql
@Select("select * from student where age = #{age} and user_name = #{userName}") Student getStudent( @Param("age") Integer age, @Param("userName") String userName);
帶Wrapper條件sql
@Param("ew")
:固定寫法,可以參照BaseMapper接口里的方法${ew.customSqlSegment}
:固定寫法,在sql后面拼接條件,不需要寫where關(guān)鍵字
@Param("page") Page<?> page
:Wrapper條件和分頁可以共用,但是分頁需要寫在最前面
// 單表查詢 @Select("select * from student ${ew.customSqlSegment}") Student getStudentById( @Param("ew") QueryWrapper<Student> wrapper); // 多表查詢 @Select("SELECT u.* FROM student u INNER JOIN address a ON u.id = a.student_id ${ew.customSqlSegment}") List<Student> queryStudentListByWrapper(@Param("page") Page<Student> page, @Param("ew")QueryWrapper<User> wrapper);
4.3、連表left join和inner join的分頁查詢區(qū)別
left join
查詢通過Page<?> page參數(shù)自動(dòng)分頁時(shí)候,查詢總條數(shù)COUNT(*)時(shí)候會(huì)將left join去掉,也就是只查主表的數(shù)據(jù)- 此時(shí)如果有副表的字段作為查詢條件會(huì)報(bào)錯(cuò):Unknown column ‘xxx’ in ‘where clause’(主表找不到xxx字段)
// 情況1:如果查詢條件中有address的字段,比如模糊查詢地址名稱 // 情況2:如果查詢條件的字段,兩個(gè)表都有,這里會(huì)有問題 // 自動(dòng)分頁的查詢count(*)時(shí)候,就會(huì)拋出以上異常 @Select("SELECT u.* FROM student u LEFT JOIN address a ON u.id = a.student_id ${ew.customSqlSegment}") List<Student> queryStudentListByWrapper(@Param("page") Page<Student> page, @Param("ew")QueryWrapper<User> wrapper);
解決方式:嵌套一層select * from (連表復(fù)雜sql)as result ${ew.customSqlSegment}
@Select("SELECT * FROM (SELECT u.* FROM student u LEFT JOIN address a ON u.id = a.student_id) as result ${ew.customSqlSegment}") List<Student> queryStudentListByWrapper(@Param("page") Page<Student> page, @Param("ew")QueryWrapper<User> wrapper);
inner join
查詢通過Page<?> page參數(shù)自動(dòng)分頁時(shí)候,查詢總條數(shù)COUNT(*)時(shí)候不會(huì)將inner join去掉,所以一般不需要嵌套
4.4、連表查詢條件Wrapper和響應(yīng)IPage的泛型
- 查詢條件Wrapper和響應(yīng)IPage的泛型
非表實(shí)體
也行,只有符合數(shù)據(jù)庫字段的駝峰命名
即可(需要?jiǎng)?chuàng)建實(shí)體對象) - 如果查詢條件同時(shí)需要多個(gè)表字段,也可以
@Param("ew") Wrapper<?> queryWrapper
(不需要?jiǎng)?chuàng)建實(shí)體對象)
5、IPage的泛型轉(zhuǎn)換(entity轉(zhuǎn)換為vo)
// 分頁查詢 Page<UserEntity> userPage = super.lambdaQuery().page(new Page<>(request.getCurrent(), request.getSize())); // entity轉(zhuǎn)換為vo IPage<UserVO> infoResPage = userPage.convert(item -> Convert.convert(UserVO.class, item));
6、SimpleQuery工具類
Simplequery可以對selectList查詢后的結(jié)果用stream流
進(jìn)行了一些封裝,使其可以返回一些指定結(jié)果,簡潔api的調(diào)用
示例
獲取Student對象集合的名字集合
// 方式一 List<String> nameList = SimpleQuery.list( new LambdaQueryWrapper<Student>().like(Student::getUserName, "張"), Student::getUserName ); // 方式二 List<Student> list = studentService.list(); List<String> nameList2 = SimpleQuery.list2List(list, Student::getUserName);
先將Student對象的名稱前后添加**再獲取名字集合
List<String> nameList = SimpleQuery.list( new LambdaQueryWrapper<Student>().like(Student::getUserName, "李"), Student::getUserName, new Consumer<Student>() { @Override public void accept(Student student) { student.setUserName("**"+student.getUserName()+"**"); } } );
返回key=名字,value=年齡的map
Map<String, Integer> map = SimpleQuery.map( new LambdaQueryWrapper<>(), Student::getUserName, Student::getAge );
group分組,key位名字,value相同名字的Student對象集合
Map<String, List<Student>> group = SimpleQuery.group( new LambdaQueryWrapper<Student>(), Student::getUserName );
7、ActiveRecord
- ActiveRecord(活動(dòng)記錄,簡稱 AR),是一種領(lǐng)域模型模式,特點(diǎn)是一個(gè)模型類對應(yīng)關(guān)系型數(shù)據(jù)庫中的一個(gè)表,而模型類的一個(gè)實(shí)例對應(yīng)表中的一行記錄
- ActiveRecord 一直廣受解釋型動(dòng)態(tài)語言( PHP 、 Ruby 等)的喜愛,通過圍繞一個(gè)數(shù)據(jù)對象進(jìn)行CRUD操作
- 僅僅需要讓實(shí)體類繼承Model類且實(shí)現(xiàn)主鍵指定方法
@Data @TableName(value = "student") public class Student extends Model<Student> { /** * 主鍵id */ private Long id; /** * 姓名 */ private String userName; /** * 年齡 */ private Integer age; } @Test void activeRecordAddQ{ Student student = new Student(); student.setUserName("李四"); student.setAge(12); student.insert(); }
Model抽象類方法
注意: 必須存在對應(yīng)的原始mapper并繼承baseMapper并且可以使用
五、插件
1、Mybatis插件
MybatisPlusInterceptor分頁插件
@Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); //注意使用哪種數(shù)據(jù)庫 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }
2、MyBatisX插件
2.1、生成逆向工程
找到我們需要生成的表點(diǎn)擊右鍵
填寫完信息以后下一步
繼續(xù)填寫信息
結(jié)果展示
2.2、快速生成CRUD
MyBaitsX可以根據(jù)我們在Mapper接口中輸入的方法名【alt+Enter
】快速幫我們生成對應(yīng)的sql語句
到此這篇關(guān)于MyBatis-Plus實(shí)用篇超完整教程的文章就介紹到這了,更多相關(guān)MyBatis-Plus實(shí)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用JavaBean根據(jù)指定條件設(shè)置屬性值默認(rèn)值方式
這篇文章主要介紹了使用JavaBean根據(jù)指定條件設(shè)置屬性值默認(rèn)值方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03SSH框架網(wǎng)上商城項(xiàng)目第8戰(zhàn)之查詢和刪除商品類別功能實(shí)現(xiàn)
SSH框架網(wǎng)上商城項(xiàng)目第8戰(zhàn)之查詢和刪除商品類別功能實(shí)現(xiàn),為項(xiàng)目增加功能,添加、更新、刪除和查詢操作,感興趣的小伙伴們可以參考一下2016-05-05Java19新特性中結(jié)構(gòu)化并發(fā)的使用
Java19在并發(fā)編程領(lǐng)域引入了一個(gè)全新的概念:結(jié)構(gòu)化并發(fā),這一特性旨在簡化并發(fā)任務(wù)的管理,提升多線程程序的可維護(hù)性和安全性,使其生命周期和控制流更加有序和明確,感興趣的可以了解一下2024-09-09Java多線程環(huán)境下SimpleDateFormat類安全轉(zhuǎn)換
這篇文章主要介紹了Java多線程環(huán)境下SimpleDateFormat類安全轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02springboot整合Mybatis、JPA、Redis的示例代碼
這篇文章主要介紹了springboot整合Mybatis、JPA、Redis的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Java ArrayList與Vector和LinkedList的使用及源碼分析
ArrayList、Vector、LinkedList類均在java.util包中,均為可伸縮數(shù)組,即可以動(dòng)態(tài)改變長度的數(shù)組。ArrayList 和 Vector都是基于存儲(chǔ)元素的Object[] array來實(shí)現(xiàn)的,它們會(huì)在內(nèi)存中開辟一塊連續(xù)的內(nèi)存來存儲(chǔ)2022-11-11Spring Boot實(shí)戰(zhàn)之?dāng)?shù)據(jù)庫操作的示例代碼
本篇文章主要介紹了Spring Boot實(shí)戰(zhàn)之?dāng)?shù)據(jù)庫操作的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01dubbo如何設(shè)置連接zookeeper權(quán)限
這篇文章主要介紹了dubbo如何設(shè)置連接zookeeper權(quán)限問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05