MyBatis-plus&SpringBoot集成Mybatis-plus

连时铭
2023-12-01

MyBatis跟Mybatis-plus的区别

优点:

1>SQL语句自由控制,较为灵活

2>SQL与业务代码分离,易于阅读与维护

3>提供动态SQL语句,可以根据需求灵活控制

缺点:

1>简单的crud操作也必须提供对应SQL语句

2>必须维护大量的xml文件

3>自身功能有限,要拓展只能依赖第三方插件

MyBatis-plus 是在Mybatis的基础上进行二次开发的具有MyBatis所有功能, 也添加了不少好用的功能

Mybatis-plus是Mybatis的增强工具,在Mybatis的的基础上只有增强没有改变,为简化开发,还大大提高了工作的效率

建项目的时候需要配置依相关的依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.3</version>
</parent>
<dependencies>
	<--!MyBatis-plus依赖-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.0</version>
    </dependency>
    <--Druid依赖-->
    <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>
    <--SoringBoot项目的依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <--小辣椒lombok-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.16</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

普通的项目改造Springboot项目

创建好项目之后,创建启动类,对应的资源包放置静态资源跟模板,相关的依赖,还有properties文件等等

@SpringBootApplication
@MapperScan(basePackages = "cn.xxx.mp.mapper")
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class,args);
    }
}

测试类上面需要贴上SoringBootTest

创建实体类,创建Mapper文件,后面去继承BaseMapper里面的泛型就是你所对应的实体类,父类里面又很得方法

常见的几种注解

@TableName(“t_employee”)

描述:表名注解

作用:指定当前实体类映射哪张数据库表, 默认是跟实体类名一致,这个是你的数数据库的表名跟你的实体类的名字不一样的时候可以使用,贴在类的上面

@TableField(value=“employename”,exist = false)

这个注解是在你的数据库里面没有这个字段的时候,或者是你的数据库里面的列名字跟你的字段名字不一样的时候.,如果说这个字段是你自己新加的,可以直接省略括号里面的value直接去写后面的

描述:字段注解(非主键)

作用:指定当前属性映射数据库表哪一列, 默认是跟属性名一致

其中:exist属性表示当前属性是否映射数据库列

** @TableId(value=“id”, type=IdType.AUTO)

这个注解是用在表的主键上面

描述:主键注解

作用:标记当前属性映射表主键。

里面的value就是代表着你对应的主键列,简单来说就是在给id制定一个增长的规则

其中:type属性指定主键类型

IdType.AUTO

数据库ID自增

IdType.NONE

无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)

IdType.INPUT

insert前自行set主键值

IdType.ASSIGN_ID

分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)

IdType.ASSIGN_UUID

分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)

在Mapper接口使用之前需要考虑的问题是employeeMapper里面并没写传入的方法,是因为这个类继承了baseMapper里面封装了我们需要的方法\

项目中并没有定义SQL语句,为什么可以执行crud操作,mybatis-plus会自动帮我们拼接SQL语句,怎么去拼接的,把实体类的类名作为表名,字段作为表的列,通过java中的内省机制,然后通过解析获取对应的字段,如果自己定义的字段跟数据库的有所出入,就需要用到注解去解决问题

增加的方法

insert

/**
 * 插入一条记录
 *
 * @param entity 实体对象
 */
int insert(T entity);
@Test
public void ImsertTest() {
    Employee employee = new Employee();
    employee.setName("刘备");
    employee.setAge(24);
    employee.setDeptId(2L);
    employee.setAdmin(1);
    employee.setPassword("123123");
    employee.setEmail("123@123.com");
    employeeMapper.insert(employee);
}

更新的时候需要注意的有些地方:比如你在使用updateById操作更新的时候,如果有的数据没有更新到,然后你的实体类里面用的还是基本数据类型,这样就导致数据丢失,这时候可以改用包装类去修饰这些字段

