欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MyBatis-Plus實(shí)用篇超完整教程

 更新時(shí)間:2025年02月17日 12:19:21   作者:冬天vs不冷  
MyBatis-Plus是一個(gè)MyBatis的增強(qiáng)工具,提供了許多便捷的功能,簡化了開發(fā)流程,同時(shí),MyBatis-Plus提供了鏈?zhǔn)讲樵兣c修改、靜態(tài)工具類、自定義SQL、IPage的泛型轉(zhuǎn)換、ActiveRecord等擴(kuò)展功能,以及分頁插件和MyBatisX插件等插件,進(jìn)一步提高了開發(fā)效率,感興趣的朋友一起看看吧

一、基礎(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

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
betweenbetween 值1 and 值2例:between(“age”,10,20) —> age between 10 and 20
notBetweennot between 值1 and 值2例:notBetween(“age”,10,20) —> age not between 10 and 20
likelike ‘%值%’例:like(“name”,“強(qiáng)”) —> name like ‘%強(qiáng)%’
notLikenot like ‘%值%’例:notLike(“name”,“強(qiáng)”) —> name not like ‘%強(qiáng)%’
likeLeftlike ‘%值’例:like(“name”,“飛”) —> name like ‘%強(qiáng)’
likeRightlike ‘值%’例: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
havinghaving (sql語句)having(“sum(age) > {0}”,18) —> having sum(age) > 18
or拼接or例:eq(“id”,1).or().eq(“name”,“老王”) —> id =1 or name = ‘老王’
andand 嵌套例: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)值方式

    這篇文章主要介紹了使用JavaBean根據(jù)指定條件設(shè)置屬性值默認(rèn)值方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • SSH框架網(wǎng)上商城項(xiàng)目第8戰(zhàn)之查詢和刪除商品類別功能實(shí)現(xiàn)

    SSH框架網(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-05
  • Java19新特性中結(jié)構(gòu)化并發(fā)的使用

    Java19新特性中結(jié)構(gòu)化并發(fā)的使用

    Java19在并發(fā)編程領(lǐng)域引入了一個(gè)全新的概念:結(jié)構(gòu)化并發(fā),這一特性旨在簡化并發(fā)任務(wù)的管理,提升多線程程序的可維護(hù)性和安全性,使其生命周期和控制流更加有序和明確,感興趣的可以了解一下
    2024-09-09
  • Java多線程環(huán)境下SimpleDateFormat類安全轉(zhuǎn)換

    Java多線程環(huán)境下SimpleDateFormat類安全轉(zhuǎn)換

    這篇文章主要介紹了Java多線程環(huán)境下SimpleDateFormat類安全轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • springboot整合Mybatis、JPA、Redis的示例代碼

    springboot整合Mybatis、JPA、Redis的示例代碼

    這篇文章主要介紹了springboot整合Mybatis、JPA、Redis的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Java ArrayList與Vector和LinkedList的使用及源碼分析

    Java 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-11
  • Spring Boot實(shí)戰(zhàn)之?dāng)?shù)據(jù)庫操作的示例代碼

    Spring Boot實(shí)戰(zhàn)之?dāng)?shù)據(jù)庫操作的示例代碼

    本篇文章主要介紹了Spring Boot實(shí)戰(zhàn)之?dāng)?shù)據(jù)庫操作的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-01-01
  • 談?wù)刯ava的concurrent用法

    談?wù)刯ava的concurrent用法

    這篇文章給大家介紹java的concurrent用法,感興趣的朋友一起學(xué)習(xí)吧
    2015-10-10
  • cmd使用javac和java及注意事項(xiàng)

    cmd使用javac和java及注意事項(xiàng)

    這篇文章主要介紹了cmd使用javac和java及注意事項(xiàng),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2021-12-12
  • dubbo如何設(shè)置連接zookeeper權(quán)限

    dubbo如何設(shè)置連接zookeeper權(quán)限

    這篇文章主要介紹了dubbo如何設(shè)置連接zookeeper權(quán)限問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05

最新評論