mybatis-plus

2023-11-07

mybatis-plus的sql拼接规则:

  1. 实体对象参数属性有值,那么该属性名会拼接sql语句中
  2. 实体对象参数属性为基本属性时,会有默认值,mybatis-plus认为是有值,参与sql拼接

mybatis-plus与mybatis的对比

  1. mybatis的sql语句全要开发者自己去手写,而mybatis-plus则不需要

  2. mybatis不支持lambda形式调用,而mybatis-plus可以

  3. mybatis-plus能自动的去映射实体类转为mybatis内部对象注入容器中

mybatis-plus缺点与优点:

优点:

  1. 不需要手动的去写sql语句
  2. 依赖小,减少开发成本,提高开发效率
  3. 内置分页插件与全局插件

缺点:

  1. 当项目比较大的时候,对手动的去写sql语句比较困难,尤其是多表联动的时候,效率就比较低
  2. 当你的实体类的字段与你的数据库的属性不匹配或实体类的字段多于数据库的属性时会出现sql语法异常

mybatis-plus原理

在baseMapper接口中注入大量的接口,每个接口对应着不同的crud操作之外还有对内置分页操作

/*
BaseMapper的所有方法(deleteById、delete、insert、select、update等)都继承了该抽象方法都继承AbstractMethod.addMappedStatement的抽象方法,源码中根据不同的方法继承AbstractMethod实现了不同的实现类,并且实现了injectMappedStatement方法,sqlSource也是在这个地方被添加进配置文件,在AbstractMethod类下你会发现其实是调用了inject方法下的injectMappedStatement方法实现了sql自动注入

mybatis-plus依赖

<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>

日志使用

mybatis使用的日志格式是

logging.level.cn.wolfcode.mp.mapper=debug

而mybatis-plus使用的日志格式是

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

这两者是有区别的,一个使用mybatis内置得日志,在springboot中输出在信息初始化列中,不方便看。mybatis-plus是直接输出在控制台中,方便看

mybatis-plus常用注解

@TableName:作用:指定当前实体类映射哪张数据库表, 默认是跟实体类名一致。用在domain类上,指定匹配表名。缺省时默认匹配同名表名,如果找不到同名表名则报错。

@TableName("employee")
public class Employee {
}

@TableField:标记当前属性映射表主键。用于javabean的字段上,指定匹配列名。缺省时默认匹配对应表的同名列名,如果找不到同名列则报错,指定属性exist=false,用于定义不能匹配的对应表中的列的字段,关联表时常用,默认为true

@TableField(value = "dept_id")    
private Long deptId;
@TableField(exist = false) //exist属性表示当前属性是否映射数据库列	
private List<Department> departments;

@TableId:用于javabean对应表的主键的字段上,缺省时使用表中主键id自增的雪花算法,可指定属性type=IdType.算法枚举变量,默认的是雪花算法,如果不想要雪花算法想自增则用type=IdType.AUTO

@TableId(value = "id",type = IdType.AUTO) //通知表这是id字段,并且不进行雪花算法
private Long 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方法)

@Version

描述:乐观锁注解、标记 @Verison 在字段上

作用:用于标记乐观锁操作字段

父类:AbstractWrapper共有的条件方法且常用的

1. allEq: 把 list 中的全部条件进行 and 比较,查询出符合要求的数据
2. eq:查询等于该条件的数据,后面可以使用多个 eq ,使用 and 拼接。
3. ne:查询不等于该条件的数据。
4. gt:大于该条件的数据
5. ge:大于或等于该条件的数据
6. lt:小于该条件的数据
7. le:小于或等于该条件的数据
8. between:取在 **betwenn** 中间的数据
9. notBetWeen:取不在 **betwenn** 中间的数据
10. isNull:取等于null的数据、
11. in:取等于 in 中所有的数据
12. notIn:取不等于 in 中所有的数据
13. inSql:取等于 in 中所有的数据,字符串拼接进去的
14. notinSql:取不等等于 in 中所有的数据,字符串拼接进去的
//模糊查询    
1. like:查询某列中能匹配到该条件的数据
2. notList:查询某列中能不匹配到该条件的数据
3. likeLeft:查询某列中能在第一个字母开始,匹配到该条件的数据
4. likeRight:查询某列中能在最后一个字母开始,匹配到该条件的数据
/*
updateWarpper方法中多了set方法进行数据库中的列的属性值修改
*/

