Mybatis-Plus 快速入門

一、why

不做重復(fù)的 CRUD 操作

問題1:EmployeeMapper 沒有寫 crud 方法,為什么在測試類中可以使用?

因為 EmployMapper 接口繼承 BaseMapper 接口 ,該接口定義了一系列 crud 方法

問題2:代碼不需要寫 crud sql 語句,那為什么可以進行 crud 數(shù)據(jù)操作?

因為 Mybatis-Plus 在項目啟動的時候執(zhí)行 sql 解析

  1. 獲取 BaseMapper 接口中指定的 Employee 泛型

  2. 解析泛型數(shù)據(jù),得到 employee 的字節(jié)碼對象

  3. 使用內(nèi)省方法解析 employee 字節(jié)碼對象,得到類和屬性名

  4. Mybatis-Plus 以類名作為表名,屬性名作為列名,進行 sql 拼接,最終得到對應(yīng) sql

二、what

MyBatis-Plus(簡稱 MP)是一個 MyBatis 的增強工具,在 MyBatis 的基礎(chǔ)上只做增強不做改變,為簡化開發(fā)、提高效率而生。

框架結(jié)構(gòu)

三、how

添加依賴

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
    </parent>

    <dependencies>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.17</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

Mysql 8 注意時區(qū)問題,配置文件的 url 加上 serverTimezone=UTC

application.properties

#mysql
spring.datasource.url=jdbc:mysql:///mybatis-plus_demo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
spring.datasource.username=admin
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

日志

application.properties 中有兩種配置 sql 打印日志方式

第一種:

logging.level.cn.jere.plus.mapper=debug

第二種:

# 推薦使用,會自動換行,看 sql 語句比較舒服
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

1、常用注解

@TableName

作用:指定當前實體類映射哪張數(shù)據(jù)庫表, 默認是跟實體類名一致

@TableName("t_employee")
public class Employee {
  //.....
}

@TableField

作用:指定當前屬性映射數(shù)據(jù)庫表哪一列, 默認是跟屬性名一致

@TableName("employee")
public class Employee {
    
    @TableField(value="eName",exist = false)
    private String name;
}

exist 屬性表示當前屬性是否映射數(shù)據(jù)庫列。實體類中若該屬性在數(shù)據(jù)庫沒有的對應(yīng)的列,要加exist=false

@TableId

作用:標記當前屬性映射表主鍵。

@TableName("employee")
public class Employee {
    @TableId(type = IdType.AUTO) // IdType.AUTO 數(shù)據(jù)庫ID自增
    private Long id;

IdType.ASSIGN_UUID 默認的 id 策略,使用雪花算法生成 long 類型的唯一 id(雪花算法用于分布式微服務(wù))

@Version

作用:用于標記樂觀鎖操作字段

2、通用 Mapper 接口

insert

/**
 * 插入一條記錄
 *
 * @param entity 實體對象
 */
int insert(T entity);

update

  1. updateById (要注意有沒有基本數(shù)據(jù)類型字段)

    使用場景:1. 條件是 id 是更新操作;2. 全量更新

// 需求: 將id=1用戶名字修改為jere
   @Test
   public void updateById() {
       Employee employee = new Employee();
       employee.setId(1L);
       employee.setName("jere");
       employeeMapper.updateById(employee);
   }

sql : UPDATE employee SET name=?, age=?, admin=? WHERE id=?

tips : updateById 在拼接 sql 時,把所有非 null 字段都進行 set 拼接

  1. update

    使用場景:1. 條件不僅僅是 id 更新場景(多條件);2. 部分字段更新

   @Test
   public void update() {
       UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
       wrapper.eq("id",1L);
       wrapper.set("name","jere24");
       employeeMapper.update(null,wrapper); // 
}

sql : UPDATE employee SET name=? WHERE (id = ?)

wrapper.條件 .set更新字段

delete

  1. deleteById(id)

