天天看點

SpringBoot結合MybatisPlus進行單表查詢(EntityWrapper)以及分頁(Page)的使用

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類作為參數即可