update

  /**
     * 更新通过id
     * 这种方法建议在全部数据更改的时候使用
     */
    @Test
    public void updateById() {
        Employee employee = employeeMapper.selectById(1L);
        employee.setName("关羽");
        employeeMapper.updateById(employee);

    }
/**
     * update通过条件构造器,就是直接在SQL语句里面拼接上where
     * wrapper.eq()意思相当于SQL语句里面的where
     */
    @Test
    public void update() {
        UpdateWrapper<Employee> wrapper = new UpdateWrapper<Employee>();
        wrapper.eq("id", 1L);
//        wrapper.setSql("name='曹操'");
        wrapper.set("name", "曹操");
        employeeMapper.update(null, wrapper);
        //两种方式都可以看自己的个人爱好,但是每种方式都要去了解
          LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Employee::getId, 2L);
        wrapper.setSql("name='赵总'");
        employeeService.getOne(wrapper);
    }

delete

/**
 * 根据 ID 删除
 */
@Test
public void deleteById() {
    employeeMapper.deleteById(1327139013313564674L);
}

/**
 * 删除批处理id
 */
@Test
public void deleteBatchIds() {
    employeeMapper.deleteBatchIds(Arrays.asList(2L, 3L));
}

/**
 * 根据 columnMap 条件,删除记录
 * int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap)
 * 表字段 map 对象
 * 需求:删除name=dafei并且age=18的员工信息
 */
@Test
public void deleteByMap() {

    Map<String, Object> map = new HashMap<>();
    map.put("name", "关羽");
    map.put("age", 40);
    employeeMapper.deleteByMap(map);

}

/**
 * 根据 entity 条件,删除记录
 * <p>
 * 实体对象封装操作类(可以为 null)
 * int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
 * 需求:删除name=dafei并且age=18的员工信息
 */
@Test
public void delete() {
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.eq("name", "dafei").eq("age", 18);
    employeeMapper.delete(wrapper);
}

/**
 * 根据 ID 查询
 * <p>
 * 主键ID
 * T selectById(Serializable id);
 * 需求:查询id=1的员工信息
 */
@Test
public void selectById() {
    employeeMapper.selectById(2L);
}

select

  /**
     * 查询(根据 columnMap 条件)
     * <p>
     * 表字段 map 对象
     * List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
     * SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE name = ? AND age = ?
     * 需求: 查询name=dafei, age=18的员工信息
     */
    @Test
    public void selectByMap() {
        Map<String, Object> map = new HashMap<>();
        map.put("name", "钱总");
        map.put("age", 31);
        employeeMapper.selectByMap(map);
    }

    /**
     * 根据 Wrapper 条件,查询总记录数
     * <p>
     * 实体对象封装操作类(可以为 null)
     * Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
     * SELECT COUNT( 1 ) FROM employee
     * SELECT COUNT( 1 ) FROM employee WHERE (name LIKE ?)
     * 需求: 查询满足条件的所有的员工个数
     */
    @Test
    public void selectCount() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
//        wrapper.like("name","明");
        Integer integer = employeeMapper.selectCount(wrapper);
    }

    /**
     * 根据 entity 条件,查询全部记录
     * <p>
     * 实体对象封装操作类(可以为 null)
     * List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
     * SELECT id,name,password,email,age,admin,dept_id FROM employee
     * 需求: 查询满足条件的所有的员工信息, 返回
     */
    @Test
    public void selectList() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        employeeMapper.selectList(wrapper);
    }

    /**
     * 根据 Wrapper 条件,查询全部记录
     * <p>
     * 实体对象封装操作类(可以为 null)
     * List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
     * 需求: 查询满足条件的所有的员工信息, 返回List<Map<String, Object>>  底层将每条数据封装成HashMap
     * 这个方法跟上面的selectList区别就是map直接将数据封装成了对象
     * 这个方法适合在数据在无法自己封装成对象的时候使用
     */
    @Test
    public void selectMaps() {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        employeeMapper.selectMaps(wrapper);
    }

selectPage