    // 需求:刪除id=20的員工信息
    @Test
    public void deleteById() {
        employeeMapper.deleteById(20L); // DELETE FROM employee WHERE id=?
    }
    
  2. deleteBatchIds(idList)

    // 需求:刪除 id=20,id=21 的員工信息
    @Test
    public void deleteBatchIds() {
        employeeMapper.deleteBatchIds(Arrays.asList("20L","21L")); 
        // DELETE FROM employee WHERE id IN ( ? , ? )
    }
    
  3. deleteByMap(map)

    // 需求:刪除name=jere并且age=18的員工信息
    @Test
    public void testDeleteByMap() {
        HashMap<String,Object> map = new HashMap();
        map.put("name","jere");
        map.put("age",18);
        employeeMapper.deleteByMap(map); // DELETE FROM employee WHERE name = ? AND age = ?
    }
    
  4. delete(wrapper)

    //需求:刪除name=dafei并且age=18的員工信息
    @Test
    public void testDeleteWrapper() {
        UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
        wrapper.eq("name","dafei").eq("age",18);
        employeeMapper.delete(wrapper); // DELETE FROM employee WHERE (name = ? AND age = ?)
    }
    

select

  1. selectById(id)

  2. selectBatchIds(idList)

    // 需求:查詢id=1,id=2的員工信息
    @Test
    public void testSelectBatchIds(){
        employeeMapper.selectBatchIds(Arrays.asList(1L,2L)); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE id IN ( ? , ? )
    }
    
  3. selectByMap(map)

    // 需求: 查詢name=dafei, age=18的員工信息
    @Test
    public void testSelectByMap(){
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","dafei");
        map.put("age",18);
        employeeMapper.selectByMap(map); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE name = ? AND age = ?
    }
    
  4. selectCount(wrapper)

    // 需求: 查詢滿足條件的所有的員工個數(shù)
    @Test
    public void testSelectCount(){
        QueryWrapper<Employee> wrapper = new QueryWrapper();
        employeeMapper.selectCount(wrapper); // SELECT COUNT( 1 ) FROM employee
        employeeMapper.selectCount(null); // 查詢?nèi)?SELECT COUNT( 1 ) FROM employee 
    }
    
  1. selectList(wrapper)

    //需求: 查詢滿足條件的所有的員工信息, 返回List<Employee>
    @Test
    public void testSelectList(){
        QueryWrapper<Employee> wrapper = new QueryWrapper();
        employeeMapper.selectList(wrapper).forEach(System.err::println); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee
    }
    

問題:什么時候使用 selectList ? 什么時候使用 selectMaps ?

如果sql執(zhí)行完之后的列能封裝成實體對象,選用 selectList,如果不能則使用 selectMaps
  1. selectMaps(wrapper)

    用了 group by 返回的列沒辦法封裝到實體對象中,不能用selectList(它的返回值是泛型為實體類的List集合),所以只能用selectMaps

    可以看成:對象即 Map , Map 即對象

    //需求: 查詢滿足條件的所有的員工信息, 返回List<Map<String, Object>>  底層將每條數(shù)據(jù)封裝成HashMap
    @Test
    public void testSelectMap(){
        QueryWrapper<Employee> wrapper = new QueryWrapper();
        employeeMapper.selectMaps(wrapper);
    }
    
  1. selectPage(page, wrapper)

    // 需求:查詢第二頁員工數(shù)據(jù), 每頁顯示3條, (分頁返回的數(shù)據(jù)是實體對象)
    @Test
    public void testSelectPage(){
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        //參數(shù)1:當前頁, 參數(shù)2:每頁顯示條數(shù)
        Page<Employee> page = new Page<>(2, 3);
        employeeMapper.selectPage(page, wrapper); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee LIMIT ?,?
        System.out.println("當前頁:" + page.getCurrent());
        System.out.println("每頁顯示條數(shù):" + page.getSize());
        System.out.println("總頁數(shù):" + page.getPages());
        System.out.println("總數(shù):" + page.getTotal());
        System.out.println("當前頁數(shù)據(jù):" + page.getRecords());
    }
    