mybatis-plus特性:

/*无侵入*/:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
/*损耗小*/:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
/*强大的 CRUD 操作*/:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
/*支持 Lambda 形式调用*/:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
/*支持主键自动生成*/:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
/*支持 ActiveRecord 模式*/:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
/*支持自定义全局通用操作*/:支持全局通用方法注入( Write once, use anywhere )
/*内置代码生成器*/:采用代码或者 Maven 插件可快速生成 MapperModelServiceController 层代码,支持模板引擎,更有超多自定义配置等您来使用
/*内置分页插件*/:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
/*分页插件支持多种数据库*/:支持 MySQLMariaDBOracle、DB2、H2、HSQL、SQLitePostgreSQLServer 等多种数据库
/*内置性能分析插件*/:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
/*内置全局拦截插件*/:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

什么时候用到updateById与update

updateById:通过

  1. 如果更新条件是id而且全部列都要更新则使用updateById

    //需求把1L的name改为小苏
    //解决办法一:把int类型改为包装类型的Integer再进行updateById操作进行更新
    //UPDATE employee_copy SET name=?, age=?, admin=? WHERE id=?
    //---------------------------//
    //解决办法二:先查找要改实体类的字段改变属性值再更新
    //SELECT id,name,password,email,age,admin,dept_id FROM employee_copy WHERE id=?
    //UPDATE employee_copy SET name=?, password=?, email=?, age=?, admin=?, dept_id=? WHERE id=?
    Employee employee = employeeMapper.selectById(1L);
    employee.setName("小天");
    employeeMapper.updateById(employee);
    
  2. 如果更新条件不仅是限于id,还要进行部分表中的属性列更新,则使用update

//解决办法三:用update方法进行局部sql更新 ,返回值为int
//eq:表示等于
//set:要设置的值
//UPDATE employee_copy SET name=? WHERE (id = ?)
UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
wrapper.eq("id",2L);
wrapper.set("name","xiaowu");
employeeMapper.update(null,wrapper);

mybatis-plus提供删除api

deleteById(id): 接收的值是一个序列化,表示无论是long类型还是int类型都能进行接收

根据id进行删除

//DELETE FROM employee_copy WHERE id=?
employeeMapper.deleteById(1L);

deleteBatchIds(List集合):接收的值是一个序列化集合,表示可以进行多个值操作

//DELETE FROM employee_copy WHERE id IN ( ? , ? , ? )
employeeMapper.deleteBatchIds(Arrays.asList(1L,2L,3L));

deleteMap(map); map中的k相当于表中的属性,v相当于表中的值,进行条件过滤
根据map传递的k和v的值进行条件删除

//DELETE FROM employee_copy WHERE dept_id = ? AND age = ?
HashMap<String,Object> map = new HashMap<>();
map.put("age",25);
map.put("dept_id",2);
employeeMapper.deleteByMap(map);

delete:根据wrapper提供的column和val进行条件过滤删除

//DELETE FROM employee WHERE (age = ? AND name = ?)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("age",0);
wrapper.eq("name","xiaofei");
employeeMapper.delete(wrapper);

myabtis-plus提供的查询api:

select:指定返回的列

selectById:根据id进行查询,返回值为object

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE id=?
Employee employee = employeeMapper.selectById(1L);
System.out.println(employee);

selectBatchIds:根据List集合储存的1个或多个id进行条件查询,返回值为List集合对象

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE id IN ( ? , ? , ? , ? )       
List<Employee> employees = employeeMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L, 4L));
employees.forEach(System.out::println);

selectMap:根据map集合的k键值对应表中列的属性值表示作为条件,v作为要进行过滤的属性值,返回为List集合对象

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE name = ? AND age = ?
HashMap<String,Object> map = new HashMap<>();
map.put("name","admin");
map.put("age","40");
List<Employee> employees = employeeMapper.selectByMap(map);
employees.forEach(System.out::println);

selectCount:根据wrapper提供的column和val进行条件过滤进行查询,返回值为Integer

//SELECT COUNT( 1 ) FROM employee WHERE (age = ?) 如果没有条件则统计全部结果
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("age",40); //判断条件age等于40进行过滤
Integer integer = employeeMapper.selectCount(wrapper);
System.out.println(integer);

selectList:根据wrapper提供的column和val进行条件过滤进行查询,返回值为List集合对象

