Springcloud学习笔记35--Mybatis-plus增删改查功能实例应用(条件构造器QueryWrapper使用)
0 Mapper 接口方法(CRUD)
【添加数据:(增)】 int insert(T entity); // 插入一条记录 注: T 表示任意实体类型 entity 表示实体对象 【删除数据:(删)】 int deleteById(Serializable id); // 根据主键 ID 删除 int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); // 根据 map 定义字段的条件删除 int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper); // 根据实体类定义的 条件删除对象 int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // 进行批量删除 注: id 表示 主键 ID columnMap 表示表字段的 map 对象 wrapper 表示实体对象封装操作类,可以为 null。 idList 表示 主键 ID 集合(列表、数组),不能为 null 或 empty 【修改数据:(改)】 int updateById(@Param(Constants.ENTITY) T entity); // 根据 ID 修改实体对象。 int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper); // 根据 updateWrapper 条件修改实体对象 注: update 中的 entity 为 set 条件,可以为 null。 updateWrapper 表示实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句) 【查询数据:(查)】 T selectById(Serializable id); // 根据 主键 ID 查询数据 List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // 进行批量查询 List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); // 根据表字段条件查询 T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 根据实体类封装对象 查询一条记录 Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查询记录的总条数 List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查询所有记录(返回 entity 集合) List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查询所有记录(返回 map 集合) List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查询所有记录(但只保存第一个字段的值) <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查询所有记录(返回 entity 集合),分页 <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查询所有记录(返回 map 集合),分页 注: queryWrapper 表示实体对象封装操作类(可以为 null) page 表示分页查询条件
1.条件构造器
QueryWrapper是mybatis plus中实现查询的对象封装操作类,他的层级关系如下
Wrapper 条件构造抽象类 -- AbstractWrapper 查询条件封装,用于生成 sql 中的 where 语句。 -- QueryWrapper Entity 对象封装操作类,用于查询。 -- UpdateWrapper Update 条件封装操作类,用于更新。 -- AbstractLambdaWrapper 使用 Lambda 表达式封装 wrapper -- LambdaQueryWrapper 使用 Lambda 语法封装条件,用于查询。 -- LambdaUpdateWrapper 使用 Lambda 语法封装条件,用于更新。
2.插入一条记录(
insert)
需要操作的实体类:
@Data @TableName("pm_os_bucket") @Accessors(chain = true) @EqualsAndHashCode(callSuper = false) @ApiModel(value="pm_os_bucket对象", description="pm_os_bucket") public class PmOsBucket implements Serializable { private static final long serialVersionUID = 1L; /**id*/ @TableId(value = "id", type = IdType.AUTO) @ApiModelProperty(value = "id") private java.lang.Integer id; /**桶名称*/ @Excel(name = "桶名称", width = 15) @ApiModelProperty(value = "桶名称") private java.lang.String bucketName; /**桶描述*/ @Excel(name = "桶描述", width = 15) @ApiModelProperty(value = "桶描述") private java.lang.String bucketDesc; /**对象存储名称*/ @Excel(name = "对象存储名称", width = 15) @ApiModelProperty(value = "对象存储名称") private java.lang.String osName; /**子系统编码*/ @Excel(name = "子系统编码", width = 15) @ApiModelProperty(value = "子系统编码") private java.lang.String subsysCode; /**状态(1启用,0不启用)*/ @Excel(name = "状态(1启用,0不启用)", width = 15) @ApiModelProperty(value = "状态(1启用,0不启用)") private java.lang.String status; /**创建人*/ @ApiModelProperty(value = "创建人") private java.lang.String createBy; /**创建时间*/ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") @DateTimeFormat(pattern="yyyy-MM-dd") @ApiModelProperty(value = "创建时间") private java.util.Date createTime; /**修改人*/ @ApiModelProperty(value = "修改人") private java.lang.String updateBy; /**修改时间*/ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") @DateTimeFormat(pattern="yyyy-MM-dd") @ApiModelProperty(value = "修改时间") private java.util.Date updateTime; }
常用注解说明:
【@TableName 】 @TableName 用于定义表名 注: 常用属性: value 用于定义表名 【@TableId】 @TableId 用于定义表的主键 注: 常用属性: value 用于定义主键字段名 type 用于定义主键类型(主键策略 IdType) 主键策略: IdType.AUTO 主键自增,系统分配,不需要手动输入 IdType.NONE 未设置主键 IdType.INPUT 需要自己输入 主键值。 IdType.ASSIGN_ID 系统分配 ID,用于数值型数据(Long,对应 mysql 中 BIGINT 类型)。 IdType.ASSIGN_UUID 系统分配 UUID,用于字符串型数据(String,对应 mysql 中 varchar(32) 类型)。 【@TableField】 @TableField 用于定义表的非主键字段。 注: 常用属性: value 用于定义非主键字段名 exist 用于指明是否为数据表的字段, true 表示是,false 为不是。 fill 用于指定字段填充策略(FieldFill)。 字段填充策略:(一般用于填充 创建时间、修改时间等字段) FieldFill.DEFAULT 默认不填充 FieldFill.INSERT 插入时填充 FieldFill.UPDATE 更新时填充 FieldFill.INSERT_UPDATE 插入、更新时填充。 【@TableLogic】 @TableLogic 用于定义表的字段进行逻辑删除(非物理删除) 注: 常用属性: value 用于定义未删除时字段的值 delval 用于定义删除时字段的值 【@Version】 @Version 用于字段实现乐观锁
(1)controller
@Api(tags="bs_file_store") @RestController @RequestMapping("/test/bsFileStore") @Slf4j public class BsFileStoreController extends JeecgController<BsFileStore, IBsFileStoreService> { @Autowired private IBsFileStoreService bsFileStoreService; @RequestMapping(value = "/insertTest", method = RequestMethod.POST) public Result<?> insertTest(HttpServletRequest request, HttpServletResponse response) { return Result.OK(bsFileStoreService.insertTest()?Result.OK("添加成功"):Result.error("添加失败!")); } }
(2)service
@Service @DS("multi-datasource1") @Slf4j public class BsFileStoreServiceImpl extends ServiceImpl<BsFileStoreMapper, BsFileStore> implements IBsFileStoreService { @Autowired private PmOsBucketMapper pmOsBucketMapper; @Override public boolean insertTest() { PmOsBucket pmOsBucket=new PmOsBucket(); pmOsBucket.setBucketName("flep03"); pmOsBucket.setStatus("1"); pmOsBucket.setBucketDesc("桶测试"); pmOsBucket.setOsName("fleposs2"); pmOsBucketMapper.insert(pmOsBucket); return true; }
}
注意:mybatisplus会自动把当前插入对象在数据库中的id写回到该实体中
(3)postman测试
http://127.0.0.1:7009/test/bsFileStore/insertTest
(4)数据库表结果
3.delete操作
3.1 根据id删除(deleteById方法)
这里只给出service层的操作
@Override public boolean deleteByIdTest() { pmOsBucketMapper.deleteById(6); return true; }
postman测试:
此时,查看数据库表,id为6的记录已经删除。
3.2 根据条件删除(QueryWrapper)
创建条件构造器时传入实体对象
设置的条件加入到Where语句中WHERE b
ucket_name=? AND status=?
。
BsFileStoreServiceImpl类中的方法:
@Override public boolean deleteByContionTest() { //QueryWrapper传入实体类,删除bucketName为flep04,status为0的记录 PmOsBucket pmOsBucket=new PmOsBucket(); pmOsBucket.setBucketName("flep04"); pmOsBucket.setStatus("0"); QueryWrapper<PmOsBucket> queryWrapper=new QueryWrapper<>(pmOsBucket); pmOsBucketMapper.delete(queryWrapper); return false; }
postman测试:
数据库表:
删除前
删除后:
4.update操作
4.1 updateById方法
BsFileStoreServiceImpl类中的方法:
@Override public boolean updateByIdTest() { PmOsBucket pmOsBucket=new PmOsBucket(); pmOsBucket.setId(5); pmOsBucket.setBucketName("flep05"); pmOsBucket.setBucketDesc("update测试flep05"); pmOsBucket.setStatus("1"); pmOsBucketMapper.updateById(pmOsBucket); return true; }
postman测试:
数据库表更新前:
数据库表更新后:
4.2 根据条件更新(QueryWrapper)
BsFileStoreServiceImpl类中的方法:
@Override public boolean updateByContidionTest() { QueryWrapper<PmOsBucket> queryWrapper=new QueryWrapper<>(); queryWrapper.eq("os_name","fleposs1") .eq("status","1" ); PmOsBucket pmOsBucket=new PmOsBucket(); pmOsBucket.setBucketName("flep06"); pmOsBucket.setCreateBy("admin"); pmOsBucketMapper.update(pmOsBucket,queryWrapper ); return true; }
注意:该案例表示把os_name为fleposs1,status为1的所有记录更新为pmOsBucket中设置的信息。
postman测试:http://127.0.0.1:7009/test/bsFileStore/updateByContidionTest
数据库表更新前:
数据库表更新后:
4.3 根据条件更新(LambdaQueryWrapper)
引入lambda,避免我们在代码中写类似的于os_name的硬编码
需求:查询student表中名为“lucky”,年龄为14的所有记录;
@PostMapping("/getStuInfo") public List<Student> getStuInfo(String name, String gender){ LambdaQueryWrapper<Student> lambdaQueryWrapper=new LambdaQueryWrapper<>(); lambdaQueryWrapper.eq(Student::getName,"lucky" ) .eq(Student::getAge,14 ); List<Student> students = studentMapper.selectList(lambdaQueryWrapper); log.info("111"); return null; }
postman调用:
5 select操作
5.1 根据id查询(selectById)
<1>controller层
@Api(tags="bs_file_store") @RestController @RequestMapping("/test/bsFileStore") @Slf4j public class BsFileStoreController extends JeecgController<BsFileStore, IBsFileStoreService> { @Autowired private IBsFileStoreService bsFileStoreService; @RequestMapping(value = "/queryByIdTest", method = RequestMethod.POST) public Result<?> queryByIdTest(@RequestParam(name="id",required=true) String id) { PmOsBucket pmOsBucket = bsFileStoreService.queryByIdTest(id); if(pmOsBucket==null) { return Result.error("未找到对应数据"); } return Result.OK(pmOsBucket); } }
<2>service层
BsFileStoreServiceImpl类中的方法:
@Override public PmOsBucket queryByIdTest(String id) { return pmOsBucketMapper.selectById(id); }
postman测试:http://127.0.0.1:7009/test/bsFileStore/queryByIdTest
5.2 根据条件查询一条数据(selectOne)
BsFileStoreServiceImpl类中的方法:
@Override public PmOsBucket queryOneTest() { PmOsBucket pmOsBucket=new PmOsBucket(); pmOsBucket.setId(4); pmOsBucket.setBucketName("flep02"); QueryWrapper<PmOsBucket> queryWrapper=new QueryWrapper<>(pmOsBucket); //若是数据库中符合传入的条件的记录有多条,那就不能用这个方法,会报错 return pmOsBucketMapper.selectOne(queryWrapper); }
注意:这个方法的sql语句就是where id = 4 and bucket_name = "flep02"
,若是符合这个条件的记录不止一条,那么就会报错。
postman测试:
5.3 根据查询条件返回多条数据(selectList)
<1>controller层
@Api(tags="bs_file_store") @RestController @RequestMapping("/test/bsFileStore") @Slf4j public class BsFileStoreController extends JeecgController<BsFileStore, IBsFileStoreService> { @Autowired private IBsFileStoreService bsFileStoreService; @RequestMapping(value = "/queryManyTest", method = RequestMethod.POST) public Result<?> queryManyTest(HttpServletRequest request, HttpServletResponse response) { List<PmOsBucket> pmOsBucketList= bsFileStoreService.queryManyTest(); return Result.OK(pmOsBucketList); } }
<2>service层
@Override public List<PmOsBucket> queryManyTest() { //01 新建一个QueryWrapper对象,类型为PmOsBucket对象,也就是你需要查询的实体数据 QueryWrapper<PmOsBucket> queryWrapper = new QueryWrapper<>(); //02 PmOsBucket对象对应的数据库表中的os_name,os_name字段值要为fleposs1 queryWrapper.eq("os_name", "fleposs1"); queryWrapper.eq("status", "1"); //03 调用pmOsBucketMapper.selectList方法,入参就为前面新建好的查询对象封装类 List<PmOsBucket> pmOsBucketList = pmOsBucketMapper.selectList(queryWrapper); return pmOsBucketList; }
postman测试:http://127.0.0.1:7009/test/bsFileStore/queryManyTest
5.4 通过id批量查询(selectBatchIds)
BsFileStoreServiceImpl类中的方法:
@Override public List<PmOsBucket> queryBatchByIdsTest() { List<Integer> idList = new ArrayList<>(); idList.add(1); idList.add(5); List<PmOsBucket> pmOsBucketList = pmOsBucketMapper.selectBatchIds(idList); return pmOsBucketList; }
postman测试:http://127.0.0.1:7009/test/bsFileStore/queryBatchByIdsTest
5.5 返回查询的符合条件的总记录数(selectCount)
需求:查找薪水大于3500 名字里有“小”的 员工的个数
sql实现:select count(*) from t_employee where salary>3500 and name like '%小%'
QueryWrapper<Employee> queryWrapper=new QueryWrapper(); queryWrapper.gt("salary",3500).like("name","小"); Integer count = employeeMapper.selectCount(queryWrapper); System.out.println(count);
5.6 常用的查询条件
<1>比较大小: ( =, <>, >, >=, <, <= )
eq(R column, Object val); // 等价于 =,例: eq("name", "老王") ---> name = '老王' ne(R column, Object val); // 等价于 <>,例: ne("name", "老王") ---> name <> '老王' gt(R column, Object val); // 等价于 >,例: gt("name", "老王") ---> name > '老王' ge(R column, Object val); // 等价于 >=,例: ge("name", "老王") ---> name >= '老王' lt(R column, Object val); // 等价于 <,例: lt("name", "老王") ---> name < '老王' le(R column, Object val); // 等价于 <=,例: le("name", "老王") ---> name <= '老王'
<2>范围:(between、not between、in、not in)
between(R column, Object val1, Object val2); // 等价于 between a and b, 例: between("age", 18, 30) ---> age between 18 and 30 notBetween(R column, Object val1, Object val2); // 等价于 not between a and b, 例: notBetween("age", 18, 30) ---> age not between 18 and 30 in(R column, Object... values); // 等价于 字段 IN (v0, v1, ...),例: in("age",{1,2,3}) ---> age in (1,2,3) notIn(R column, Object... values); // 等价于 字段 NOT IN (v0, v1, ...), 例: notIn("age",{1,2,3}) ---> age not in (1,2,3) inSql(R column, Object... values); // 等价于 字段 IN (sql 语句), 例: inSql("id", "select id from table where id < 3") ---> id in (select id from table where id < 3) notInSql(R column, Object... values); // 等价于 字段 NOT IN (sql 语句)
<3>模糊匹配:(like)
like(R column, Object val); // 等价于 LIKE '%值%',例: like("name", "王") ---> name like '%王%' notLike(R column, Object val); // 等价于 NOT LIKE '%值%',例: notLike("name", "王") ---> name not like '%王%' likeLeft(R column, Object val); // 等价于 LIKE '%值',例: likeLeft("name", "王") ---> name like '%王' likeRight(R column, Object val); // 等价于 LIKE '值%',例: likeRight("name", "王") ---> name like '王%'
<4>空值比较:(isNull、isNotNull)
isNull(R column); // 等价于 IS NULL,例: isNull("name") ---> name is null isNotNull(R column); // 等价于 IS NOT NULL,例: isNotNull("name") ---> name is not null
<5>分组、排序:(group、having、order)
groupBy(R... columns); // 等价于 GROUP BY 字段, ..., 例: groupBy("id", "name") ---> group by id,name orderByAsc(R... columns); // 等价于 ORDER BY 字段, ... ASC, 例: orderByAsc("id", "name") ---> order by id ASC,name ASC orderByDesc(R... columns); // 等价于 ORDER BY 字段, ... DESC, 例: orderByDesc("id", "name") ---> order by id DESC,name DESC having(String sqlHaving, Object... params); // 等价于 HAVING ( sql语句 ), 例: having("sum(age) > {0}", 11) ---> having sum(age) > 11
6.条件构造器常用案例
6.1 分页查询年龄在18 - 50且gender为0、姓名为tom的用户:
List<Employee> employees = emplopyeeDao.selectPage(new Page<Employee>(1,3), new EntityWrapper<Employee>() .between("age",18,50) .eq("gender",0) .eq("last_name","tom") );
6.2 查询gender为0且名字中带有老师、或者邮箱中带有a的用户
List<Employee> employees = emplopyeeDao.selectList( new EntityWrapper<Employee>() .eq("gender",0) .like("last_name","老师") //.or()//和or new 区别不大 .orNew() .like("email","a") );
6.3 查询gender为0,根据age排序,简单分页:
List<Employee> employees = emplopyeeDao.selectList( new EntityWrapper<Employee>() .eq("gender",0) .orderBy("age")//直接orderby 是升序,asc .last("desc limit 1,3")//在sql语句后面追加last里面的内容(改为降序,同时分页) );
select ······ order by desc limit 1, 3
,追加了desc limit 1,3
所以可以进行降序排序和分页。参考文献:
https://blog.csdn.net/bird_tp/article/details/105587582
https://www.jianshu.com/p/52600e85af64
https://www.jianshu.com/p/c5537559ae3a(非常推荐)
https://www.jianshu.com/p/ceb1df475021(非常非常推荐)
https://blog.csdn.net/llllllkkkkkooooo/article/details/108216957(非常推荐)
https://www.cnblogs.com/l-y-h/p/12859477.html----推荐
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2018-10-18 HTML的知识点讲解(HTML版本)