/**
 * 根据 entity 条件,查询全部记录(并翻页)
 * <p>
 * 实体对象封装操作类(可以为 null)
 * <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
 * 需求:查询第二页员工数据, 每页显示3条, (分页返回的数据是实体对象)
 */
@Test
public void selectPage() {
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    Page<Employee> page = new Page<>(2, 3);
    employeeMapper.selectPage(page, wrapper);
}

selectOne

/**
 * 根据 entity 条件,查询一条记录
 * <p>
 * 实体对象封装操作类(可以为 null)
 * T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
 * 需求: 查询满足条件的所有的员工, 取第一条
 */
@Test
public void selectOne() {
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.eq("name", "赵总");
    employeeMapper.selectOne(wrapper);
}

selectObjs

/**
 * 根据 Wrapper 条件,查询全部记录
 * <p>注意: 只返回第一个字段的值</p>
 * <p>
 * 实体对象封装操作类(可以为 null)
 * List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
 * 需求: 查询满足条件的所有的员工, 返回排在第一的列所有数据, 没特别指定, 一般返回时id
 */
@Test
public void selectObjs() {
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.select("name");
    List<Object> list = employeeMapper.selectObjs(wrapper);
    list.forEach(System.out ::println);
}

高级查询

列投影

就是打印指定的列

/**
 * //参数:指定查询后返回的列
 * select(String... sqlSelect)
 * //参数:Predicate 函数, 满足指定判定逻辑列才返回
 * //要求:wrapper.setEntity(employee);
 * select(Predicate<TableFieldInfo> predicate)
 * //参数1:通过实体属性映射表中列
 * //参数2:Predicate 函数, 满足指定判定逻辑列才返回
 * select(Class<T> entityClass, Predicate<TableFieldInfo> predicate)
 * SELECT name,age FROM employee
 * 需求:查询所有员工, 返回员工name, age列
 */
@Test
public void select1(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.select("name","age");
    employeeMapper.selectList(wrapper);
}

排序

排序里面需要注意的是排序的条件不能颠倒,那个在前写的时候就是哪个在前

好多的方法里面有三个参数,第一份参数是Boolean类型的,这个表示的是一个开关,默认是TRUE,或者默认是当前的操作,如果填上FALSE就会变为相反的操作

/**
 * orderByAsc: 正序排序
 * 等价SQL: select ..from table   ORDER BY 字段, ... ASC
 * wrapper方法:
 * orderByAsc(R... columns)
 * orderByAsc(boolean condition, R... columns)
 * 示例:
 * orderByAsc("id", "name")--->order by id ASC,name ASC
 * SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id ASC
 * SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id DESC
 * 需求:查询所有员工信息按age正序排, 如果age一样, 按id正序排
 */
@Test
public void orderByAsc(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.orderByAsc("age");
    wrapper.orderByDesc("id");
    employeeMapper.selectList(wrapper);
}
/**
 * orderBy:定制排序
 * 等价SQL: select ..from table   ORDER BY 字段,
 * //参数1:控制是否进行排序
 * //参数2:控制是不是正序
 * orderBy(boolean condition, boolean isAsc, R... columns)
 * 排序:ORDER BY 字段, ...
 * 例: orderBy(true, true, "id", "name")--->order by id ASC,name ASC
 * 需求:查询所有员工信息按age正序排, 如果age一样, 按id正序排
 */
@Test
public void orderBy(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.orderBy(true,true,"name","id");
    employeeMapper.selectList(wrapper);
}

分组Groupby

/**
 * groupBy : 分组:GROUP BY 字段, ...
 * groupBy(R... columns)
 * groupBy(boolean condition, R... columns)
 * 例: groupBy("id", "name")--->group by id,name
 * 需求: 以部门id进行分组查询,查每个部门员工个数
 */
@Test
public void groupBy(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.groupBy("dept_id");
    wrapper.select("dept_id","count(id) count");
    employeeMapper.selectList(wrapper);
}

Having