//SELECT id,name,password,email,age,admin,dept_id FROM employee (没有条件下)
//SELECT COUNT( 1 ) FROM employee WHERE (age = ?)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("age",40);
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.out::println);

selectPage:根据page的current当前页与size每页显示条数两个字段和wrapper提供的column和val进行条件过滤进行查询,返回值为List集合对象

//SELECT id,name,password,email,age,admin,dept_id FROM employee LIMIT ?,?
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
Page page = new Page<>();
page.setCurrent(2);
page.setSize(3);
Page<Employee> employeePage = employeeMapper.selectPage(page, wrapper);
System.out.println("当前页:" + employeePage.getCurrent());
System.out.println("每页显示条数:" + employeePage.getSize());
System.out.println("总页数:" + employeePage.getPages());
System.out.println("总数:" + employeePage.getTotal());
System.out.println("当前页数据:" + employeePage.getRecords());

selectMapsPage:通过IPage<Map<String,Object>>进行分页筛选过滤,根据wrapper提供的column和val进行条件过滤进行查询,返回值为List集合对象

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ?) LIMIT ?
EmployeeQuery qo = new EmployeeQuery();
IPage<Map<String,Object>> page = new Page<>(qo.getCurrentPage(),qo.getPageSize());
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
qo.setKeyWord("明"); //过滤条件

wrapper.like("name",qo.getKeyWord());

IPage<Map<String, Object>> mapIPage = employeeMapper.selectMapsPage(page, wrapper);
System.out.println("当前页:" + mapIPage.getCurrent());
System.out.println("每页显示条数:" + mapIPage.getSize());
System.out.println("总页数:" + mapIPage.getPages());
System.out.println("总数:" + mapIPage.getTotal());
System.out.println("当前页数据:" + mapIPage.getRecords());

selectOne:需要自己手动的去给wrapper一个条件否则会报mybatis方法异常,预期是一个对象结果是多个对象的异常,根据wrapper提供的column和val进行条件过滤进行查询,返回值为实体类对象,底层用的还是selectList

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id = ?)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("id",1L);
Employee employee = employeeMapper.selectOne(wrapper);
System.out.println(employee);

selectObject:根据wrapper提供的column和val进行条件过滤进行查询,返回值为实体类List集合的Object对象,打印的是id值

//SELECT id,name,password,email,age,admin,dept_id FROM employee
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.like("name","明");
List<Object> objects = employeeMapper.selectObjs(wrapper);
objects.forEach(System.err::println);

select用法

需求:查询所有员工, 返回员工name, age列

根据wrapper提供的column和val进行条件过滤进行selectList方法查询,返回值为实体类List集合对象

QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.select("name,age");
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.err::println);

orderByASC与orderByDesc还有orderBy用法

orderByASC为升序

orderByDesc为降序

orderBy:第一个参数是否拼接sql,第二个参数是否为升序,第三个参数则是排序表中的列属性

需求:查询所有员工信息按age正序排, 如果age一样, 按id正序排

//SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age,id ASC
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
// wrapper.orderBy(true,true,"age,id");
wrapper.orderByAsc("age").orderByAsc("id");
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.err::println);

需求:查询所有员工信息按age正序排, 如果age一样, 按id倒序排

//SELECT id,name,password,email,age,admin,dept_id FROM employee ORDER BY age ASC,id DESC
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("age").orderByDesc("id");
List<Employee> employees = employeeMapper.selectList(wrapper);
employees.forEach(System.err::println);

groupBy用法

指定要分组的表中的列属性,配合select一起使用

select:第一个参数为表中的列属性,第二个参数为要查询的列

需求:以部门id进行分组查询,查每个部门员工个数, 将大于3人的部门过滤出来

//SELECT dept_id,count(id) count FROM employee GROUP BY dept_id HAVING count > 3
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.groupBy("dept_id").having("count > 3").select("dept_id","count(id) count");
List<Map<String,Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

eq、ne、allEq用法

eq:对应的列只能是这个属性值才能查询到

需求:查询name=dafei, age=18的员工信息

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("name","defei").eq("age",18);
maps.forEach(System.err::println);

allEq:根据map提供的k和v进行表中列的属性值条件过滤,一次性包含处理多个条件

需求:查询name=dafei, age=18的员工信息

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
HashMap<String, Object> map = new HashMap<>();
map.put("name","dafei");
map.put("age",18);
wrapper.allEq(map);
List<Map<String,Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