  1. selectOne(wrapper)【拓展】

    //需求: 查詢滿足條件的所有的員工, 取第一條
    @Test
    public void testSelectOne(){
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        Employee employee = employeeMapper.selectOne(wrapper); 
        // 查出結(jié)果條數(shù)大于1,則拋出異常 Expected one result (or null) to be returned by selectOne(), but found: 19
        System.out.println(employee);
    }
    
  1. selectObjs(wrapper)【拓展】

    //需求: 查詢滿足條件的所有的員工, 返回排在第一的列所有數(shù)據(jù), 沒特別指定, 一般返回時id
    @Test
    public void testSelectObjs(){
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.select("name");  //挑選返回的列   SELECT name FROM employee
        List<Object> list = employeeMapper.selectObjs(wrapper);
        list.forEach(System.out::println);
    }
    
  1. selectMapsPage(page, wrapper)【拓展】

     @Test
    public void testSelectMapsPage(){
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        //參數(shù)1:當前頁, 參數(shù)2:每頁顯示條數(shù)
        IPage<Map<String, Object>> page = new Page<>(2, 3);
        employeeMapper.selectMapsPage(page, wrapper);
        System.out.println("當前頁:" + page.getCurrent());
        System.out.println("每頁顯示條數(shù):" + page.getSize());
        System.out.println("總頁數(shù):" + page.getPages());
        System.out.println("總數(shù):" + page.getTotal());
        System.out.println("當前頁數(shù)據(jù):" + page.getRecords());
    }
    

3、條件構(gòu)造器

繼承體系

更新操作

UpdateWrapper 更新

