一、Wrapper 介绍
MyBatis Plus 通过 Wrapper 来构造查询条件,实现条件读操作或者条件写操作。
Wrapper的抽象子类AbstractWrapper中定义了各种条件参数
拼接SQL语句使用的是数据库字段,而不是Java实体类的属性
AbstractWrapper中所有查询条件的含义可以查看官方文档中的 条件构造器
二、条件查询
前期准备
修改insert方法,往t_tesla表中插入数据
@Test public void insert(){ for (int i = 4; i < 40; i++) { Tesla tesla = new Tesla(); tesla.setVehicleName("Model " + i); tesla.setVehicleType("Compact Car"); if (i % 2 == 0) { tesla.setFactory("Fremont Gigafactory"); } else { tesla.setFactory("Shanghai Gigafactory"); } tesla.setVehiclePrice(23000d + i * 10000); teslaMapper.insert(tesla); } } 复制代码
执行该方法,即可往数据库中插入数据
实现条件查询
BaseMapper中的selectList以及selectCount方法
/** * 根据 entity 条件,查询全部记录 * * @param queryWrapper 实体对象封装操作类(可以为 null) */ List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); /** * 根据 Wrapper 条件,查询总记录数 * * @param queryWrapper 实体对象封装操作类(可以为 null) */ Long selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); 复制代码
需求:查询所有弗拉蒙特工厂生产的Compact Car车型的Tesla
@Test public void selectListWithWrapper(){ // 构造查询条件 QueryWrapper<Tesla> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("factory", "Fremont Gigafactory") // 添加or关键字 .or() .eq("vehicle_type","Compact Car"); List<Tesla> teslaList = teslaMapper.selectList(queryWrapper); System.out.println("查询到的总数为:" + teslaList.size()); } 复制代码
执行该方法
查看or方法的源码
实现selectCount测试方法
@Test public void selectCountWithWrapper(){ // 构造查询条件 QueryWrapper<Tesla> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("factory", "Shanghai Gigafactory") .eq("vehicle_type","Compact Car"); Long count = teslaMapper.selectCount(queryWrapper); System.out.println("查询到符合条件的总数为:" + count); } 复制代码
执行该方法
实现分页条件查询
需求:分页查询所有上海工厂生产并且价格在230000和3000000之间的Tesla
@Test public void selectPageWithWrapper(){ // 构造查询条件 QueryWrapper<Tesla> teslaWrapper = new QueryWrapper<>(); teslaWrapper.between("price",230000,3000000) .eq("factory","Shanghai Gigafactory"); // 构造分页条件 Page<Tesla> teslaPageCondition = new Page<>(2,4); Page<Tesla> teslaPage = teslaMapper.selectPage(teslaPageCondition, teslaWrapper); System.out.println("分页条件查询的数据:" + teslaPage.getRecords()); System.out.println("分页条件查询到的记录总数:" + teslaPage.getTotal()); } 复制代码
执行该方法
三、条件更新
BaseMapper中的条件更新方法
/** * 根据 whereEntity 条件,更新记录 * * @param entity 实体对象 (set 条件值,可以为 null) * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句) */ int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper); 复制代码
需求:将所有价格为113000.00以上的并且是上海工厂生产的Tesla的价格调整为113000.00
@Test public void updateWithWrapper(){ // 构造更新条件 UpdateWrapper<Tesla> updateWrapper = new UpdateWrapper<>(); updateWrapper.gt("price",113000.00) .eq("factory","Shanghai Gigafactory") .set(true,"price",113000.00); int updateCount = teslaMapper.update(null, updateWrapper); System.out.println("更新的行数为:" + updateCount); } 复制代码
执行该方法
update方法传入一个实体类
@Test public void updateWithWrapper(){ // 构造更新条件 UpdateWrapper<Tesla> updateWrapper = new UpdateWrapper<>(); updateWrapper.gt("price",100000.00) .eq("factory","Shanghai Gigafactory") .set(true,"price",100000.00); Tesla tesla = new Tesla(); tesla.setFactory("Shanghai Gigafactory"); tesla.setVehiclePrice(100000.00); tesla.setVehicleType("Roadster"); tesla.setVehicleName("Tesla Roadster"); int updateCount = teslaMapper.update(tesla, updateWrapper); System.out.println("更新的行数为:" + updateCount); } 复制代码
update传入一个实体类
根据执行的SQL语句来看,MyBatis Plus将传入的实体类的属性值作为更新后的字段的值,SQL语句中set关键字后面有两个price=?,说明UpdateWrapper的set方法设置的更新字段的值没有被实体类的price覆盖。
如果更新的更新的字段比较少,可以在QueryWrapper中使用set方法进行设置更新后的字段的值,如果需要更新的字段比较多,建议new一个对象,将需要更新的字段值设置到对象对应的属性中去。
四、条件删除
BaseMapper中的条件删除方法
/** * 根据 entity 条件,删除记录 * * @param queryWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句) */ int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); 复制代码
需求:删除上海工厂生产的价格大于90000的Tesla
@Test public void deleteWithWrapper(){ QueryWrapper<Tesla> queryWrapper = new QueryWrapper(); queryWrapper.eq("factory", "Shanghai Gigafactory") .gt("price","90000.00"); int deleteCount = teslaMapper.delete(queryWrapper); System.out.println("删除的数量为:" + deleteCount); } 复制代码
执行该方法
五、Wrapper 的其他常用方法
排序
排序的条件可以是单个条件也可以是一个集合
@Test public void selectPageByWrapperAndSortByPrice(){ // 排序条件的集合 List<String> orderConditionList = new ArrayList<>(); orderConditionList.add("price"); orderConditionList.add("name"); // 对所有弗拉蒙特工厂生产的Tesla按照价格降序排列 QueryWrapper<Tesla> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("factory","Fremont Gigafactory") .orderByDesc(orderConditionList); Page<Tesla> teslaPageCondition = new Page<>(2,5); Page<Tesla> teslaPage = teslaMapper.selectPage(teslaPageCondition, queryWrapper); System.out.println("分页查询并降序排列的数据:" + teslaPage.getRecords()); } 复制代码
执行该方法
拼接SQL
last方法可以在SQL末尾进行拼接SQL
@Test public void selectListByLastInWrapper(){ QueryWrapper<Tesla> queryWrapper = new QueryWrapper<>(); queryWrapper.last("ORDER BY price"); List<Tesla> teslaList = teslaMapper.selectList(queryWrapper); System.out.println("last方法拼接SQL查询到的数据:" + teslaList); } 复制代码
执行该方法
六、Wrapper 总结
对于查询和删除操作可以使用QueryWrapper构造条件,对于更新可以使用UpdateWrapper构造条件。
在通用Mapper以及MyBatis MBG生成的方法中会包含Criteria查询,既QBC查询,通过生成实体类XxxExaple来构建查询条件,具体可以查看 Data Access 之 MyBatis(八)- MyBatis 通用 Mapper(Part B)中的 ”通用Mapper实现复杂查询-ExampleMapper“
两者的区别:
- MBG或者通用Mapper的条件查询不同的地方在于MBG构造条件使用的是
XxxExample中的属性也就是实体类的属性
。 - MyBatis Plus构造查询条件使用的是
数据库的字段
。