ne:对应的列只能要不是这个属性值即可查询到

需求:查询name !=dafei员工信息

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name <> ?)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.ne("name","dafei");
List<Map<String,Object>> map2 = employeeMapper.selectMaps(wrapper);
map2.forEach(System.err::println);

gt、lt、ge、le用法

gt:大于这个表中对应列的属性值

lt:小于这个表中对应列的属性值

ge:大于等于这个表中对应列的属性值

le:小于等于这个表中对应列的属性值

需求:查询age 大于18岁员工信息

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age > ?)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.gt("age",18);
List<Map<String,Object>> map2 = employeeMapper.selectMaps(wrapper);
map2.forEach(System.err::println);
//--------------------------------------------
//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age < ?)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.lt("age",18);
List<Map<String,Object>> map2 = employeeMapper.selectMaps(wrapper);
map2.forEach(System.err::println);

wrapper中默认是and拼接,如果需要用到or则在or里面进行条件过滤

需求:查询年龄介于18~30岁的员工信息

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age >= ? AND age <= ?)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.ge("age",18).le("age",30);
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

需求:查询年龄小于18或者大于30岁的员工信息

or:进行或条件的过滤,一个or执行一个过滤条件

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age <= ? OR (age >= ?))
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.le("age",18).or(wr->wr.ge("age",30));
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

between与notBetween用法

需求:查询年龄小于18或者大于30岁的员工信息

notBetween:表示不存在这个范围之内的都能进行查询

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age NOT BETWEEN ? AND ?)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.notBetween(true,"age","18","30");
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

需求:查询年龄大于18~30岁之间的员工信息

between:表示只能查询到存在这个范围之内的值

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age BETWEEN ? AND ?)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.between(true,"age","18","30");
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

isNull与isNotNull用法

需求: 查询dept_id 为null 员工信息

isNull:查询表中该列的属性值为null条件的数据

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (dept_id IS NULL)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.isNull("dept_id");
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

需求: 查询dept_id 为null 员工信息

isNotNull:查询表中该列的属性值不为null条件的数据

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (dept_id IS NOT NULL)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.isNotNull("dept_id");
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

inSql、notSql、in、notIn用法

inSql与notSql都是直接去占位,而in与notIn则是先用占位符占了位置再去赋值

需求: 查询id为1, 2 的员工信息

//用inSql查询
//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id IN (1,2))
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.inSql("id","1,2");
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);
//----------------
//用in查询
//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (dept_id IN (?,?))
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.in("id",Arrays.asList(1L,2L));
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

需求: 查询id不为1, 2 的员工信息

//用notSql查询
//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id NOT IN (1,2))
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.notInSql(true,"id","1,2");
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);
//----------------
//用notIn查询
//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (id NOT IN (?,?))
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.notIn("id",Arrays.asList(1L,2L));
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

like、notLike、likeLeft、likeRight用法

需求: 查询name中含有fei字样的员工

like:进行模糊查询,主要表中的列下的属性值存在xxx字样就行

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ?)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.like("name","fei");
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

需求: 查询name中不含有fei字样的员工

notLike:进行模糊查询,主要表中的列下的属性值不存在xxx字样就行

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name NOT LIKE ?)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.notLike("name","fei");
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

需求: 查询姓王的员工信息

likeRight:进行模糊查询,主要表中的列下的属性值存在以xxx字样开头就行

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ?)
//王%(String)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.likeRight("name","王");
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

需求: 查询以王结尾的员工信息

likeLeft:进行模糊查询,主要表中的列下的属性值存在以xxx字样结尾就行

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ?)
//%王(String)
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.likeLeft("name","王");
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

or与and用法

or:在wrapper中进行或条件的过滤,一个or执行一个或过滤条件但可以拼接多个进行多个或过滤条件

and:在wrapper中进行或条件的过滤,一个and执行一个且过滤条件但可以拼接多个and进行多个且过滤条件

需求: 查询age = 18 或者 name=dafei 或者 id =1 的用户

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age = ? OR (name = ? OR (id = ?)))
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.eq("age","18").or(wr->wr.eq("name","dafei").or(w->w.eq("id",1)));
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

需求:查询name含有fei字样的,或者 年龄在18到30之间的用户

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ? OR (age >= ? AND age <= ?))
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.like("name","feo").or(wr->wr.ge("age",18).le("age",30));
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);
//------------------------------------------------
//使用between
//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ? OR (age BETWEEN ? AND ?))
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.like("name","feo").or(wr->wr.between("age",18,30));
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

