1.引入MybatisPlus的依賴
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatisplus-spring-boot-starter</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.1.4</version>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</exclusion>
</exclusions>
</dependency>
注: 用maven管理庫依賴,有個好處就是連同庫的依賴的全部jar檔案一起下載下傳,免去手工添加的麻煩,但同時也帶來了同一個jar會被下載下傳了不同版本的問題,好在pom的配置裡面允許用< exclusion >來排除一些不需要同時下載下傳的依賴jar 。
2.在application.yml檔案裡進行mybatisPlus的相關配置
mybatis-plus:
#外部化xml配置
mapper-locations: classpath:/mybatismapper/*Mapper.xml
#實體掃描,多個package用逗号或者分号分隔
type-aliases-package: com.chanjue.activiti.workflow.entities
#typeEnumsPackage: com.baomidou.springboot.entity.enums
global-config:
#主鍵類型 0:"資料庫ID自增", 1:"使用者輸入ID",2:"全局唯一ID (數字類型唯一ID)", 3:"全局唯一ID UUID";
id-type: 2
#字段政策 0:"忽略判斷",1:"非 NULL 判斷"),2:"非空判斷"
field-strategy: 2
#駝峰下劃線轉換
db-column-underline: false
#重新整理mapper 調試神器
refresh-mapper: true
#資料庫大寫下劃線轉換
#capital-mode: true
#序列接口實作類配置
#key-generator: com.baomidou.springboot.xxx
#邏輯删除配置
logic-delete-value: 1
logic-not-delete-value: 0
#自定義填充政策接口實作
meta-object-handler: com.wt.activiti.common.config.MybatisMetaObjectHandler
#自定義SQL注入器
sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
configuration:
map-underscore-to-camel-case: false
cache-enabled: false
注: 上面的配置是我在開發中所需用到的一些配置,如果還想配置其他的相關參數,請參考下面的資訊。
mybatis-plus:
#外部化xml配置
config-location: classpath:mybatis-config.xml
#指定外部化 MyBatis Properties 配置,通過該配置可以抽離配置,實作不同環境的配置部署
configuration-properties: classpath:mybatis/config.properties
#xml掃描,多個目錄用逗号或者分号分隔(告訴 Mapper 所對應的 XML 檔案位置)
mapper-locations: classpath*:/mapper/*.xml
#MyBaits 别名包掃描路徑,通過該屬性可以給包中的類注冊别名
type-aliases-package: net.xinhuamm.noah.api.model.entity,net.xinhuamm.noah.api.model.dto
#如果配置了該屬性,則僅僅會掃描路徑下以該類作為父類的域對象
type-aliases-super-type: java.lang.Object
#枚舉類 掃描路徑,如果配置了該屬性,會将路徑下的枚舉類進行注入,讓實體類字段能夠簡單快捷的使用枚舉屬性
type-enums-package: com.baomidou.mybatisplus.samples.quickstart.enums
#項目啟動會檢查xml配置存在(隻在開發時候打開)
check-config-location: true
#SIMPLE:該執行器類型不做特殊的事情,為每個語句的執行建立一個新的預處理語句,REUSE:該執行器類型會複用預處理語句,BATCH:該執行器類型會批量執行所有的更新語句
default-executor-type: REUSE
configuration:
# 是否開啟自動駝峰命名規則(camel case)映射,即從經典資料庫列名 A_COLUMN(下劃線命名) 到經典 Java 屬性名 aColumn(駝峰命名) 的類似映射
map-underscore-to-camel-case: false
# 全局地開啟或關閉配置檔案中的所有映射器已經配置的任何緩存,預設為 true
cache-enabled: false
#懶加載
aggressive-lazy-loading: true
#NONE:不啟用自動映射 PARTIAL:隻對非嵌套的 resultMap 進行自動映射 FULL:對所有的 resultMap 都進行自動映射
auto-mapping-behavior: partial
#NONE:不做任何處理 (預設值)WARNING:以日志的形式列印相關警告資訊 FAILING:當作映射失敗處理,并抛出異常和詳細資訊
auto-mapping-unknown-column-behavior: none
#如果查詢結果中包含空值的列,則 MyBatis 在映射的時候,不會映射這個字段
call-setters-on-nulls: true
# 這個配置會将執行的sql列印出來,在開發或測試的時候可以用
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
#表名下劃線命名預設true
table-underline: true
#id類型
id-type: auto
#是否開啟大寫命名,預設不開啟
capital-mode: false
#邏輯已删除值,(邏輯删除下有效) 需要注入邏輯政策LogicSqlInjector 以@Bean方式注入
logic-not-delete-value: 0
#邏輯未删除值,(邏輯删除下有效)
logic-delete-value: 1
#資料庫類型
db-type: sql_server
3.建立實體類
根據對應的資料庫表建立該表的實體類
@Data
@TableName("wf_v_todotask")
public class WfTodoTask {
@TableField("TASK_ID")
private String taskId;
@TableField("city_code")
private String cityCode;
@TableField("PROC_INST_ID")
private String procInstId;
@TableField("business_id")
private String businessId;
@TableField("ACT_ID")
private String actId;
}
4.使用MybatisPlus進行單表查詢
1.Service層的代碼書寫
1.首先建立一個EntityWrapper對象
2.再根據EntityWrapper建立相應的sql語句
3.再調用mapper層的方法,這裡面的方法都是mybatisPlus自動生成的
接口:
public interface WfTodoTaskService extends IService<WfTodoTask> {
List<WfTodoTask> getPagedList(WfTodoTaskQueryInDto input);
}
實作層:
public class WfTodoTaskServiceImpl extends ServiceImpl<WfTodoTaskRepository, WfTodoTask> implements WfTodoTaskService {
public List<WfTodoTask> getPagedList(WfTodoTaskQueryInDto input) {
//建立EntityWrapper對象
EntityWrapper<WfTodoTask> ew = new EntityWrapper<>();
//封裝查詢條件
ew.andNew();
ew.eq("city_code", input.getCityCode());
ew.eq(!StringUtils.isEmpty(input.getBusinessId()), "business_id", input.getBusinessId());
ew.eq(!StringUtils.isEmpty(input.getModelCode()), "model_code", input.getModelCode());
ew.eq(!StringUtils.isEmpty(input.getProcInstId()), "PROC_INST_ID", input.getProcInstId());
ew.eq(!StringUtils.isEmpty(input.getModelName()), "model_name", input.getModelName());
ew.like(!StringUtils.isEmpty(input.getProcFolio()), "proc_folio", input.getProcFolio());
ew.eq(!StringUtils.isEmpty(input.getActId()),"ACT_ID",input.getActId());
ew.like(!StringUtils.isEmpty(input.getActName()), "ACT_NAME", input.getActName());
ew.like(!StringUtils.isEmpty(input.getAssigneeName()), "ASSIGNEE_NAME", input.getAssigneeName());
ew.like(!StringUtils.isEmpty(input.getOrigiatorName()), "origiatorName", input.getOrigiatorName());
ew.ge(input.getProcStartDateBegin() != null,"proc_start_date",input.getProcStartDateBegin());
//調用mapper層的方法,這裡寫baseMapper或者this都是可以的,調用的都是WfTodoTaskRepository裡面的方法
List<WfTodoTask> list = baseMapper.selectList(ew);
return list;
}
}
注:
1.service層接口需要繼承IService<實體類>,這裡的service層實作類繼承ServiceImpl<mapper層的接口,實體類>的作用就是不用再在service類裡面注入mapper層的接口了,可以通過baseMapper.或者this.直接來調用mapper層接口的方法。
2.Mybatis-Plus通過EntityWrapper(簡稱EW,MP封裝的一個查詢條件構造器)或者Condition(與EW類似)來讓使用者自由的建構查詢條件,條件有很多,列出如下:
查詢方式 | 說明 |
---|---|
setSqlSelect | 設定SELECT查詢字段 |
where | WHERE語句,拼接 - WHERE條件 |
and | AND語句,拼接 - AND 字段=值 |
andNew | AND語句,拼接 - AND (字段=值) |
or | OR語句,拼接 - OR 字段=值 |
orNew | OR語句,拼接 - OR(字段=值) |
eq | 等于= |
allEq | 基于map内容等于= |
ne | 不等于<> |
gt | 大于> |
ge | 大于等于>= |
lt | 小于< |
le | 小于等于<= |
like | 模糊查詢LIKE |
notLike | 模糊查詢NOT LIKE |
in | IN查詢 |
notin | NOT IN查詢 |
isNull | NULL值查詢 |
isNotNull | IS NOT NULL |
groupBy | 分組GROUP BY |
having | HAVING關鍵詞 |
orderBy | 排序ORDER BY |
orderAsc | ASC排序ORDER BY |
orderDesc | DESC排序ORDER BY |
exists | EXISTS條件語句 |
notExists | NOT EXISTS條件語句 |
between | BETWEEN條件語句 |
notBetween | NOT BETWEEN條件語句 |
addFilter | 自由拼接SQL |
last | 拼接在最後,例如last(“LIMIT 1”) |
2.mapper層的代碼的書寫
@Repository
public interface WfTodoTaskRepository extends BaseMapper<WfTodoTask> {
//注解sql
@Update("update wfl.wf_v_todotask set act_name=#{newName} where act_id=#{actid}")
List<WfTodoTask> updateActName(String newName,Integer actid);
//非注解sql,對應xml檔案
List<WfTodoTask> getAllTask(Page<WfTodoTask> pager,WfTodoTaskQueryInDto input);
}
注::
1.這裡的mapper層接口我們要繼承BaseMapper這個類,這個類裡面的方法都是mybatisPlus自動生成的
2.BaseMapper裡面的所有方法都是針對WfTodoTask這個實體類所對應的資料庫表所生成的一系列方法,有時我們需要額外添加一些别的操作,我們就可以在這個WfTodoTaskRepository 接口裡按照以往的方式去寫一些我們需要的方法
3.要注意,xml檔案的位置要寫在我們先前在application.yml裡面所配置的路徑下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chanjue.activiti.workflow.repositories.WfTaskAgentFullRepository">
<resultMap id="WF_TaskAgentFullResultMap" type="com.chanjue.activiti.workflow.entities.WfTaskAgentFull">
<id property="id" column="id" />
<result column="assignee" property="assignee" />
<result column="attorney" property="attorney" />
<result column="attorneyName" property="attorneyName" />
<result column="startTime" property="startTime" />
<result column="endTime" property="endTime" />
<result column="processDefinitionKey" property="processDefinitionKey" />
<result column="processDefinition" property="processDefinition" />
<result column="status" property="status" />
<result column="gmtCreatedBy" property="gmtCreatedBy" />
<result column="gmtCreatedOn" property="gmtCreatedOn" />
<result column="gmtUpdatedBy" property="gmtUpdatedBy" />
<result column="gmtUpdatedOn" property="gmtUpdatedOn" />
<result column="gmtVersion" property="gmtVersion" />
</resultMap>
<select id="get" resultMap="WF_TaskAgentFullResultMap">
select a.assignee , a.attorney , a.attorneyName , a.startTime , a.endTime , a.processDefinitionKey , a.processDefinition , a.status , a.id , a.gmtCreatedBy , a.gmtCreatedOn , a.gmtUpdatedBy , a.gmtUpdatedOn , a.gmtVersion from wf_task_agent_full a
where a.id = #{id}
</select>
</mapper>
4.BaseMapper類裡面的方法說明
4.使用MybatisPlus進行分頁操作
1.Service層的代碼書寫
1.建立EntityWrapper類,自定義查詢條件,在 2.x版本用EntityWrapper,3.x版本用QueryWrapper
2.建立Page類,并設定偏移量和頁碼号
3.調用mybatisPlus的BaseMapper類裡面的selectPage方法,對資料進行分頁
注:這裡繼承ServiceImpl的目的就是為了可以在Service就可以使用MybatisPlus的方法,你可以通過this.或者baseMapper.的方式進行操作
public class WfTodoTaskServiceImpl extends ServiceImpl<WfTodoTaskRepository, WfTodoTask> implements WfTodoTaskService {
public List<WfTodoTask> getPagedList(WfTodoTaskQueryInDto input) {
//建立EntityWrapper對象
EntityWrapper<WfTodoTask> ew = new EntityWrapper<>();
//封裝查詢條件
ew.andNew();
ew.eq("city_code", input.getCityCode());
ew.eq(!StringUtils.isEmpty(input.getBusinessId()), "business_id", input.getBusinessId());
ew.eq(!StringUtils.isEmpty(input.getModelCode()), "model_code", input.getModelCode());
ew.eq(!StringUtils.isEmpty(input.getProcInstId()), "PROC_INST_ID", input.getProcInstId());
ew.eq(!StringUtils.isEmpty(input.getModelName()), "model_name", input.getModelName());
ew.like(!StringUtils.isEmpty(input.getProcFolio()), "proc_folio", input.getProcFolio());
ew.eq(!StringUtils.isEmpty(input.getActId()),"ACT_ID",input.getActId());
ew.like(!StringUtils.isEmpty(input.getActName()), "ACT_NAME", input.getActName());
ew.like(!StringUtils.isEmpty(input.getAssigneeName()), "ASSIGNEE_NAME", input.getAssigneeName());
ew.like(!StringUtils.isEmpty(input.getOrigiatorName()), "origiatorName", input.getOrigiatorName());
ew.ge(input.getProcStartDateBegin() != null,"proc_start_date",input.getProcStartDateBegin());
//建立Page類,設定頁碼和偏移量
Page<WfTodoTask> pager = new Page<WfTodoTask>(1,10);
//調用mapper層的方法,這裡寫baseMapper或者this都是可以的,調用的都是WfTodoTaskRepository裡面的方法
List<WfTodoTask> list= baseMapper.selectPage(pager,ew);
pager.setRecords(list);
//這個類是我定義的分頁查詢結果的傳回類
return new PagedResultOutput<WfTodoTask>(results.getTotal(), results.getCurrent(), results.getSize(), results.getRecords());
}
}
注::
1.mybatisPlus的BaseMapper類裡面的selectPage與selectList這兩個方法的差別就在于,一個傳遞了Page類作為參數,一個沒有,當我們以Page類作為參數進行傳參時,sql語句執行時,會執行兩條語句,一條會查詢出資料的總數目,一條會在sql語句的後面添加上limit以此來規定查出的具體資料,如下:
[BaseJdbcLogger.java : 159] :: ==> Preparing: SELECT COUNT(1) FROM wf_v_todotask WHERE (ASSIGNEE = ? OR CANDIDATE = ?) AND (city_code = ?)
[BaseJdbcLogger.java : 159] :: ==> Parameters: USER_10013_8165726(String), USER_10013_8165726(String), 320100(String)
[BaseJdbcLogger.java : 159] :: ==> Preparing: SELECT TASK_ID AS taskId,city_code AS cityCode,PROC_INST_ID AS procInstId,business_id AS businessId,ACT_ID AS actId,ACT_NAME AS actName,ASSIGNEE AS assignee,ASSIGNEE_NAME AS assigneeName,DELEGATION_ID AS delegationId,DESCRIPTION AS description,CREATE_TIME AS createTime,DUE_DATE AS dueDate,CANDIDATE AS candidate,CANDIDATE_NAME AS candidateName,FORM_KEY AS formKey,model_code AS modelCode,model_name AS modelName,origiator,origiatorName,proc_start_date AS procStartDate,proc_folio AS procFolio,proc_remark AS procRemark,model_category AS modelCategory FROM wf_v_todotask WHERE (ASSIGNEE = ? OR CANDIDATE = ?) AND (city_code = ?) ORDER BY CREATE_TIME DESC LIMIT 0,10
[BaseJdbcLogger.java : 159] :: ==> Parameters: USER_10013_8165726(String), USER_10013_8165726(String), 320100(String)
[BaseJdbcLogger.java : 159] :: <== Total: 10
2.如果我們不單單隻是進行對這個實體類所對應的表進行單表查詢,而是多張表進行聯合操作,然後再利用Page類進行分頁的話,可按如下操作:
service層:
public class WfTodoTaskServiceImpl extends ServiceImpl<WfTodoTaskRepository, WfTodoTask> implements WfTodoTaskService {
public List<WfTodoTask> getPagedList(WfTodoTaskQueryInDto input) {
//建立Page類,設定頁碼和偏移量
Page<WfTodoTask> pager = new Page<WfTodoTask>(1,10);
//調用mapper層的方法,不是BaseMapper裡面的方法,而是你自己寫的方法
List<WfTodoTask> list= baseMapper.getAllTask(pager,input);
pager.setRecords(list);
//這個類是我定義的分頁查詢結果的傳回類
return new PagedResultOutput<WfTodoTask>(results.getTotal(), results.getCurrent(), results.getSize(), results.getRecords());
}
}
mapper層:
@Select("<script>" +
"select * from wfl.wf_v_todotask todoTask"+
" <where>" +
" todoTask.assignee=#{assignee} or todoTask.CANDIDATE=#{assignee}" +
" and todoTask.city_code=#{cityCode}" +
" <if test=\"businessId != null and businessId !=''\" >" +
"and todoTask.businessId=#{businessId}" +
"</if>" +
" <if test=\"procInstId != null and procInstId != ''\">" +
"and todoTask.proc_inst_id=#{procInstId}" +
" </where>)"
"</script>")
})
List<WfTodoTask> getAllTask(Page<WfTodoTask> pager,WfTodoTaskQueryInDto input);
其實就是仿照BaseMapper裡面餓selectPage方法,傳遞一個Page類作為參數即可