/**
 * having : HAVING ( sql语句 )
 * having(String sqlHaving, Object... params)
 * having(boolean condition, String sqlHaving, Object... params)
 * 例: having("sum(age) > 10")--->having sum(age) > 10
 * 例: having("sum(age) > {0}", 11)--->having sum(age) > 11
 * 需求: 以部门id进行分组查询,查每个部门员工个数, 将大于3人的部门过滤出来
 */
@Test
public void having(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.groupBy("dept_id");
    wrapper.select("dept_id","count(id) count").having("count>3");
    employeeMapper.selectList(wrapper);
}

allEq/eq/ne

/**
 * allEq : 全等匹配
 * wrapper方法:
 * allEq(Map<R, V> params)
 * allEq(Map<R, V> params, boolean null2IsNull)
 * allEq(boolean condition, Map<R, V> params, boolean null2IsNull)
 * params : key为数据库字段名,value为字段值
 * null2IsNull : 为true则在map的value为null时调用 isNull 方法,为false时则忽略value为null的
 *SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
 * 需求:查询name=dafei, age=18的员工信息
 */
@Test
public void allEq(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    Map<String, Object> map = new HashMap<>();
    map.put("name", "赵总");
    map.put("age", 35);
    map.put("dept_id", null);
    wrapper.allEq(map,false);
    employeeMapper.selectList(wrapper);
}
/**
 * eq:单个参数判断是否相等
 * eq(R column, Object val)
 * eq(boolean condition, R column, Object val)
 * 等于 =
 * 例: eq("name", "老王")--->name = '老王'
 * 需求:查询name=dafei员工信息
 */
@Test
public void eq(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.eq("name","赵总");
    employeeMapper.selectList(wrapper);

}
/**
 *ne: 不等于
 * ne(R column, Object val)
 * ne(boolean condition, R column, Object val)
 * 不等于 <>
 * 例: ne("name", "老王")--->name <> '老王'
 * 需求:查询name !=dafei员工信息
 */
@Test
public void ne(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.ne("name","赵总");
    employeeMapper.selectList(wrapper);
}

get/gl/lt/le

gt是大于但是不包含 lt小于不包含

ge是大于并且包含 le小于包含

/**
 * gt : 大于 >
 * gt(R column, Object val)
 * gt(boolean condition, R column, Object val)
 * 参数一就是相当于开关,参数二相当于表的列,参数三就是你自己想设置的值
 * 例: gt("age", 18)--->age > 18
 * ge:大于等于 >=
 * ge(R column, Object val)
 * ge(boolean condition, R column, Object val)
 * lt:小于 <
 * lt(R column, Object val)
 * lt(boolean condition, R column, Object val)
 * 例: lt("age", 18)--->age < 18
 * le:小于 <
 * le(R column, Object val)
 * le(boolean condition, R column, Object val)
 * 例: le("age", 18)--->age < 18
 * SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age > ? AND age < ?)
 * 需求:查询age 大于18岁员工信息
 */
@Test
public void gt(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.gt("age",25).lt("age",50);
    employeeMapper.selectList(wrapper);
}

between/notBetween

/**
 * between : BETWEEN 值1 AND 值2
 * between(R column, Object val1, Object val2)
 * between(boolean condition, R column, Object val1, Object val2)
 * 例: between("age", 18, 30)--->age between 18 and 30
 * SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age  BETWEEN ? AND ?)
 * 需求:查询年龄介于18~30岁的员工信息
 */
@Test
public void between(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.between("age",25,25);
    employeeMapper.selectList(wrapper);
}
/**
     * notBetween : NOT BETWEEN 值1 AND 值2
     * notBetween(R column, Object val1, Object val2)
     * notBetween(boolean condition, R column, Object val1, Object val2)
     * 例: notBetween("age", 18, 30)--->age not between 18 and 30
     * SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age NOT BETWEEN ? AND ?)
     * 需求:查询年龄小于18或者大于30岁的员工信息【用between实现
     */
    @Test
    public void notBetween(){
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.notBetween("age",25,25);
        employeeMapper.selectList(wrapper);
    }