需求:查询name含有fei字样的并且 年龄在小于18或者大于30的用户

//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name LIKE ? AND (age >= ? OR (age <= ?)))
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.like("name","fei").and(wr->wr.ge("age",18).or(w->w.le("age",30)));
List<Map<String, Object>> maps = employeeMapper.selectMaps(wrapper);
maps.forEach(System.err::println);

使用注解进行单表查询

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

测试

//select e.* from employee e
List<Employee> employees = employeeMapper.listByAnnoSingle();
System.out.println(employees);

使用注解进行关联表查询

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

测试

//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
@Test
public void test22(){
    List<Employee> employees = employeeMapper.listByAnnoJoin();
    employees.forEach(System.err::println);
}

QueryWrapper 和 LambdaQueryWrapper的使用

//普通的条件构造器
QueryWrapper<Employee> queryWrapper = new QueryWrapper();
//指定要显示出来的列
queryWrapper.select("id","username");
List<Map<String,Object>> list = employeeMapper.selectMaps(qeryWrapper);

//------------------------------------

//支持lambda的 条件构造器
LambdaQueryWrapper<Employee> lambdaQueryWrapper = new LambdaQueryWrapper();
//指定根据排序列
lambdaQueryWrapper.orderByDesc(Employee::getId);
//指定要显示出来的列
lambdaQueryWrapper.select(Employee::getId,Employee::getName,Employee::getPassword);
List<Employee> employees = employeeMapper.selectList(lambdaQueryWrapper);

LambdaUpdateWrapper和UpdateWrapper语法

//普通的条件构造器
UpdateWrapper<Employee> updateWrapper = new UpdateWrapper();
updateWrapper.eq("指定要进行修改列的条件","条件属性值");
updateWrapper.set("指定要进行修改列","要进行修改的值");
employeeMapper.update(null,updateWrapper);

//------------------------------------

//支持lambda的 条件构造器
LambdaUpdateWrapper<Employee> lambdaUpdateWrapper = new LambdaUpdateWrapper();
//指定要进行修改列的值
lambdaUpdateWrapper.eq(Employee::getId);
//指定列要进行属性值修改
lambdaQueryWrapper.set(Employee::getName,"xiaoming");
employeeMapper.update(null.lambdaUpdateWrapper);

QueryWrapper与UpdateWrapper的区别

QueryWrapper:只进行sql语句查询

UpdateWrapper:提供set方法可以有效针对数据库表中的列进行值修改,eq表示列等于什么条件下

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mybatis-plus 的相关文章

