总结
mybatis的一下问题
每个实体表对应一个实体类,对应一个Mapper.java接口, 对应一个Mapper.xml配置文件
每个Mapper.java接口都有重复的crud方法,每一个Mapper.xml都有重复的crud的sql配置
mybatis-plus
简介请去官网详细查看MyBatis-Plus, mybatis.plus
什么是Mybatis-plus
Mybatis-Plus(简称MP)是一个Mybatis的增强工具,只是在Mybatis的基础上做了增强却不做改变,MyBatis-Plus支持所有Mybatis原生的特性,所以引入Mybatis-Plus不会对现有的Mybatis构架产生任何影响。MyBatis 增强工具包,简化 CRUD 操作。启动加载 XML 配置时注入单表 SQL 操作 ,为简化开发工作、提高生产率而生。
思考?能不能对这些重复的crud方法, crud配置做配置呢?
答案是也是: 使用Mybatis-plus
支持的数据分别有
mysql 、mariadb 、oracle 、db2 、h2 、hsql 、sqlite 、postgresql 、sqlserver 、presto 、Gauss 、Firebird
Phoenix 、clickhouse 、Sybase ASE 、 OceanBase 、达梦数据库 、虚谷数据库 、人大金仓数据库 、南大通用数据库
特性
无侵入:只做增强不做改变,引入它不会对现有的工程产生影响,非常舒服
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere ) 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
框架结构
?
mybatis-plus 优点, 缺点, 与mybatis对比
不用我们使用Mapper.xml编写SQL的基本crud语句,mybatis-plus底层已经帮我们封装好了,mybatis-plus 还内置了分页功能,开发者配置一下即可实现分页功能,通过实现BeanMapper<泛型>接口即可实现基本的 crud操作,提高开发效率,但一般在开发中小型项目中比较高效,对于大项目,则需要大量的表进行关联 起来,操作复杂,所有显得mybatis-plus没有那么优势
依赖
?
?
?<dependencies>
? ? ? ?<dependency>
? ? ? ? ? ?<groupId>com.baomidou</groupId>
? ? ? ? ? ?<artifactId>mybatis-plus-boot-starter</artifactId>
? ? ? ? ? ?<version>3.4.0</version>
? ? ? ?</dependency>
? ? ?
? ? ? ?<dependency>
? ? ? ? ? ?<groupId>mysql</groupId>
? ? ? ? ? ?<artifactId>mysql-connector-java</artifactId>
? ? ? ? ? ?<version>8.0.22</version>
? ? ? ?</dependency>
? ?</dependencies>
mybatis-plus入门案例
@SpringBootTest
public class CRUDTest {
? ?@Autowired
? ?private EmployeeMapper employeeMapper;
? ?//新增
? ?@Test
? ?public void testSave(){
? ? ? ?Employee employee = new Employee();
? ? ? ?employee.setAdmin(1);
? ? ? ?employee.setAge(18);
? ? ? ?employee.setDeptId(1L);
? ? ? ?employee.setEmail("2394162893@qq.com");
? ? ? ?employee.setName("wangson");
? ? ? ?employee.setPassword("111");
? ? ? ?employeeMapper.insert(employee);
?
? }
?
? ?//编辑
? ?@Test
? ?public void testUpdate(){
? ? ? ?Employee employee = new Employee();
? ? ? ?employee.setId(1327139013313564673L);
? ? ? ?employee.setAdmin(1);
? ? ? ?employee.setAge(18);
? ? ? ?employee.setDeptId(1L);
? ? ? ?employee.setEmail("2394162893@qq.com");
? ? ? ?employee.setName("wangson03");
? ? ? ?employee.setPassword("111");
? ? ? ?employeeMapper.updateById(employee);
? }
?
? ?//删除
? ?@Test
? ?public void testDelete(){
? ? ? ?employeeMapper.deleteById(1327139013313564673L);
? }
? ?
? ?//查询id为1的信息
? ?@Test
? ?public void testGet(){
?System.out.println(employeeMapper.selectById(1L));
? }
?
? ?//查询所有信息
? ?@Test
? ?public void testList(){
? ? ? ?System.out.println(employeeMapper.selectList(null));
? }
}
mybatis-plus原理
ScanEntity扫描实体,通过反射提取:Reflection extraction,分析表名称:Analysis Table, 实现SQL:insert,update,Delete,select,再注入到mybatis容器里面
常用注解 【必须掌握】
@TableName:指定当前实体类映射哪张数据库表,默认是跟实体类名一致,也就是说当表名与类名不一致使用,跟表名与类名映射
@TableId(value="id",type=IdType.AUTO):在没有明确指定id生成规则时,默认使用雪花算法,value的值是数据库中哪一列的值,type的值是实现根据前面value的值进行自增
@TableField():当列名与属性名不一致时使用,做列名与属性名映射
@TableField(exist=false):表示该属性不与表中列进行映射,默认是true
@VerSion:描述:乐观锁注解、标记 @Verison 在字段上,作用:用于标记乐观锁操作字段,乐观锁注解,主要解决并发操作可能引起的一些数据异常
日志
第一种:
?
logging.level.cn.wolfcode.mp.mapper=debug
?
第二种:
?
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
通用mapper接口【必须掌握】
新增操作
? ?/**
? ? * 插入一条记录
? ? * @param entity 实体对象
? ? */
? ?int insert(T entity);
需求:添加一条用户信息
@Test
? ?public void testSave(){
? ? ? ?Employee employee = new Employee();
? ? ? ?employee.setAdmin(1);
? ? ? ?employee.setAge(18);
? ? ? ?employee.setDeptId(1L);
? ? ? ?employee.setEmail("2394162893@qq.com");
? ? ? ?employee.setName("wangson");
? ? ? ?employee.setPassword("1");
? ? ? ?employeeMapper.insert(employee);
?
? }
编辑操作
1.updateById(id)
/**
? ? * 根据 ID 修改
? ? * @param entity 实体对象
? ? */
? ?int updateById(@Param(Constants.ENTITY) T entity);
需求: 将id=1用户名字修改为wangson
? ?@Test
? ?public void testUpdateById(){
? ? ? ?Employee employee = new Employee();
? ? ? ?employee.setId(1L);
? ? ? ?employee.setName("wangson");
? ? ? ?employeeMapper.updateById(employee);
? }
?
注意: 拼接sql时,所有非null 字段都进行set 拼接
打印sql: UPDATE employee SET name=?, age=?, admin=? WHERE id=?
改进:
1:先查
2:替换
3:更新
? ?
需求: 将id=1用户名字修改为wangson
? ?@Test
? ?public void testUpdateById2(){
? ? ? ?Employee employee = employeeMapper.selectById(1L);
? ? ? ?employee.setName("wangson");
? ? ? ?employeeMapper.updateById(employee);
? }
2.update(entity,warpper)
? ?/**
? ? * 根据 whereEntity 条件,更新记录
? ? *
? ? * @param entity ? ? ? 实体对象 (set 条件值,可以为 null)
? ? * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
? ? */
? ?int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
?
需求:更新name=dafei员工年龄为18岁
? ?@Test
? ?public void testUpdate(){
? ? ? ?Employee employee = new Employee();
? ? ? ?employee.setAge(18);
? ? ? ?//update 语句中的where 条件包装类
? ? ? ?UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
? ? ? ?wrapper.eq("name", "wangson");
? ? ? ?employeeMapper.update(employee, wrapper);
? }
?
注意: 拼接sql时,所有非null 字段都进行set 拼接
打印sql: UPDATE employee SET name=?, age=?, admin=? WHERE id=?
升级:
需求:更新name=dafei员工年龄为18岁
? ?@Test
? ?public void testUpdate2(){
? ? ? ?//update 语句中的where 条件包装类
? ? ? ?UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
? ? ? ?wrapper.eq("name", "wanson").set("age", 18);
? ? ? ?employeeMapper.update(null, wrapper);
? }
?
需求:更新name=wangson,并且password=1111的员工年龄为18岁
? ?@Test
? ?public void testUpdate2(){
? ? ? ?//update 语句中的where 条件包装类
? ? ? ?UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
? ? ? ?wrapper.eq("name", "wangson")
? ? ? ? ? ? ? .eq("password", "1111")
? ? ? ? ? ? ? .set("age", 18);
? ? ? ?employeeMapper.update(null, wrapper);
? }
3.使用建议
知道id,并且所有更新使用
updateById
部分字段更新,使用
update
使用这种方式:
wrapper.条件.set更新字段
? ?/**
? ? * updateById
? ? * ? :全量更新, 只要传入对象属性不为null, 都可以进行update更新, 条件是通过id匹配
? ? * ? 正确操作姿势: 前提: 必须知道id
? ? * ? //1:查
? ? * ? //2:替换
? ? * ? //3:更新
? ? * update+wrapper
? ? * ? :部分字段更新, 通过wrapper对象拼接各种满足要求条件, 更新set的列由wrapper 决定
? ? * ? 正确操作姿势:
? ? * ? 1>设置更新条件
? ? * ? 2>拼接更新列
? ? */
删除操作
/**
? ? * 根据 ID 删除
? ? *
? ? * @param id 主键ID
? ? */
? ?int deleteById(Serializable id);
需求:删除id=1的员工信息
? ?@Test
? ?public void testDeleteById(){
? ? ? employeeMapper.deleteById(1L);
? }
?
?/**
? ? * 删除(根据ID 批量删除)
? ? *
? ? * @param idList 主键ID列表(不能为 null 以及 empty)
? ? */
? ?int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
需求:删除id=1, id=2的员工信息
? ?@Test
? ?public void testDeleteBatchIds(){
? ? ? ?employeeMapper.deleteBatchIds(Arrays.asList(1L,2L));
? }
?
? ?/**
? ? * 根据 columnMap 条件,删除记录
? ? *
? ? * @param columnMap 表字段 map 对象
? ? */
? ?int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
需求:删除name=wangson并且age=18的员工信息
? ?@Test
? ?public void testDeleteByMap(){
? ? ? ?Map<String, Object> map = new HashMap<>();
? ? ? ?map.put("name", "wangson");
? ? ? ?map.put("age", 18);
? ? ? ?employeeMapper.deleteByMap(map);
? }
打印:DELETE FROM employee WHERE name = ? AND age = ?
? ?
? ? ? ?/**
? ? * 根据 entity 条件,删除记录
? ? *
? ? * @param wrapper 实体对象封装操作类(可以为 null)
? ? */
? int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
需求:删除name=wangson并且age=18的员工信息
? ?@Test
? ?public void testDeleteWrapper(){
? ? ? ?QueryWrapper<Employee> wrapper = new QueryWrapper<>();
? ? ? ?wrapper.eq("name", "wangson").eq("age", 18);
? ? ? ?employeeMapper.delete(wrapper);
? }
查询操作
/**
* 根据 ID 查询
*
* @param id 主键ID
*/
T selectById(Serializable id);
需求:查询id=1的员工信息
@Test
public void testSelectById(){
System.out.println(employeeMapper.selectById(1L));
}
/**
* 查询(根据ID 批量查询)
*
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
需求:查询id=1,id=2的员工信息
@Test
public void testSelectBatchIds(){ System.out.println(employeeMapper.selectBatchIds(Arrays.asList(1L, 2L)));
}
/**
* 查询(根据 columnMap 条件)
*
* @param columnMap 表字段 map 对象
*/
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
需求: 查询name=dafei, age=18的员工信息
@Test
public void testSelectByMap(){
Map<String, Object> map = new HashMap<>();
map.put("name", "dafei");
map.put("age", 18);
System.out.println(employeeMapper.selectByMap(map));
}
/**
* 根据 Wrapper 条件,查询总记录数
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
需求: 查询满足条件的所有的员工个数
@Test
public void testSelectCount(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
System.out.println(employeeMapper.selectCount(wrapper));
//没有指定条件, 等价于传入null
//System.out.println(employeeMapper.selectCount(null));
}
/**
* 根据 entity 条件,查询全部记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
需求: 查询满足条件的所有的员工信息, 返回List<Employee>
@Test
public void testSelectList(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
List<Employee> list = employeeMapper.selectList(wrapper);
list.forEach(System.out::println);
//没有指定条件, 等价于传入null
//List<Employee> list2 = employeeMapper.selectList(null);
//list2.forEach(System.out::println);
}
/**
* 根据 Wrapper 条件,查询全部记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
需求: 查询满足条件的所有的员工信息, 返回List<Map<String, Object>> 底层将每条数据封装成HashMap
@Test
public void testSelectMap(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
List<Map<String, Object>> map = employeeMapper.selectMaps(wrapper);
map.forEach(System.out::println);
//没有指定条件, 等价于传入null
//List<Map<String, Object>> map2= employeeMapper.selectMaps(null);
//map2.forEach(System.out::println);
}
/**
* 根据 entity 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
<E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
需求:查询第二页员工数据, 每页显示3条, (分页返回的数据是实体对象)
步骤1:配置分页插件
启动类中:
//分页拦截器
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
paginationInnerInterceptor.setOverflow(true); //合理化 interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
/**
* 根据 entity 条件,查询一条记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
需求: 查询满足条件的所有的员工, 取第一条
@Test
public void testSelectOne(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
Employee employee = employeeMapper.selectOne(wrapper);
System.out.println(employee);
}
注意: 如果查出数据条数超过一条报错:Expected one result (or null) to be returned by selectOne(), but found: xxx
/**
* 根据 Wrapper 条件,查询全部记录
* <p>注意: 只返回第一个字段的值</p>
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
需求: 查询满足条件的所有的员工, 返回排在第一的列所有数据, 没特别指定, 一般返回时id
@Test
public void testSelectObjs(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
//wrapper.select("name"); //挑选返回的列
List<Object> list = employeeMapper.selectObjs(wrapper);
list.forEach(System.out::println);
}
/**
* 根据 Wrapper 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件
* @param queryWrapper 实体对象封装操作类
*/
<E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
需求:查询第二页员工数据, 每页显示3条, (分页返回的数据是HashMap)
步骤1:配置分页插件
步骤2:编写分页代码
@Test
public void testSelectMapsPage(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
//参数1:当前页, 参数2:每页显示条数
IPage<Map<String, Object>> page = new Page<>(2, 3);
employeeMapper.selectMapsPage(page, wrapper);
System.out.println("当前页:" + page.getCurrent());
System.out.println("每页显示条数:" + page.getSize());
System.out.println("总页数:" + page.getPages());
System.out.println("总数:" + page.getTotal());
System.out.println("当前页数据:" + page.getRecords());
}
分页操作
//需求:查询第二页员工数据, 每页显示3条, (分页返回的数据是HashMap)
@Test
public void testSelectMapsPage() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
Page<Map<String , Object>> page = new Page<>(2,3);
employeeMapper.selectMapsPage(page,wrapper);
System.err.println("当前页:"+page.getCurrent());
System.err.println("每页显示的条数:"+page.getSize());
System.err.println("总数:"+page.getTotal());
System.err.println("每页显示的数据:"+page.getRecords());
System.err.println("总页数:"+page.getPages());
}
继承体系
?
条件构造器【必须掌握】
更新操作
需求:将id=1的员工name改为dafei
@Test
public void testUpdate(){
Employee employee = new Employee();
employee.setId(1L);
employee.setName("wanson");
employeeMapper.updateById(employee);
}
可能导致数据丢失
UpdateWrapper更新
set(String column, Object val)
set(boolean condition, String column, Object val)
例: set("name", "老李头")
需求:将id=1的员工name改为wangson
@Test
public void testUpdate2(){
UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
wrapper.eq("id", 1L);
wrapper.set("name", "wangson");
employeeMapper.update(null, wrapper);
}
需求:将id=1的员工age改为18, 如果传入uname变量值不等于null或者“”,修改为员工name为uname变量值
@Test
public void testUpdate2(){
String uname="xxxx";
//String uname=null;
UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
wrapper.eq("id", 1L);
wrapper.set("age", 18);
if(StringUtils.hasLength(uname)){
wrapper.set("name", uname);
}
employeeMapper.update(null, wrapper);
}
//需求:使用lambda表达式 将id=3的用户name改为xingxing
@Test
public void testLambdaUpdate4() {
LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Employee::getId,3L).set(Employee::getName,"xingxing");
employeeMapper.update(null,wrapper);
}
//推荐使用LambdaUpdateWrapper更新
查询操作
//需求:查询name=jaskson, age=18的用户
@Test
public void testQuery() {
Map<String,Object> map = new HashMap<>();
map.put("name","jaskson");
map.put("age",18L);
List<Employee> employeeList = employeeMapper.selectByMap(map);
employeeList.forEach(System.err::println);
}
//lambda形式
//需求:查询name=xingxing, age=25的用户
@Test
public void testQuery2() {
LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Employee::getName,"xingxing");
wrapper.eq(Employee::getAge,25L);
employeeMapper.selectList(wrapper).forEach(System.err::println);
}
//推荐使用LambdaUpdateWrapper更新
工具类:Wrappers
query
//需求:查询name=xingxing, age=25的用户
@Test
public void testWrappers1() {
QueryWrapper<Employee> wrapper = Wrappers.<Employee>query();
wrapper.ge("age", 18L).lt("age", 30L);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
需求:将id=5的用户name改为zhangjie
@Test
public void testWrapper2() {
UpdateWrapper<Employee> wrapper = Wrappers.<Employee>update();
wrapper.eq("id", 5L).set("name", "zhangjie");
employeeMapper.update(null, wrapper);
}
//需求:查询name=xingxing, age=25的用户
@Test
public void testWrapper3() {
LambdaQueryWrapper<Employee> wrapper = Wrappers.<Employee>lambdaQuery();
wrapper.eq(Employee::getName, "xingxing").eq(Employee::getAge, 25L);
employeeMapper.selectList(wrapper).forEach(System.err::println);
}
//需求:查询所有员工, 返回员工以a字母开头的列
@Test
public void testQuery6() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.select(Employee.class, wp -> wp.getProperty().startsWith("a"));
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求:查询所有员工信息按age正序排, 如果age一样, 按id正序排,condition:开关条件
@Test
public void testQuery7() {
LambdaQueryWrapper<Employee> wrapper = Wrappers.<Employee>lambdaQuery();
wrapper.orderBy(true, true, Employee::getAge);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
7:高级查询-各种where条件 sql其他语法【必须掌握】
列投影
//参数:指定查询后返回的列
select(String... sqlSelect)
//参数:Predicate 函数, 满足指定判定逻辑列才返回
//要求:wrapper.setEntity(employee);
select(Predicate<TableFieldInfo> predicate)
//参数1:通过实体属性映射表中列
//参数2:Predicate 函数, 满足指定判定逻辑列才返回
select(Class<T> entityClass, Predicate<TableFieldInfo> predicate)
需求:查询所有员工, 返回员工name, age列
@Test
public void testQuery4(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.select("name", "age");
employeeMapper.selectList(wrapper);
}
需求:查询所有员工, 返回员工以a字母开头的列
@Test
public void testQuery4(){
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.select(Employee.class, tableFieldInfo->tableFieldInfo.getProperty().startsWith("a"));
employeeMapper.selectList(wrapper);
}
orderBy排序:
//需求:查询所有员工信息按age正序排, 如果age一样, 按id正序排,condition:开关条件
@Test
public void testQuery7() {
LambdaQueryWrapper<Employee> wrapper = Wrappers.<Employee>lambdaQuery();
wrapper.orderBy(true, true, Employee::getAge);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//orderByDesc 跟 orderByAsc用法一样, 不过是倒序排
@Test
public void testQuery8() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("age");
wrapper.orderByDesc("dept_id");
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
groupBy分组查询
//需求: 以部门id进行分组查询,查每个部门员工个数, 将大于3人的部门过滤出来
@Test
public void testQuery10() {
QueryWrapper<Employee> wrapper = Wrappers.<Employee>query();
wrapper.groupBy("dept_id");
wrapper.select("dept_id", "count(id) as count").having("count >{0}", 3);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
allEq:全等
//需求:查询name=jaskson, age=18的员工信息
//SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (name = ? AND age = ?)
@Test
public void testQuery11() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
Map<String, Object> map = new HashMap<>();
map.put("name", "jaskson");
map.put("age", 18L);
wrapper.allEq(map,true); //设置为true 是当字段对应的值为null时,也加入条件查询,而false则不加入其中运算
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求:查询name =wangson员工信息
@Test
public void testQuery14() {
LambdaQueryWrapper<Employee> wrapper = Wrappers.<Employee>lambdaQuery();
wrapper.eq(Employee::getName, "wangson");
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求:查询name !=fei员工信息
@Test
public void testQuery15() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.ne("name", "fei");
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求:查询age 大于18岁员工信息
@Test
public void testQuery16() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.gt("age", 18);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求:查询age 大于或等于18岁员工信息
@Test
public void testQuery17() {
LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Employee::getAge, 18);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求:查询age 小于25岁员工信息
@Test
public void testQuery18() {
QueryWrapper<Employee> wrapper = Wrappers.<Employee>query();
wrapper.lt("age", 25L);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求:查询age 小于等于25岁员工信息
@Test
public void testQuery19() {
LambdaQueryWrapper<Employee> wrapper = Wrappers.<Employee>lambdaQuery();
wrapper.le(Employee::getAge, 25L);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求:查询年龄介于18~30岁的员工信息
// SELECT id,name,password,email,age,admin,dept_id FROM employee WHERE (age BETWEEN ? AND ?)
@Test
public void testQuery20() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.between("age", 18L, 30L);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
notBetween的用法
//需求:查询年龄小于18或者大于30岁的员工信息【用between实现】
@Test
public void testQuery21() {
LambdaQueryWrapper<Employee> wrapper = Wrappers.<Employee>lambdaQuery();
wrapper.notBetween(Employee::getAge, 18L, 30L);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
isNull和isNotNull
//需求: 查询dept_id 为null 员工信息
@Test
public void testQuery22() {
LambdaQueryWrapper<Employee> wrapper = Wrappers.<Employee>lambdaQuery();
wrapper.isNull(Employee::getDeptId);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求: 查询dept_id 为不为null 员工信息
@Test
public void testQuery23() {
LambdaQueryWrapper<Employee> wrapper = Wrappers.<Employee>lambdaQuery();
wrapper.isNotNull(Employee::getDeptId);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
in的用法:
//需求: 查询id为1, 2 的员工信息
@Test
public void testQuery24() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.in("id", 1l, 2L);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求: 查询id不为1, 2 的员工信息
@Test
public void testQuery25() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.notIn("id", 1l, 2L);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//inSql的用法
//需求: 查询id为1, 2 的员工信息
@Test
public void testQuery26() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.inSql("id", "1,2");
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求: 查询id不为1, 2 的员工信息
@Test
public void testQuery27() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.notInSql("id", "1,2");
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//exists : 拼接 EXISTS ( sql语句 )
@Test
public void testQuery28() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.exists("select id from employee where age = 21").exists("select name from employee where name = 'wangson'");
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求: 查询name中含有fei字样的员工
@Test
public void testQuery29() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.like("name", "fei");
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求: 查询name中不含有fei字样的员工
@Test
public void testQuery30() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.notLike("name", "fei");
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求: 查询name以son结尾的员工信息
@Test
public void testQuery31() {
LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
wrapper.likeLeft(Employee::getName, "son");
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求: 查询姓wang的员工信息
@Test
public void testQuery32() {
LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
wrapper.likeRight(Employee::getName, "wang");
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求: 查询age = 18 或者 name=jaskson 或者 id =1 的用户
@Test
public void testQuery33() {
LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Employee::getAge, 18)
.or()
.eq(Employee::getName, "jaskson")
.or()
.eq(Employee::getId, 1L);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求:查询name含有fei字样的,或者 年龄在18到30之间的用户
@Test
public void testQuery34() {
LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
//方式一
/* wrapper.eq(Employee::getName,"fei")
.or().between(Employee::getAge,18,30);*/
wrapper.eq(Employee::getName, "fei")
.or(wp -> wp.ge(Employee::getAge, 18).le(Employee::getAge, 30));
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求:查询年龄介于18~30岁的员工信息
//默认是and操作
@Test
public void testQuery35() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
//方式一
//wrapper.ge("age",18).le("age",30);
//方式二
wrapper.between("age", 18, 30);
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
//需求:查询name含有fei字样的并且 年龄在小于18或者大于30的用户
@Test
public void testQuery36() {
QueryWrapper<Employee> wrapper = new QueryWrapper<>();
wrapper.like("name", "fei")
.and(wp -> wp.lt("age", 18)
.or()
.gt("age", 30));
employeeMapper.selectMaps(wrapper).forEach(System.err::println);
}
8:通用的service接口【必须掌握】
分页配置
步骤1:配置分页插件
//分页
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
paginationInnerInterceptor.setOverflow(true); //合理化
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
|