 @Test
public void testUpdate2() {
    UpdateWrapper<Employee> wrapper = new UpdateWrapper();
    wrapper.eq("id", 1).set("name", "jere");
    employeeMapper.update(null, wrapper); // UPDATE employee SET name=? WHERE (id = ?)
}
 @Test
public void testUpdate2() {
    UpdateWrapper<Employee> wrapper = new UpdateWrapper();
    wrapper.eq("id", 1);
    wrapper.setSql("name='jere'");// sql 片段方式, 上面用 set 是占位符形式
    employeeMapper.update(null, wrapper); // UPDATE employee SET name='jere' WHERE (id = ?)
}

LambdaUpdateWrapper 更新

@Test
public void testUpdate3() {
    LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper();
    wrapper.eq(Employee::getId, 1L).set(Employee::getName,"Jere");
    employeeMapper.update(null, wrapper); //  UPDATE employee SET name=? WHERE (id = ?)
}

查詢操作

QueryWrapper 查詢

// 需求:查詢name=jere, age=18的用戶
@Test
public void testQuery1(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.eq("name", "jere").eq("age", 18);
    System.out.println(employeeMapper.selectList(wrapper));
}

LambdaQueryWrapper 查詢

// 需求:查詢name=dafei, age=18的用戶
@Test
public void testQuery3(){
    LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(Employee::getName, "dafei").eq(Employee::getAge, 18);
    System.out.println(employeeMapper.selectList(wrapper));
}

工具類 Wrappers

作用:用于創(chuàng)建各種類型的wrapper

@Test
public void testWrappers(){
    //update
    UpdateWrapper<Employee> updateWrapper1 = new UpdateWrapper<>();
    UpdateWrapper<Employee> updateWrapper2 = Wrappers.<Employee>update();

    LambdaUpdateWrapper<Employee> lambdaUpdateWrapper1 = new LambdaUpdateWrapper<>();
    LambdaUpdateWrapper<Employee> lambdaUpdateWrapper2 = Wrappers.<Employee>lambdaUpdate();
    //UpdateWrapper -->LambdaUpdateWrapper
    LambdaUpdateWrapper<Employee> lambdaUpdateWrapper3 = updateWrapper1.lambda();

    //select
    QueryWrapper<Employee> QueryWrapper1 = new QueryWrapper<>();
    QueryWrapper<Employee> QueryWrapper2 = Wrappers.<Employee>query();

    LambdaQueryWrapper<Employee> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
    LambdaQueryWrapper<Employee> lambdaQueryWrapper2 = Wrappers.<Employee>lambdaQuery();
    //QueryWrapper -->LambdaQueryWrapper
    LambdaQueryWrapper<Employee> lambdaQueryWrapper3 = QueryWrapper1.lambda();
}

4、高級查詢

列投影

select

// 需求:查詢所有員工, 返回員工name, age列
    @Test
    public void testQuery1() {
        QueryWrapper<Employee> wrapper = new QueryWrapper();
        wrapper.select("name,age"); // 用別名就封裝不到 employee 對象了
        List<Employee> employees = employeeMapper.selectList(wrapper);
        employees.forEach(System.err::println);
    }

排序

orderByAsc / orderByDesc

orderBy

// 需求:查詢所有員工信息按age正序排, 如果age一樣,按id正序排
    @Test
    public void testQuery2() {
        QueryWrapper<Employee> wrapper = new QueryWrapper();
        boolean flag = true;
        // 參數(shù)1:當前參數(shù)為 true 時,才執(zhí)行排序邏輯
//        wrapper.orderByDesc(flag,"age");
        // 參數(shù)1:是否排序開關(guān),true表示排序,false表示不排序
        // 參數(shù)2:是否正序排,true表示正序排,false表示倒序排
        // 參數(shù)3:排序的列
        wrapper.orderBy(flag, true, "age", "id"); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id ASC
        List<Employee> employees = employeeMapper.selectList(wrapper);
    }
// 需求:查詢所有員工信息按age正序排, 如果age一樣, 按id倒序排
    @Test
    public void testQuery3() {
        QueryWrapper<Employee> wrapper = new QueryWrapper();
        wrapper.orderByAsc("age").orderByDesc("id"); 
        // SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id DESC
        employeeMapper.selectList(wrapper);
    }

分組查詢

groupBy

having

// 需求: 以部門id進行分組查詢,查每個部門員工個數(shù)
@Test
public void testQuery4() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.select("dept_id,count(1)");
    wrapper.groupBy("dept_id");
    List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper); 
    // SELECT dept_id,count(1) FROM employee GROUP BY dept_id
}

group by 什么,則只能 select 什么,統(tǒng)計函數(shù)除外

// 需求: 以部門id進行分組查詢,查每個部門員工個數(shù),將大于3人的部門過濾出來
@Test
public void testQuery5() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.select("dept_id,count(1) count");
    wrapper.groupBy("dept_id").having("count(1)>3");
    List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper); 
    // SELECT dept_id,count(1) count FROM employee GROUP BY dept_id HAVING count(1)>3
}

條件查詢

1. 比較運算符

allEq / eq / ne

//需求:查詢name=dafei,age=18的員工信息
@Test
public void testQuery6() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.eq("name", "Jere").eq("age", 18);
    List<Employee> employeeList = employeeMapper.selectList(wrapper); 
    // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
}

鏈式編程返回的是自己,然后繼續(xù)執(zhí)行后面的

// 需求:查詢滿足條件員工信息,注意傳入的map條件中,包含a的列才參與條件查詢
@Test
public void testQuery7() {
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    Map<String, Object> map = new HashMap<>();
    map.put("name", "dafei");
    map.put("age", 18);
    wrapper.allEq((k, v) -> k.contains("a"), map);
    employeeMapper.selectList(wrapper); 
    //SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
}
//需求:查詢name !=dafei員工信息
@Test
public void testQuery8() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.ne("name", "Jere");
    List<Employee> employees = employeeMapper.selectList(wrapper);
}

