- 单表:Mybatis-Plus分页
- 单表:Plus的CRUD规范
- 单表:补充计数方法
- 单表:条件构造器Wrapper
- #allEq">#allEq
- #eq">#eq
- #ne">#ne
- #gt">#gt
- #ge">#ge
- #lt">#lt
- #le">#le
- #between">#between
- #notBetween">#notBetween
- #like">#like
- #notLike">#notLike
- #likeLeft">#likeLeft
- #likeRight">#likeRight
- #isNull">#isNull
- #isNotNull">#isNotNull
- #in">#in
- #notIn">#notIn
- #inSql">#inSql
- #notInSql">#notInSql
- #groupBy">#groupBy
- #orderByAsc">#orderByAsc
- #orderByDesc">#orderByDesc
- #orderBy">#orderBy
- #having">#having
- #func">#func
- #or">#or
- #and">#and
- #nested">#nested
- #apply">#apply
- #last">#last
- #exists">#exists
- #notExists">#notExists
单表:Mybatis-Plus分页
单表查询时建议使用:借助的是Page类与Wrapper接口实现
单表分页:在IService里有分页查询接口叫Page<T> selectPage(Page<T> page);和Page<T> selectPage(Page<T> page, Wrapper<T> wrapper);
/*** <p>* 顶级 Service* </p>** @author hubin* @Date 2016-04-20*/public interface IService<T> {/*** <p>* 翻页查询* </p>** @param page 翻页对象* @return*/Page<T> selectPage(Page<T> page);/*** <p>* 翻页查询* </p>** @param page 翻页对象* @param wrapper 实体包装类 {@link Wrapper}* @return*/Page<T> selectPage(Page<T> page, Wrapper<T> wrapper);}由于是单表查询,不需定义连接查询的Mapper,用IService的Page<T> selectPage(Page<T> page, Wrapper<T> wrapper);即可@Overridepublic PageInfo<MsgLogConditionResponse> msgLogs(MsgLogConditionRequest msgLogConditionRequest) {Page page = new Page<>((msgLogConditionRequest.getCurrent() == null ? 1 : msgLogConditionRequest.getCurrent()), (msgLogConditionRequest.getSize() == null ? 10 : msgLogConditionRequest.getSize()));Boolean unRead = msgLogConditionRequest.getUnRead();String sceneType = msgLogConditionRequest.getSceneType();System.out.println("sceneType:"+sceneType);//分页列表SQL,if-test控制是否执行过滤Page resPage = selectPage(page, new EntityWrapper<MsgLog>().eq(unRead, MsgLog.CONST_MSG_STATE, MsgLog.HAVED_NO_READ).eq(StringUtils.isNotBlank(sceneType), MsgLog.CONST_SCENE_TYPE, sceneType).eq(MsgLog.CONST_STATUS, MsgLog.DELETE_STATUS_VALIDATED));List<MsgLog> records = resPage.getRecords();ArrayList<MsgLogConditionResponse> responses = new ArrayList<>();for (MsgLog msgLog : records) {MsgLogConditionResponse msgLogConditionResponse = new MsgLogConditionResponse();msgLogConditionResponse.setMsgContent(msgLog.getMsgContent());msgLogConditionResponse.setReceiveTime(msgLog.getReceiveTime());msgLogConditionResponse.setSceneType(msgLog.getSceneType());msgLogConditionResponse.setMsgStatus(msgLog.getMsgState());responses.add(msgLogConditionResponse);}return new PageInfo<>(page.getCurrent(), page.getSize(), page.getTotal(), responses);}
遇到连表分页就自定义连接查询的Mapper,即手写SQL
public interface VmInstanceApplicationMapper extends BaseMapper<VmInstanceApplication> {/*** 申请列表* @param page* @param params* @return*/List<VmInstanceApplicationResponse> applicationList(Page page, VmInstanceApplicationRequest params);}#SQL无需手动分页了<select id="applicationList" parameterType="com.iwhalecloud.aiFactory.aiDevCenter.application.vo.VmInstanceApplicationRequest" resultType="com.iwhalecloud.aiFactory.aiDevCenter.application.vo.VmInstanceApplicationResponse">SELECTvm.name vmName,t.id, t.vm_instance, t.duration, t.application_desc, t.create_user_id, t.create_time, t.auditor, t.audit_desc, t.audit_time, t.com_acct_id, t.application_statusFROMvm_instance_application tLEFT JOIN vm_instance vm ON t.vm_instance = vm.idWHERE1 = 1<if test="createUserId != null">AND t.create_user_id = #{createUserId}</if><if test="applicationStatus != null and applicationStatus != ''">AND t.application_status = #{applicationStatus}</if><if test="vmName != null and vmName != ''">AND vm.name LIKE concat('%', #{vmName}, '%')</if><if test="vmInstance != null">AND t.vm_instance = #{vmInstance}</if><if test="comAcctId != null">AND t.com_acct_id = #{comAcctId}</if><if test="applicationStatusList != null and applicationStatusList.size() > 0">AND t.application_status in<foreach collection="applicationStatusList" item="one" open="(" close=")" separator=",">#{one}</foreach></if>ORDER BYcreate_time DESC</select>
单表:Plus的CRUD规范
单操作|条件操作|批量操作使用规范:
BaseMapper只有单条插入,在IService里有批量插入接口叫insertBatchBaseMapper只有单条删除,在IService里有批量删除接口叫deleteBatchIdsBaseMapper只有单条修改,在IService里有批量删除接口叫updateBatchById- 其实
BaseMapper里面的条件删除,条件修改也可以构造批量操作条件,但是直接使用IService里面现成的批量操作更方便,推荐!
BaseMapper里面的条件查询十分好用List<T> selectList(@Param("ew") Wrapper<T> wrapper);IService里的批量ids查询很方便List<T> selectBatchIds(Collection<? extends Serializable> idList);增
单增
public interface BaseMapper<T> {/*** <p>* 插入一条记录* </p>** @param entity 实体对象* @return int*/Integer insert(T entity);}
返回ID
```java MyBatis-Plus 新增插入成功并返回自增Id:调用完insert方法后,直接 entity.getId() 即可
taiModelChangeMapper.insert(taiModelChange); //得到mybatis-plus的自增id Integer id = taiModelChange.getId(); System.out.println(“得到mybatis-plus的自增id “+id);
<a name="MWnGV"></a>### 批量增`BaseMapper`只有单条插入,在`IService`里有批量插入接口叫`insertBatch````shellpublic interface IService<T> {/*** <p>* 插入(批量),该方法不适合 Oracle* </p>** @param entityList 实体对象列表* @return boolean*/boolean insertBatch(List<T> entityList);}
删
单删deleteById
public interface BaseMapper<T> {/*** <p>* 根据 ID 删除* </p>** @param id 主键ID* @return int*/Integer deleteById(Serializable id);}
条件删
public interface BaseMapper<T> {/*** <p>* 根据 entity 条件,删除记录* </p>** @param wrapper 实体对象封装操作类(可以为 null)* @return int*/Integer delete(@Param("ew") Wrapper<T> wrapper);}
批量删
BaseMapper只有单条删除,在IService里有批量删除接口叫deleteBatchIds
public interface IService<T> {/*** <p>* 删除(根据ID 批量删除)* </p>** @param idList 主键ID列表* @return boolean*/boolean deleteBatchIds(Collection<? extends Serializable> idList);}
改
单改updateById
public interface BaseMapper<T> {/*** <p>* 根据 ID 修改* </p>** @param entity 实体对象* @return int*/Integer updateById(@Param("et") T entity);}
条件改
public interface BaseMapper<T> {/*** <p>* 根据 whereEntity 条件,更新记录* </p>** @param entity 实体对象* @param wrapper 实体对象封装操作类(可以为 null)* @return*/Integer update(@Param("et") T entity, @Param("ew") Wrapper<T> wrapper);}
批量改
BaseMapper只有单条修改,在IService里有批量删除接口叫updateBatchById
public interface IService<T> {/*** <p>* 根据ID 批量更新* </p>** @param entityList 实体对象列表* @return boolean*/boolean updateBatchById(List<T> entityList);}
查
单查
/*** <p>* 根据 ID 查询* </p>** @param id 主键ID* @return T*/T selectById(Serializable id);/*** <p>* 根据 entity 条件,查询一条记录* </p>** @param entity 实体对象* @return T*/T selectOne(@Param("ew") T entity);
条件查
public interface BaseMapper<T> {/*** <p>* 根据 entity 条件,查询全部记录* </p>** @param wrapper 实体对象封装操作类(可以为 null)* @return List<T>*/List<T> selectList(@Param("ew") Wrapper<T> wrapper);}
批量查
public interface IService<T> {/*** <p>* 查询(根据ID 批量查询)* </p>** @param idList 主键ID列表* @return List<T>*/List<T> selectBatchIds(Collection<? extends Serializable> idList);}
单表:补充计数方法
Plus计数可以不用分组
@Overridepublic MsgTaskListResponse getTaskCountsGroupByMsgType(){MsgTaskListResponse msgTaskListResponse = new MsgTaskListResponse();//平台消息计数Integer msgTaskPlatformCounts = msgTaskMapper.selectCount(new EntityWrapper<MsgTask>().eq(MsgTask.CONST_MSG_TYPE, MsgTask.CONST_MSGTYPE_PLATFORM));msgTaskListResponse.setPlatformCounts(msgTaskPlatformCounts);//企业消息计数Integer msgTaskEntCounts = msgTaskMapper.selectCount(new EntityWrapper<MsgTask>().eq(MsgTask.CONST_MSG_TYPE, MsgTask.CONST_MSGTYPE_ENT));msgTaskListResponse.setEntCounts(msgTaskEntCounts);// 所有消息计数Integer sumCounts = msgTaskMapper.selectCount(new EntityWrapper<>());msgTaskListResponse.setSumCounts(sumCounts);return msgTaskListResponse;}
单表:条件构造器Wrapper
情况说明:<mybatisplus-starter.version>2.1.9</mybatisplus-starter.version>
Wrapper是EntityWrapper的父类- 用于生成 sql 的 where 条件, entity 属性也用于生成 sql 的 where 条件
- 注意: entity 生成的 where 条件与 使用各个 api 生成的 where 条件没有任何关联行为
```java
/**
- Copyright (c) 2011-2014, hubin (jobob@qq.com).
- Licensed under the Apache License, Version 2.0 (the “License”); you may not
- use this file except in compliance with the License. You may obtain a copy of
- the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an “AS IS” BASIS, WITHOUT
- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- License for the specific language governing permissions and limitations under
- the License. */ package com.baomidou.mybatisplus.mapper;
import com.baomidou.mybatisplus.toolkit.StringUtils;
/**
- Entity 对象封装操作类,定义T-SQL语法
- *
- @author hubin , yanghu , Dyang , Caratacus
@Date 2016-11-7 */ @SuppressWarnings(“serial”) public class EntityWrapper
extends Wrapper { /**
数据库表映射实体类 */ protected T entity = null;
public EntityWrapper() { / 注意,传入查询参数 / }
public EntityWrapper(T entity) { this.entity = entity; }
public EntityWrapper(T entity, String sqlSelect) { this.entity = entity; this.sqlSelect = sqlSelect; }
@Override public T getEntity() { return entity; }
public void setEntity(T entity) { this.entity = entity; }
/**
SQL 片段 / @Override public String getSqlSegment() { /
无条件 */ String sqlWhere = sql.toString(); if (StringUtils.isEmpty(sqlWhere)) { return null; }
/*
- 根据当前实体判断是否需要将WHERE替换成 AND 增加实体不为空但所有属性为空的情况 */ return isWhere != null ? (isWhere ? sqlWhere : sqlWhere.replaceFirst(“WHERE”, AND_OR)) : sqlWhere.replaceFirst(“WHERE”, AND_OR); }
}
使用示例:```javaDate date = new Date();List<MsgTask> msgTasks = msgTaskMapper.selectList(new EntityWrapper<MsgTask>().lt(MsgTask.CONST_SEND_TIME,date).eq(MsgLog.CONST_SEND_STATE,MsgLog.SEND_STATUS_FAILED));
使用示例:if-test
Wrapper的第一个入参boolean condition表示该条件是否加入最后生成的sql中,类似于MybatisXML的if-test标签,例如:
@Overridepublic List<MsgLogConditionResponse> msgLogs(MsgLogConditionRequest msgLogConditionRequest) {Page<MsgLog> page = new Page<>();if (msgLogConditionRequest.getSize() != null) {page.setSize(msgLogConditionRequest.getSize());}if (msgLogConditionRequest.getCurrent() != null) {page.setCurrent(msgLogConditionRequest.getCurrent());}Boolean unRead = msgLogConditionRequest.getUnRead();String sceneType = msgLogConditionRequest.getSceneType();//分页列表SQL,if-test控制是否执行过滤Page<MsgLog> pageResult = selectPage(page, new EntityWrapper<MsgLog>().eq(unRead, MsgLog.CONST_MSG_STATE, MsgLog.HAVED_NO_READ).eq(StringUtils.isNotBlank(sceneType), MsgLog.CONST_SCENE_TYPE, sceneType));List<MsgLog> msgLogs = pageResult.getRecords();ArrayList<MsgLogConditionResponse> responses = new ArrayList<>();for (MsgLog msgLog : msgLogs) {MsgLogConditionResponse msgLogConditionResponse = new MsgLogConditionResponse();msgLogConditionResponse.setMsgContent(msgLog.getMsgContent());msgLogConditionResponse.setReceiveTime(msgLog.getReceiveTime());msgLogConditionResponse.setSceneType(msgLog.getSceneType());msgLogConditionResponse.setMsgStatus(msgLog.getMsgState());responses.add(msgLogConditionResponse);}return responses;}
警告:
- wrapper 很重,不支持以及不赞成在 RPC 调用中把 Wrapper 进行传输
- 传输 wrapper 可以类比为你的 controller 用 map 接收值(开发一时爽,维护火葬场)
- 正确的 RPC 调用姿势是写一个 DTO 进行传输,被调用方再根据 DTO 执行相应的操作
- 我们拒绝接受任何关于 RPC 传输 Wrapper 报错相关的 issue 甚至 pr
#allEq
allEq(Map<R, V> params)allEq(Map<R, V> params, boolean null2IsNull)allEq(boolean condition, Map<R, V> params, boolean null2IsNull)
- 全部eq(或个别isNull)个别参数说明:
params:key为数据库字段名,value为字段值null2IsNull: 为true则在map的value为null时调用 isNull 方法,为false时则忽略value为null的 - 例1:
allEq({id:1,name:"老王",age:null})—->id = 1 and name = '老王' and age is null - 例2:
allEq({id:1,name:"老王",age:null}, false)—->id = 1 and name = '老王'
allEq(BiPredicate<R, V> filter, Map<R, V> params)allEq(BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull)allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull)
个别参数说明:filter : 过滤函数,是否允许字段传入比对条件中params 与 null2IsNull : 同上
- 例1:
allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null})—->name = '老王' and age is null - 例2:
allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null}, false)—->name = '老王'#eq
eq(R column, Object val)eq(boolean condition, R column, Object val)
- 等于 =
- 例:
eq("name", "老王")—->name = '老王'#ne
ne(R column, Object val)ne(boolean condition, R column, Object val)
- 不等于 <>
- 例:
ne("name", "老王")—->name <> '老王'#gt
gt(R column, Object val)gt(boolean condition, R column, Object val)
- 大于 >
- 例:
gt("age", 18)—->age > 18#ge
ge(R column, Object val)ge(boolean condition, R column, Object val)
- 大于等于 >=
- 例:
ge("age", 18)—->age >= 18#lt
lt(R column, Object val)lt(boolean condition, R column, Object val)
- 小于 <
- 例:
lt("age", 18)—->age < 18#le
le(R column, Object val)le(boolean condition, R column, Object val)
- 小于等于 <=
- 例:
le("age", 18)—->age <= 18#between
between(R column, Object val1, Object val2)between(boolean condition, R column, Object val1, Object val2)
- BETWEEN 值1 AND 值2
- 例:
between("age", 18, 30)—->age between 18 and 30#notBetween
notBetween(R column, Object val1, Object val2)notBetween(boolean condition, R column, Object val1, Object val2)
- NOT BETWEEN 值1 AND 值2
- 例:
notBetween("age", 18, 30)—->age not between 18 and 30#like
like(R column, Object val)like(boolean condition, R column, Object val)
- LIKE ‘%值%’
- 例:
like("name", "王")—->name like '%王%'#notLike
notLike(R column, Object val)notLike(boolean condition, R column, Object val)
- NOT LIKE ‘%值%’
- 例:
notLike("name", "王")—->name not like '%王%'#likeLeft
likeLeft(R column, Object val)likeLeft(boolean condition, R column, Object val)
- LIKE ‘%值’
- 例:
likeLeft("name", "王")—->name like '%王'#likeRight
likeRight(R column, Object val)likeRight(boolean condition, R column, Object val)
- LIKE ‘值%’
- 例:
likeRight("name", "王")—->name like '王%'#isNull
isNull(R column)isNull(boolean condition, R column)
- 字段 IS NULL
- 例:
isNull("name")—->name is null#isNotNull
isNotNull(R column)isNotNull(boolean condition, R column)
- 字段 IS NOT NULL
- 例:
isNotNull("name")—->name is not null#in
in(R column, Collection<?> value)in(boolean condition, R column, Collection<?> value)
- 字段 IN (value.get(0), value.get(1), …)
- 例:
in("age",{1,2,3})—->age in (1,2,3)
in(R column, Object... values)in(boolean condition, R column, Object... values)
- 字段 IN (v0, v1, …)
- 例:
in("age", 1, 2, 3)—->age in (1,2,3)#notIn
notIn(R column, Collection<?> value)notIn(boolean condition, R column, Collection<?> value)
- 字段 NOT IN (value.get(0), value.get(1), …)
- 例:
notIn("age",{1,2,3})—->age not in (1,2,3)
notIn(R column, Object... values)notIn(boolean condition, R column, Object... values)
- 字段 NOT IN (v0, v1, …)
- 例:
notIn("age", 1, 2, 3)—->age not in (1,2,3)#inSql
inSql(R column, String inValue)inSql(boolean condition, R column, String inValue)
- 字段 IN ( sql语句 )
- 例:
inSql("age", "1,2,3,4,5,6")—->age in (1,2,3,4,5,6) - 例:
inSql("id", "select id from table where id < 3")—->id in (select id from table where id < 3)#notInSql
notInSql(R column, String inValue)notInSql(boolean condition, R column, String inValue)
- 字段 NOT IN ( sql语句 )
- 例:
notInSql("age", "1,2,3,4,5,6")—->age not in (1,2,3,4,5,6) - 例:
notInSql("id", "select id from table where id < 3")—->id not in (select id from table where id < 3)#groupBy
groupBy(R... columns)groupBy(boolean condition, R... columns)
- 分组:GROUP BY 字段, …
- 例:
groupBy("id", "name")—->group by id,name
与SQL分组同理:满足“SELECT子句中的列名必须为分组列或列函数”
@Overridepublic MsgTaskSendLogConditionResponse getSendDetailGroup(MsgTaskSendLogConditionRequest msgTaskSendLogConditionRequest) {MsgTaskSendLogConditionResponse msgTaskSendLogConditionResponse = new MsgTaskSendLogConditionResponse();Integer msgTaskId = msgTaskSendLogConditionRequest.getMsgTaskId();//查询Page page = new Page<>((msgTaskSendLogConditionRequest.getCurrent() == null ? 1 : msgTaskSendLogConditionRequest.getCurrent()), (msgTaskSendLogConditionRequest.getSize() == null ? 10 : msgTaskSendLogConditionRequest.getSize()));msgTaskMapper.getSendDetailPage(page, msgTaskSendLogConditionRequest);msgTaskSendLogConditionResponse.setCountsOfSended(page.getTotal());//logs表单表,countsOfSuccess;分组List<MsgLog> msgLogSuccess = msgLogMapper.selectList(new EntityWrapper<MsgLog>().setSqlSelect(MsgLog.CONST_SEND_STATE + ",count(*) AS counts_of_success").eq(MsgLog.CONST_SEND_STATE, MsgLog.SEND_STATUS_SUCCESS).eq(MsgLog.CONST_STATUS, MsgLog.DELETE_STATUS_VALIDATED).groupBy(MsgLog.CONST_SEND_STATE));msgTaskSendLogConditionResponse.setCountsOfSuccess(msgLogSuccess.size() == 0 ? 0 : msgLogSuccess.get(0).getCountsOfSuccess());//logs表单表,countsOfFailed;分组List<MsgLog> msgLogFailed = msgLogMapper.selectList(new EntityWrapper<MsgLog>().setSqlSelect(MsgLog.CONST_SEND_STATE + ",count(*) AS counts_of_failed").eq(MsgLog.CONST_SEND_STATE, MsgLog.SEND_STATUS_FAILED).eq(MsgLog.CONST_STATUS, MsgLog.DELETE_STATUS_VALIDATED).groupBy(MsgLog.CONST_SEND_STATE));msgTaskSendLogConditionResponse.setCountsOfFailed(msgLogFailed.size() == 0 ? 0 : msgLogFailed.get(0).getCountsOfFailed());//logs表单表,countsOfReaded;分组List<MsgLog> msgLogReaded = msgLogMapper.selectList(new EntityWrapper<MsgLog>().setSqlSelect(MsgLog.CONST_SEND_STATE + ",count(*) AS counts_of_readed").eq(MsgLog.CONST_MSG_STATE, MsgLog.HAVED_READ).eq(MsgLog.CONST_STATUS, MsgLog.DELETE_STATUS_VALIDATED).groupBy(MsgLog.CONST_SEND_STATE));msgTaskSendLogConditionResponse.setCountsOfReaded(msgLogReaded.size() == 0 ? 0 : msgLogReaded.get(0).getCountsOfReaded());return msgTaskSendLogConditionResponse;}
其中setSqlSelect的SQL里的counts_of_success和counts_of_failed和counts_of_readed:注意是下划线
//logs表单表,countsOfSuccess;分组List<MsgLog> msgLogSuccess = msgLogMapper.selectList(new EntityWrapper<MsgLog>().setSqlSelect(MsgLog.CONST_SEND_STATE + ",count(*) AS counts_of_success").eq(MsgLog.CONST_SEND_STATE, MsgLog.SEND_STATUS_SUCCESS).eq(MsgLog.CONST_STATUS, MsgLog.DELETE_STATUS_VALIDATED).groupBy(MsgLog.CONST_SEND_STATE));msgTaskSendLogConditionResponse.setCountsOfSuccess(msgLogSuccess.size() == 0 ? 0 : msgLogSuccess.get(0).getCountsOfSuccess());
需要在Entity配置额外的统计字段counts_of_success,counts_of_failed,counts_of_readed
@TableField(exist = false)private static final long serialVersionUID = 1L;@TableField(exist = false)public Integer countsOfSuccess;@TableField(exist = false)public Integer countsOfFailed;@TableField(exist = false)public Integer countsOfReaded;
#orderByAsc
orderByAsc(R... columns)orderByAsc(boolean condition, R... columns)
- 排序:ORDER BY 字段, … ASC
- 例:
orderByAsc("id", "name")—->order by id ASC,name ASC#orderByDesc
orderByDesc(R... columns)orderByDesc(boolean condition, R... columns)
- 排序:ORDER BY 字段, … DESC
例:
orderByDesc("id", "name")—->order by id DESC,name DESC#orderBy
orderBy(boolean condition, boolean isAsc, R... columns)
排序:ORDER BY 字段, …
- 例:
orderBy(true, true, "id", "name")—->order by id ASC,name ASC#having
having(String sqlHaving, Object... params)having(boolean condition, String sqlHaving, Object... params)
- HAVING ( sql语句 )
- 例:
having("sum(age) > 10")—->having sum(age) > 10 - 例:
having("sum(age) > {0}", 11)—->having sum(age) > 11#func
func(Consumer<Children> consumer)func(boolean condition, Consumer<Children> consumer)
- func 方法(主要方便在出现if…else下调用不同方法能不断链)
- 例:
func(i -> if(true) {i.eq("id", 1)} else {i.ne("id", 1)})#or
or()or(boolean condition)
- 拼接 OR注意事项:
主动调用or表示紧接着下一个方法不是用and连接!(不调用or则默认为使用and连接) - 例:
eq("id",1).or().eq("name","老王")—->id = 1 or name = '老王'
or(Consumer<Param> consumer)or(boolean condition, Consumer<Param> consumer)
- OR 嵌套
- 例:
or(i -> i.eq("name", "李白").ne("status", "活着"))—->or (name = '李白' and status <> '活着')#and
and(Consumer<Param> consumer)and(boolean condition, Consumer<Param> consumer)
- AND 嵌套
- 例:
and(i -> i.eq("name", "李白").ne("status", "活着"))—->and (name = '李白' and status <> '活着')#nested
nested(Consumer<Param> consumer)nested(boolean condition, Consumer<Param> consumer)
- 正常嵌套 不带 AND 或者 OR
- 例:
nested(i -> i.eq("name", "李白").ne("status", "活着"))—->(name = '李白' and status <> '活着')#apply
apply(String applySql, Object... params)apply(boolean condition, String applySql, Object... params)
- 拼接 sql注意事项:
该方法可用于数据库函数 动态入参的params对应前面applySql内部的{index}部分.这样是不会有sql注入风险的,反之会有! - 例:
apply("id = 1")—->id = 1 - 例:
apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")—->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'") - 例:
apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08")—->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")#last
last(String lastSql)last(boolean condition, String lastSql)
- 无视优化规则直接拼接到 sql 的最后
- 注意事项:只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用
- 例:
last("limit 1")#exists
exists(String existsSql)exists(boolean condition, String existsSql)
- 拼接 EXISTS ( sql语句 )
- 例:
exists("select id from table where age = 1")—->exists (select id from table where age = 1)#notExists
notExists(String notExistsSql)notExists(boolean condition, String notExistsSql)
- 拼接 NOT EXISTS ( sql语句 )
- 例:
notExists("select id from table where age = 1")—->not exists (select id from table where age = 1)