随机推荐

  • python3安装Pillow(PIL)

    本方法亲测可用 我的是win7 32位 Python3 4 官网上还没有支持Python3的PIL 使用Pillow代替PIL 首先 下载对应的whl文件 来源http www lfd uci edu gohlke pythonlibs 4
  • n个数分为两组,两组数的个数尽可能相等,差值最小

    题目描述 对于有n个数的数组 分为两组 这两组的数的个数尽可能相等 不超过1 同时两组的数之和的差值最小 这个题目使用类似0 1背包问题 思路 从k个数中选i个数 求所有可能的和 并把这些和放在flag中用true表示 k i flag见代
  • ubuntu忘记root密码怎么办?

    普通用户 无论你是否申请了root帐号 或是普通账号密码忘记了都没有问题的 首先 重启ubuntu 随即长按shift进入grub菜单 其次 选择第二个高级模式recovery mode进入Recovery Menu界面 选择root Dr
  • jsp代码中EL表达式无法显示(已解决)

    jstl最近是不是有问题 还是我的代码有问题 每次遍历都不会出来 都是显示这样 有的说是必须要有jstl jar和 standard jar 但是我也有了 但是也是没有说打刀口上 其实是忽略了一个知识点 EL表达式 在这里加上 isELIg
  • CUnit 单元测试 方法总结

    CUnit是一个用C语言编写 管理和运行单元测试的轻量级系统 它为C程序员提供了基本的测试功能和灵活的各种用户接口 CUnit被构建为一个与用户的测试代码链接的静态库 它使用一个简单的框架来构建测试结构 并为测试常见数据类型提供了一套丰富的
  • Java 多线程 --- 终止线程 Terminate Threads

    Java 多线程 终止线程 Terminate Threads 为什么要终止线程 终止线程的方法 return stop interrupt InterruptedException 为什么要终止线程 线程消耗资源 包括内存 内核 CPU等
  • 非常详细的51单片机引脚介绍

    引用cy pp 的 非常详细的51单片机引脚介绍 T89C2051是精简版的51单片机 精简掉了P0口和P2口 只有20引脚 但其内部集成了一个很实用的模拟比较器 特别适合开发精简的51应用系统 毕竟很多时候我们开发简单的产品时用不了全部3
  • Qt编写控件属性设计器-用户属性

    一 前言 用户属性是后面新增加的一个功能 自定义控件如果采用的Q PROPERTY修饰的属性 会自动识别到属性栏中 这个一般称为控件属性 在组态设计软件中 光有控件本身的控件属性还是不够的 毕竟这些属性仅仅是以外观为主 并不能表示某个设备的
  • c#监测文件的类---FileSystemWatcher

    本文转载自 http blog csdn net jason ldh article details 9972801 FileSystemWatcher控件主要功能 监控指定文件或目录的文件的创建 删除 改动 重命名等活动 可以动态地定义需
  • 带头结点和尾节点的双向链表的(增删改查,头遍历,尾遍历)java实现

    废话不多说 请看代码 测试输出 代码 package com coderman dataStruct 双链表 Author zhangyukang Date 2020 2 18 19 00 Version 1 0 class DoubleL
  • PyTorch使用LMDB数据库加速文件读取

    PyTorch使用LMDB数据库加速文件读取 文章目录 PyTorch使用LMDB数据库加速文件读取 背景介绍 具体操作 LMDB主要类 lmdb Environment lmdb Transaction Imdb Cursor 操作流程
  • mybatisPlus-wrapper使用

    创建测试类 import com baomidou mybatisplus core conditions query QueryWrapper import com plus mybatis mapper UserMapper impor
  • 思科模拟器静态路由

    网络拓扑图 Router0配置 Router2配置 Multilayer Switch0配置 Switch0配置 Switch2配置 主机PC0配置 202 199 1 2 255 255 255 0 202 199 1 1 主机PC1配置
  • LDAP: error code 32 - No Such Object

    使用spring ldap创建节点的时候报错 LDAP error code 32 No Such Object 是在调用 this ldapTemplate create ldapUser 的时候报的错 找了半天没有发现原因 最后看到一篇
  • JavaScript整理

    第一章 JavaScript概述 1 1 JavaScript简介 JavaScript 简称js 是一种直译式脚本语言 是一种动态类型 弱类型 基于原型的语言 内置支持类型 它的解释器被称为JavaScript引擎 为浏览器的一部分 广泛
  • ajax请求和普通请求的区别

    当浏览器按照window location href index html 进行定期请求时 会清除当前窗口并将服务器响应加载到窗口中 使用ajax请求 当前窗口 文档不受影响 JavaScript代码可以检查请求的结果 并使用这些结果执行所
  • 一些黑科技接口钩子 钉钉,禅道,gitlab,jenkins等

    日常工作中需要做流程的串联 这个时候就需要掌握一些黑科技接口 这些接口甚至是官方文档上并没有提供的 但是我们确实可以使用 进行内部工具开发的一定要记得提供钩子 没有钩子 做不了朋友 钉钉相关 钉钉群中的自定义机器人 curl https o
  • C/C++在线编译器

    一直以来都喜欢用手机看书 尤其是在上班时 看的最多的是编程一类的书 主要是C 看着就想写写代码 可是电脑用不能用 怎么办 于是想到用UC浏览器找找看网上有没有在线的编译器 想什么时候写代码都可以验证 于是就找了几个 各有千秋吧 中文的我没找
  • 在地址栏中输入一段内容,接下来都发生了些什么

    用户发出 URL 请求到页面开始解析的这个过程 就叫做导航 用以定位到新资源 并且将老的资源从页面卸载 一 用户输入 地址栏首先判断输入的内容是搜索内容还是符合url规则的url 如果是搜索内容的话 浏览器会拼接上该搜索内容形成一个新的ur
  • mybatis-plus

    mybatis plus的sql拼接规则 实体对象参数属性有值 那么该属性名会拼接sql语句中 实体对象参数属性为基本属性时 会有默认值 mybatis plus认为是有值 参与sql拼接 mybatis plus与mybatis的对比 m