gt / ge / lt / le

 // 需求:查詢 age 大于18歲員工信息
@Test
public void testQuery9() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.gt("age", 18);
    employeeMapper.selectList(wrapper);
}

between / notBetween

//需求:查詢年齡介于18~30歲的員工信息
@Test
public void testQuery10() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.between("age", 18, 30);
    employeeMapper.selectList(wrapper); 
    // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age BETWEEN ? AND ?)
}
//需求:查詢年齡小于18或者大于30歲的員工信息【用between實現(xiàn)】
@Test
public void testQuery11() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.notBetween("age", 18, 30);
    employeeMapper.selectList(wrapper); 
    // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age NOT BETWEEN ? AND ?)
}

isNull / isNotNull

 // 需求: 查詢dept_id 為null 員工信息
@Test
public void testQuery12() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.isNull("dept_id");
    employeeMapper.selectList(wrapper); 
    //SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (dept_id IS NULL)
}
// 需求: 查詢dept_id 為不為null 員工信息
@Test
public void testQuery13() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.isNotNull("dept_id");
    employeeMapper.selectList(wrapper); 
    //SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (dept_id IS NOT NULL)
}

in/notIn / inSql / notInSql

// 需求: 查詢id為1, 2 的員工信息
@Test
public void testQuery14() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.in("id", 1, 2);
    employeeMapper.selectList(wrapper); 
    // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id IN (?,?))
}
// 需求: 查詢id不為1, 2 的員工信息
@Test
public void testQuery15() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.notIn("id", 1, 2);
    employeeMapper.selectList(wrapper); 
    // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id NOT IN (?,?))
}
//需求: 查詢id為1, 2 的員工信息
@Test
public void testQuery16() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.inSql("id", "1,2");
    employeeMapper.selectList(wrapper);
    // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id IN (1,2))
}
//需求: 查詢id不為1, 2 的員工信息
@Test
public void testQuery17() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.notInSql("id", "1,2");
    employeeMapper.selectList(wrapper); // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id NOT IN (1,2))
}

exists / notExists【拓展】

 @Test
public void testQuery18() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.exists("select id from department where sn='cwb'");
    employeeMapper.selectList(wrapper);
    // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (EXISTS (select id from department where sn='cwb'))
}
2. 模糊查詢

like / notLike

//需求: 查詢name中含有fei字樣的員工
@Test
public void testQuery19() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.like("name", "fei");
    employeeMapper.selectList(wrapper); 
    // SELECT id,name,password,email,age,admin,dept_id FROM employee where (name LIKE '%fei%');
}
// 需求: 查詢name中不含有fei字樣的員工
@Test
public void testQuery20() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.notLike("name", "fei");
    employeeMapper.selectList(wrapper); 
    // SELECT id,name,password,email,age,admin,dept_id  FROM employee  WHERE (name NOT LIKE '%fei%');
}

likeLeft / likeRight

// 需求: 查詢name以fei結(jié)尾的員工信息
@Test
public void testQuery21() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.likeLeft("name", "fei");
    employeeMapper.selectList(wrapper); 
    // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE '%fei');
}
// 需求: 查詢姓王的員工信息
@Test
public void testQuery22() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.likeRight("name", "王");
    employeeMapper.selectList(wrapper); 
    // SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE '王%')
}
3. 邏輯運算符

or / and

注意:需要加括號的話在or / and(里面使用 lambda 表達式)