isnull/isnotnull

/**
 * isNull :  字段 IS NULL
 * isNull(R column)
 * isNull(boolean condition, R column)
 * 例: isNull("name")--->name is null
 * 需求: 查询dept_id 为null 员工信息
 */
@Test
public void isNull(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.isNull("dept_id");
    employeeMapper.selectList(wrapper);
}
/**
 * isNotNull :  字段 IS NOT NULL
 * isNotNull(R column)
 * isNotNull(boolean condition, R column)
 * 例: isNotNull("name")--->name is not null
 * 需求: 查询dept_id 为不为null 员工信息
 */
@Test
public void isNotNull(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.isNotNull("dept_id");
    employeeMapper.selectList(wrapper);
}

in/notin

/**
 * in : 字段 IN (value1, value2, ...)
 * in(R column, Collection<?> value)
 * in(boolean condition, R column, Collection<?> value)
 * 例: in("age",{1,2,3})--->age in (1,2,3)
 * 需求: 查询id为1, 2 的员工信息
 */
@Test
public void in(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    ArrayList<Long> list = new ArrayList<>();
    list.add(1L);
    list.add(2L);
    wrapper.in("id",list);
    employeeMapper.selectList(wrapper);
}
/**
 * notIn : 字段 NOT IN  (value1, value2, ...)
 * notIn(R column, Object... values)
 * notIn(boolean condition, R column, Object... values)
 * 例: notIn("age",{1,2,3})--->age not in (1,2,3)
 * 需求: 查询id不为1, 2 的员工信息
 */
@Test
public void notIn(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    ArrayList<Long> list = new ArrayList<>();
    list.add(1L);
    list.add(2L);
    wrapper.notIn("id",list);
    employeeMapper.selectList(wrapper);
}

inSQL/notInSQL

用法跟in的区别不大,只是在写条件的时候用法可能会有不一样的地方

wrapper.inSql(“id”,“1,2”);这个在用的时候可以直接使用SQL片段拼接,直接一个字符串写出所有的条件,然后可以自动解析

/**
 * inSql : 字段 IN ( sql语句 )
 * inSql(R column, String inValue)
 * inSql(boolean condition, R column, String inValue)
 * 例: inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6)
 * 例: inSql("id", "select id from table where id < 3")--->id in (select id from table where id < 3)
 * 需求: 查询id为1, 2 的员工信息
 */
@Test
public void inSql(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    ArrayList<Long> list = new ArrayList<>();
    list.add(1L);
    list.add(2L);
    wrapper.inSql("id","1,2");
    employeeMapper.selectList(wrapper);
}
/**
 * notInSql : 字段 NOT  IN ( sql语句 )
 * notInSql(R column, String inValue)
 * notInSql(boolean condition, R column, String inValue)
 * 例: notInSql("age", "1,2,3,4,5,6")--->age not in (1,2,3,4,5,6)
 * 例: notInSql("id", "select id from table where id < 3")--->id not in (select id from table where id < 3)
 * 需求: 查询id不为1, 2 的员工信息
 */
@Test
public void notInSql(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    ArrayList<Long> list = new ArrayList<>();
    list.add(1L);
    list.add(2L);
    wrapper.notInSql("id","1,2");
    employeeMapper.selectList(wrapper);
}

like/notlike/likeleft.likeRight

like在那边%相对于就会在哪边

/**
 * like: LIKE '%值%'
 * like(R column, Object val)
 * like(boolean condition, R column, Object val)
 * 例: like("name", "王")--->name like '%王%'
 * 需求: 查询name中含有fei字样的员工
 */
@Test
public void like(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.like("name","总");
    employeeMapper.selectList(wrapper);
}
/**
 * notLike : NOT LIKE '%值%'
 * notLike(R column, Object val)
 * notLike(boolean condition, R column, Object val)
 * 例: notLike("name", "王")--->name not like '%王%'
 * 需求: 查询name中不含有fei字样的员工
 */
