一、条件构造器常用方法
以下语法可以查询大全,会用即可:
LambdaQueryWrapper<GuideLimit> wrapper = new LambdaQueryWrapper();
wrapper.isNull(GuideLimit::getDescription);//为空
wrapper.isNotNull(GuideLimit::getDescription);//不为空
wrapper.ge(GuideLimit::getDeleted,1);//大于等于1
wrapper.between(GuideLimit::getGuideLimitId,1,10);//在1到10之间,包含关系
wrapper.like(GuideLimit::getUnitName,"合肥");//模糊查询
wrapper.likeRight(GuideLimit::getUnitName,"合肥");//左匹配
wrapper.likeLeft(GuideLimit::getUnitName,"大学");//右匹配
wrapper.inSql(GuideLimit::getGuideLimitId,"select guide_limit_id from lztxjsj_guide_limit where guide_limit_id = 1");//插入sql
List<GuideLimit> users = guideLimitService.list(wrapper);
二、Iservice crud相关方法
1、get相关
//SERVICE的CRUD接口
//get相关
//1、getById 根据id返回一个对象,如果有字段加了@TableLogic,或获取此字段为0的数据,如果没有字段加@TableLogic这个注解,就查符合条件的数据
// 没有会返回null,不会报错
GuideLimit byId = guideLimitService.getById(88L);
//2、getOne,两种传参
GuideLimit one = guideLimitService.getOne(wrapper);//直接传wrapper,返回一个对象,如果存在多个报错
GuideLimit one1 = guideLimitService.getOne(wrapper, false);//前面传wrapper,后面传boolean值,如果不传默认true,设置为false会从多条数据中取第一个,没有就是null
//3、getMap
Map<String, Object> map = guideLimitService.getMap(wrapper);//根据条件查询结果,然后将对象转成map,数据库中的字段名就是key,存在多个就返回第一个
//4、getObj
Object obj = guideLimitService.getObj(wrapper, (o) -> {
return Integer.parseInt(o.toString());
});//根据条件查询结果,不过只返回一个字段,有主键返回主键值(需要加上主键注解),没有主键返回类中设置的第一个字段,后面是转换函数,用来指定返回值的类型,如果类型转换不了会报错。
//5、获取baseMapper也就DAO层继承的那个接口,不过一般都自动注入DAO层,所以不需要这样获取
BaseMapper<GuideLimit> baseMapper = guideLimitService.getBaseMapper();
//6、获取实体类的Class对象
Class<GuideLimit> entityClass = guideLimitService.getEntityClass();
2、list相关
//list相关
//1、list() 查询所有,如果有字段加了@TableLogic,就会排除此字段不为0的注解,如果没有就差所有
//2、list(wrapper),查询符合条件的,排除@TableLogic字段不为0的数据
List<GuideLimit> list = guideLimitService.list();
List<GuideLimit> list1 = guideLimitService.list(wrapper);
//3、listObj()、listObjs(wrapper)、listObjs(mapper)、listObjs(wrapper, mapper)
List<Object> objects = guideLimitService.listObjs();//查询所有数据的列表但只返回一个字段,有主键注解的字段优先返回注解字段,没有优先返回类中第一个字段
List<Object> objects1 = guideLimitService.listObjs(wrapper);//查询符合条件数据的列表但只返回一个字段,有主键注解的字段优先返回注解字段,没有优先返回类中第一个字段
List<Integer> integers = guideLimitService.listObjs((o) -> {
return Integer.parseInt(o.toString());
});//查询所有数据的列表但只返回一个字段,并且按指定类型返回,类型转换要注意,转换不了会报错
List<Integer> integers1 = guideLimitService.listObjs(wrapper, (o) -> {
return Integer.parseInt(o.toString());
});//查询符合条件数据的列表但只返回一个字段,并且按指定类型返回,类型转换要注意,转换不了会报错
//4、listMaps()、listMaps(wrapper)
List<Map<String, Object>> maps = guideLimitService.listMaps();//查询所有,将每个对象都转成一个map,然后组成列表
List<Map<String, Object>> maps1 = guideLimitService.listMaps(wrapper);//根据条件查询列表,并将列表中每个数据都转成map
//5、listByMap(map) 根据map查询相关列表,map的key是数据库的字段名,如果key值写错会报错
Map map = new HashMap();
map.put("guide_limit_id","1");
List list2 = guideLimitService.listByMap(map);
//6、listByIds(ids) 根据主键id列表查询相关列表,没有加主键注解会报错
List ids = new ArrayList();
ids.add(88);
List list3 = guideLimitService.listByIds(ids);
3、remove相关
//remove相关(物理删除)
//1、remove(wrapper) 根据条件删除相关列表
guideLimitService.remove(wrapper);
//2、removeById()
guideLimitService.removeById(100000);//根据id删除
guideLimitService.removeById(guideLimit);//根据实体类id删除
guideLimitService.removeById(100000,false);//不太清楚,是否启用填充(为true的情况,会将入参转换实体进行delete删除),没太懂true和false的区别
//3、removeByIds() 批量删除,不太清楚后面传入true和false会有什么影响。
guideLimitService.removeByIds(ids);
guideLimitService.removeByIds(ids,false);
//4、removeBatchByIds(),可以传入ids,也可以传入实体类对象list,
guideLimitService.removeBatchByIds(list);
guideLimitService.removeBatchByIds(list,1);//这个size不确定具体含义,但是所有符合条件的都会删除
guideLimitService.removeBatchByIds(list,false);//不太确定true和false的含义
guideLimitService.removeBatchByIds(list,1,false);
//5、removeByMap(map) 根据map条件删除
guideLimitService.removeByMap(map);
4、update相关
//update相关
//1、.update()不传任何参数,返回UpdateChainWrapper<GuideLimit>类,返回的对象会将数据库中所有数据都进行选中,然后修改的内容会对所有的数据都生效
//也可以对选中的数据进行筛选,那么修改就会对筛选之后的数据都生效。
map.put("guide_limit_id","100001");
UpdateChainWrapper<GuideLimit> update = guideLimitService.update().allEq(map);
update.update(guideLimit);
//2、update(updateWrapper),要先有判断条件,不然就默认选中全部数据
updateWrapper.eq(GuideLimit::getGuideLimitId,100001L);
updateWrapper.set(GuideLimit::getName,"kkkkkk");
guideLimitService.update(updateWrapper);
//3、update(guideLimit,updateWrapper),首先updateWrapper中也必须先有筛选条件,不然会选中全部,而且第一个实体类参数中只参与修改,不会根据实体类进行查询
//如果updateWrapper中有set条件,会以updateWrapper中为准,其次的条件会根据实体类存在的字段为准进行更新,可以单独修改一些置空的数据
updateWrapper.eq(GuideLimit::getGuideLimitId,100001L);
updateWrapper.set(GuideLimit::getName,"kkkkkk");
guideLimitService.update(guideLimit,updateWrapper);
//4、updateById(guideLimit)根据id修改,updateBatchById(list)根据实体类列表批量修改
guideLimitService.updateById(guideLimit);
guideLimitService.updateBatchById(list);
//5、ktUpdate() 返回KtUpdateChainWrapper,不太理解,跟update()比较类似。
KtUpdateChainWrapper<GuideLimit> guideLimitKtUpdateChainWrapper = guideLimitService.ktUpdate();
//6、saveOrUpdate(guideLimit),根据实体类id修改或者保存,
guideLimitService.saveOrUpdate(guideLimit);
//7、saveOrUpdate(guideLimit,updateWrapper),修改原则如下:
//1)如果updateWrapper没有查询条件,就会对所有数据按照实体类进行修改,优先按照updateWrapper中设置的值进行修改
//2)如果updateWrapper有查询条件,而且查询的到,就会对查询到的数据按照实体类数据进行修改,也是优先按照updateWrapper中设置的值进行修改
//3)如果updateWrapper有查询条件,但是查不到,实体类中有id,且可以查到,就会实体类对应的数据单独修改
//4)如果updateWrapper有查询条件,查不到,且实体类中有id,但是查不到,就会对实体类按照id新增
//5)如果updateWrapper有查询条件,查不到,实体类中没有id,就会对实体类随机新增
guideLimitService.saveOrUpdate(guideLimit,updateWrapper);
//8、saveOrUpdateBatch(list),id存在的修改,id不存在的新增
guideLimitService.saveOrUpdateBatch(list);
5、insert相关
//save相关
//1、save(guideLimit),注意主键冲突
guideLimitService.save(guideLimit);
//2、save(list),批量保存
guideLimitService.saveBatch(list);
6、count
guideLimitService.count()
guideLimitService.count(wrapper)
7、分页查询
首先要明白Page与IPage的区别,Page实现了IPage,实际上就是对IPage进行了一个简单的封装,就是把各种基本参数都设定好了,所以如果直接使用Page只需要指定pageIndex(页码)、pageSize(个数)即可,如下最简单的分页查询:
Page page = new Page<Coupon>(1, 1);
LambdaQueryWrapper<Coupon> wrapper = new LambdaQueryWrapper<>();
wrapper.in(Coupon::getId,1,2);
couponService.page(page,wrapper);
、一般的实现方式是这样:IPage作为实现类型,
IPage<GuideLimit> page = new Page(1,10);
如果分页查询遇到类型转换,只需要重新new一个新的类型的对象即可,再将原来的分页对象set进新的对象中。
Page<ProjectPageRespDto> projectPageRespDtoPage = new Page<>();
projectPageRespDtoPage.setSize(projectPage.getSize());
projectPageRespDtoPage.setCurrent(projectPage.getCurrent());
projectPageRespDtoPage.setTotal(projectPage.getTotal());
projectPageRespDtoPage.setRecords(collect);
projectPageRespDtoPage.setPages(projectPage.getPages());
三、BaseMapper 基本方法
(基本跟IService的用法差不多)
//插入一条记录
int insert(T entity);
//根据 ID 删除
int deleteById(Serializable id);
//根据实体(ID)删除
int deleteById(T entity);
//根据 columnMap 条件(表字段),删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
//根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
//删除(根据ID或实体 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<?> idList);
//根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
/**
* 根据 whereEntity 条件,更新记录
*
* @param entity 实体对象 (set 条件值,可以为 null)
* @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
*/
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
//根据 ID 查询
T selectById(Serializable id);
//查询(根据ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
//查询(根据 columnMap 条件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
/**
* 根据 entity 条件,查询一条记录
* <p>查询一条记录,例如 qw.last("limit 1") 限制取一条记录, 注意:多条数据会报异常</p>
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
default T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper) {
List<T> ts = this.selectList(queryWrapper);
if (CollectionUtils.isNotEmpty(ts)) {
if (ts.size() != 1) {
throw ExceptionUtils.mpe("One record is expected, but the query result is multiple records");
}
return ts.get(0);
}
return null;
}
//根据 Wrapper 条件,判断是否存在记录
default boolean exists(Wrapper<T> queryWrapper) {
Long count = this.selectCount(queryWrapper);
return null != count && count > 0;
}
//根据 Wrapper 条件,查询总记录数
Long selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
//根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
//根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录
* <p>注意: 只返回第一个字段的值</p>
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 entity 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
<P extends IPage<T>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件
* @param queryWrapper 实体对象封装操作类
*/
<P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
四、复杂条件构造 wrapper
1、last()
无视规则直接拼接到sql的最后,但是只能调用一次,多次调用以最后一次为准,有sql注入的风险,谨慎使用
LambdaQueryWrapper<GuideLimit> wrapper = new LambdaQueryWrapper();
wrapper.in(GuideLimit::getGuideLimitId, Lists.newArrayList(1L, 2L, 3L));
wrapper.last("limit 1");
List<GuideLimit> list1 = guideLimitService.list(wrapper);
2、or()
wrapper.eq(GuideLimit::getGuideLimitId, 1).or().eq(GuideLimit::getGuideLimitId,2);
3、and()
wrapper.and( i->i.eq(GuideLimit::getUnitName,123).eq(GuideLimit::getName,888888)
.or().eq(GuideLimit::getUnitName,234).eq(GuideLimit::getName,888888));
4、groupby()
本项目中不能用,用了会报错,原因是因为mysql的myini文件中缺少:sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
五、使用mybatis-plus构建自定义sql
我们可以使用 ew进行简单的条件构造,简单理解:也就是说ew就相当于where+条件。
<select id="tableList" resultType="java.util.LinkedHashMap">
SELECT
${ew.sqlSelect} // 这里拼接select后面的语句
FROM
${table_name} //如果是单表的话,这里可以写死
${ew.customSqlSegment}
</select>
1、ew简单实现查询:
service:
LambdaQueryWrapper<GuideLimit> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(GuideLimit::getGuideLimitId,1L);
List<GuideLimit> list = guideLimitDao.selectByMyWrapper(wrapper);
DAO层:
/**
* 如果自定义的方法还希望能够使用MP提供的Wrapper条件构造器,则需要如下写法
* @param userWrapper
*/
@Select("SELECT * FROM lztxjsj_guide_limit1 ${ew.customSqlSegment}")
List<GuideLimit> selectByMyWrapper(@Param(Constants.WRAPPER) Wrapper<GuideLimit> userWrapper);
2、ew实现分页查询简单实现:
service:
Page<PersonnelVO> page = new Page<>(dto.getPageIndex(), dto.getPageSize());
LambdaQueryWrapper<Personnel> wrapper = buildWrapper(dto);
wrapper.orderByAsc(Personnel::getSerial);
page = personnelDao.pageByCondition(page, wrapper);
dao层:
@Select("select * from lztxjsj_personnel ${ew.customSqlSegment}")
Page<PersonnelVO> pageByCondition(Page<PersonnelVO> page, @Param(Constants.WRAPPER) Wrapper<Personnel> wrapper);
3、ew实现分表查询:
public Page<RelationUnitTopicVO> pageByCondition(RelationUnitTopicPageDTO dto) {
Page<RelationUnitTopicVO> page=new Page<>(dto.getPageIndex(),dto.getPageSize());
QueryWrapper<RelationUnitTopic> wrapper=buildQueryWrapper(dto);
wrapper.eq("zrut.topic_id",dto.getTopicId());
wrapper.orderByAsc("zrut.serial");
page=relationUnitTopicDao.pageByCondition(page,wrapper);
return page;
}
@Select(" select zrut.*,zpu.unit_name,zpu.unit_code,zpu.unit_properties,zpu.is_lose_faith " +
" from zdxm_relation_unit_topic zrut" +
" left join zdxm_participation_unit zpu " +
" on zrut.unit_id = zpu.unit_id" +
" ${ew.customSqlSegment}")
Page<RelationUnitTopicVO> pageByCondition(Page<RelationUnitTopicVO> page, @Param(Constants.WRAPPER) Wrapper<RelationUnitTopic> wrapper);