// 需求: 查詢age = 18 或者 name=Jere 或者 id =1 的用戶
@Test
public void testQuery24() {
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.eq("age",18);
    wrapper.or();
    wrapper.eq("name","Jere");
    wrapper.or();
    wrapper.eq("id",1);
    employeeMapper.selectList(wrapper); 
//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age = ? OR name = ? OR id = ?)
}
// 需求:查詢name含有re字樣的,或者 年齡在18到30之間的用戶
@Test
public void testQuery25() {
    /* QueryWrapper wrapper = new QueryWrapper();
        wrapper.like("name","re");
        wrapper.or();
        wrapper.between("age",18,30);
        employeeMapper.selectList(wrapper);*/
    QueryWrapper<Employee> wrapper = new QueryWrapper();
    wrapper.like("name","re");
    wrapper.or(wp->wp.ge("age",18).le("age",30));
    employeeMapper.selectList(wrapper);
    //SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ? OR (age >= ? AND age <= ?))
}

自定義SQL

  1. mapper.xml方式

    <!--單表-->
    <select id="listByXmlSingle" resultMap="BaseResultMap">
        select id, name, password, email, age, admin, dept_id
        from employee
    </select>
    
    <!--多表-->
    <select id="listByXmlJoin" resultMap="BaseResultMap">
        select e.*, d.id d_id, d.name d_name, d.sn d_sn from employee e left join department d on e.dept_id = d.id
    </select>
    
  1. 注解方式【拓展】

    @Select("select e.* from employee e")
    List<Employee> listByAnnoSingle();
    
    @Select("select e.*, d.id d_id, d.name d_name, d.sn d_sn from employee e left join department d on e.dept_id = d.id")
    @Results({
        @Result(column="d_id", property = "dept.id"),
        @Result(column="d_name", property = "dept.name"),
        @Result(column="d_sn", property = "dept.sn")
    })
    List<Employee> listByAnnoJoin();
    

5、通用 Service 接口

1. 定義

Mybatis-Plus 服務(wù)層接口定義

  1. 自定義一個接口繼承 IService 接口
  2. 明確指定操作實體對象的泛型
public interface IEmployeeService extends IService<Employee> {
    //....
}

Mybatis-Plus 服務(wù)層實現(xiàn)類定義

  1. 自定義一個類,繼承 ServiceImpl 類,同時實現(xiàn)自定義服務(wù)成接口
  2. 明確指定兩個泛型:第一個是操作實體類的 mapper 接口,第二個是操作的實體類
@Service
@Transactional
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements IEmployeeService {
    //....
}

2. 分頁

步驟1:在啟動類配置分頁插件

//分頁
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    PaginationInnerInterceptor paginationInnerInterceptor = new      PaginationInnerInterceptor(DbType.MYSQL);
    paginationInnerInterceptor.setOverflow(true); //合理化
    interceptor.addInnerInterceptor(paginationInnerInterceptor);
    return interceptor;
}

步驟2:編寫分頁代碼

@Getter
@Setter
public class QueryObject {
    private int currentPage = 2;// 當前頁
    private int pageSize = 3;// 每頁顯示條數(shù)
    private String keyword;// 關(guān)鍵字
}
//2>query(EmployeeQuery)方法定義
//3>query(EmployeeQuery)方法實現(xiàn)
@Override
public IPage<Employee> query(QueryObject qo) {
   IPage<Employee> page = new Page<>(qo.getCurrentPage(), qo.getPageSize()); //設(shè)置分頁信息
   QueryWrapper<Employee> wrapper = Wrappers.<Employee>query(); //拼接條件
   return super.page(page, wrapper);
}
//需求:查詢第2頁員工信息, 每頁顯示3條, 按id排序
@Test
public void testPage(){
    QueryObject qo = new QueryObject();
    qo.setPageSize(3);
    qo.setCurrentPage(2);
    IPage<Employee> page = employeeService.query(qo);
    System.out.println("當前頁:" + page.getCurrent());
    System.out.println("總頁數(shù):" + page.getPages());
    System.out.println("每頁顯示條數(shù):" + page.getSize());
    System.out.println("總記錄數(shù):" + page.getTotal());
    System.out.println("當前頁顯示記錄:" + page.getRecords());
}

3. 事務(wù)

貼 @Transactional 注解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容