@Test
public void notLike(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.notLike("name","总");
    employeeMapper.selectList(wrapper);
}
/**
 * likeLeft : LIKE '%值'
 * likeLeft(R column, Object val)
 * likeLeft(boolean condition, R column, Object val)
 * 例: likeLeft("name", "王")--->name like '%王'
 * SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ?)
 * ==> Parameters: %总(String)
 * 需求: 查询name以fei结尾的员工信息
 */
@Test
public void likeLeft(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.likeLeft("name","总");
    employeeMapper.selectList(wrapper);
}
/**
 * likeRight : LIKE '值%'
 * likeRight(R column, Object val)
 * likeRight(boolean condition, R column, Object val)
 * 例: likeRight("name", "王")--->name like '王%'
 * 需求: 查询姓王的员工信息
 */
@Test
public void likeRight(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.likeRight("name","王");
    employeeMapper.selectList(wrapper);
}

or/and

/**
 * or : 拼接 OR
 * or()
 * or(boolean condition)
 * 例: eq("id",1).or().eq("name","老王")--->id = 1 or name = '老王'
 * 注意事项:
 * 主动调用or表示紧接着下一个方法不是用and连接!(不调用or则默认为使用and连接)
 * 需求: 查询age = 18 或者 name=dafei 或者 id =1 的用户
 */
@Test
public void or(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.eq("name","赵总").or().eq("age",18).or().eq("id",2L);
    employeeMapper.selectList(wrapper);
}
/**
 * 嵌套OR:
 * or(Consumer<Param> consumer)
 * or(boolean condition, Consumer<Param> consumer)
 * 例: or(i -> i.eq("name", "李白").ne("status", "活着"))--->or (name = '李白' and status <> '活着')
 * 需求:查询name含有fei字样的,或者 年龄在18到30之间的用户
 * SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ? OR (age BETWEEN ? AND ?))
 */
@Test
public void or2(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.like("name","总").or(employeeQueryWrapper -> employeeQueryWrapper.between("age",18,30));
    employeeMapper.selectList(wrapper);
}
/**
 * 嵌套and:
 * and(Consumer<Param> consumer)
 * and(boolean condition, Consumer<Param> consumer)
 * SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ? AND (age < ? OR age >= ?))
 * 需求:查询name含有fei字样的并且 年龄在小于18或者大于30的用户
 */
@Test
public void and(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.like("name","总").and(employeeQueryWrapper -> employeeQueryWrapper.lt("age",18).or().ge("age",30));
    employeeMapper.selectList(wrapper);
}

对应的还有就是单表查询跟多表联查,这种用以前的Mapper写比较方便,用MP写的话就会很麻烦

MP单表查询

@Select("select e.* from employee e")
List<Employee> listByAnnoSingle();

MP多表查询

@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();

service接口的使用

在传统的接口上面去去继承IService

public interface IEmployeeService extends IService<Employee> {

}

对应实现类还需要继承ServiceImpl<M,T>,里面的M跟T分别表示的是Mapper类跟实体类

public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper,Employee> implements IEmployeeService {}

写好之后就可以直接调用里面封装的方法,里面对应的也会有CRUD方法

分页

public interface IEmployeeService extends IService<Employee> {
    Page<Employee> queryPage(EmployeeQueryObject qo);

}
@Service
@Transactional
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper,Employee> implements IEmployeeService {
    @Override
    public Page<Employee> queryPage(EmployeeQueryObject qo) {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        //利用Page得到需要用到的分页数据
        Page<Employee> page = new Page<>(qo.getCurrentPage(), qo.getPageSize());
        //这个地方相当于条件的搜索
        wrapper.like(StringUtils.hasText(qo.getKeyword()),"name",qo.getKeyword());
        //super意思就是继承了父类的方法
        EmployeeServiceImpl.super.page(page);
        return super.page(page,wrapper);
    }
}
 类似资料: