歡迎光臨
每天分享高質量文章

一起來學 SpringBoot 2.x | 第八篇:通用 Mapper 與分頁插件的集成

點擊上方“芋道原始碼”,選擇“置頂公眾號”

技術文章第一時間送達!

原始碼精品專欄

 


摘要: 原創出處 http://blog.battcn.com/2018/05/10/springboot/v2-orm-mybatis-plugin/ 「唐亞峰」歡迎轉載,保留摘要,謝謝!

  • 插件介紹

  • 匯入依賴

  • 屬性配置

  • 具體編碼

  • 說點什麼


SpringBoot是為了簡化Spring` 應用的創建、運行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關註業務本身而不是外部的XML配置,我們只需遵循規範,引入相關的依賴就可以輕易的搭建出一個 WEB 工程

在一起來學SpringBoot | 第七篇:整合Mybatis一文中,我們介紹了Mybatis這款優秀的框架,順便提及了民間大神開發的兩款插件(通用Mapper、PageHelper),從此告別簡單CURD代碼的編寫….

插件介紹

以下兩款插件作者均是同一個人,如果你想深入瞭解Mybatis以及插件開發可以購買作者的書籍

  • 京東: https://item.jd.com/12103309.html

  • 噹噹: http://product.dangdang.com/25098208.html

分頁插件

  • GIT地址: https://github.com/pagehelper/Mybatis-PageHelper

在沒有分頁插件之前,寫一個分頁需要兩條SQL陳述句,一條查詢一條統計,然後才能計算出頁碼,這樣的代碼冗餘而又枯燥,更重要的一點是資料庫遷移,眾所周知不同的資料庫分頁寫法是不同的,而Mybatis不同於Hibernate的是它只提供動態SQL和結果集映射。值得慶幸的是,它雖然沒有為分頁提供良好的解決方案,但卻提供了Interceptor以供開發者自己擴展,這也是這款分頁插件的由來….

通用Mapper

  • GIT地址: https://gitee.com/free/Mapper

通用 Mapper 是一個可以實現任意 MyBatis 通用方法的框架,專案提供了常規的增刪改查操作以及 Example 相關的單表操作。通用 Mapper 是為瞭解決 MyBatis 使用中 90% 的基本操作,使用它可以很方便的進行開發,可以節省開發人員大量的時間。

匯入依賴

在 pom.xml 中添加通用Mapper與分頁插件的依賴包


<dependency>
    <groupId>tk.mybatisgroupId>


    <artifactId>mapper-spring-boot-starterartifactId>
    <version>2.0.2version>
dependency>

<dependency>
    <groupId>com.github.pagehelpergroupId>
    <artifactId>pagehelper-spring-boot-starterartifactId>
    <version>1.2.5version>
dependency>

<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-testartifactId>
    <scope>testscope>
dependency>

屬性配置

在 application.properties 檔案中分別添加上資料庫、Mybatis、通用Mapper、PageHelper的屬性配置,這裡只提供了常見場景的配置,更全的配置可以參考上文所述的文文件(#^.^#)

spring.datasource.url=jdbc:mysql://localhost:3306/chapter7?useUnicode=true&characterEncoding;=UTF-8&zeroDateTimeBehavior;=convertToNull&allowMultiQueries;=true&useSSL;=false
spring.datasource.password=root
spring.datasource.username=root
# 如果想看到mybatis日誌需要做如下配置
logging.level.com.battcn=DEBUG
######### Mybatis 自身配置 ##########
mybatis.mapper-locations=classpath:com/battcn/mapper/*.xml
mybatis.type-aliases-package=com.battcn.entity
# 駝峰命名規範 如:資料庫欄位是  order_id 那麼 物體欄位就要寫成 orderId
mybatis.configuration.map-underscore-to-camel-case=true
######### 通用Mapper ##########
# 主鍵自增回寫方法,預設值MYSQL,詳細說明請看文件
mapper.identity=MYSQL
mapper.mappers=tk.mybatis.mapper.common.BaseMapper
# 設置 insert 和 update 中,是否判斷字串型別!=''
mapper.not-empty=true
# 列舉按簡單型別處理
mapper.enum-as-simple-type=true
######### 分頁插件 ##########
pagehelper.helper-dialect=mysql
pagehelper.params=count=countSql
pagehelper.reasonable=false
pagehelper.support-methods-arguments=true

通用Mapper

  • mapper.enum-as-simple-type: 列舉按簡單型別處理,如果有列舉欄位則需要加上該配置才會做映射

  • mapper.not-empty: 設置以後,會去判斷 insert 和 update 中符串型別!=’’

分頁插件

  • pagehelper.reasonable: 分頁合理化引數,預設值為false。當該引數設置為 true 時,pageNum<=0 時會查詢第一頁, pageNum>pages(超過總數時),會查詢最後一頁。預設false 時,直接根據引數進行查詢。

  • support-methods-arguments: 支持通過 Mapper 接口引數來傳遞分頁引數,預設值false,分頁插件會從查詢方法的引數值中,自動根據上面 params 配置的欄位中取值,查找到合適的值時就會自動分頁。

註意事項

由於 mybatis.mapper-locations=classpath:com/battcn/mapper/*.xml配置的在java package中,而Spring Boot預設只打入java package -> *.java,所以我們需要給pom.xml檔案添加如下內容

<build>
    <resources>
        <resource>
            <directory>src/main/resourcesdirectory>


        resource>
        <resource>
            <directory>src/main/javadirectory>
            <includes>
                <include>**/*.xmlinclude>
            includes>
            <filtering>truefiltering>
        resource>
    resources>
    <plugins>
        <plugin>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-maven-pluginartifactId>
        plugin>
    plugins>
build>

具體編碼

完成基本配置後,接下來進行具體的編碼操作。

表結構

創建一張 t_user 的表

CREATE TABLE `t_user` (
  `id` int(8NOT NULL AUTO_INCREMENT COMMENT '主鍵自增',
  `username` varchar(50NOT NULL COMMENT '用戶名',
  `password` varchar(50NOT NULL COMMENT '密碼',
  PRIMARY KEY (`id`)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶表';

物體類

通用Mapper採用了JPA規範包中的註解,這種的設計避免了重覆造輪子,更是讓Spring Data Jpa的應用可以輕鬆切換到Mybatis

package com.battcn.entity;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;

/**
 * @author Levin
 * @since 2018/5/10 0007
 */

@Table(name = "t_user")
public class User implements Serializable {

    private static final long serialVersionUID = 8655851615465363473L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    // TODO  省略get set
}

持久層

為了更好的讓熟悉它,此處模擬了一個自定義的SQL,可以發現使用 通用Mapper 後並不會破壞原有代碼結構

UserMapper

繼承 BaseMapper 就可以了,這點是不是有點類似 JpaRepository,同時也可以根據自己需要擴展出更適合自己專案的BaseMapper,它的靈活也是眾多開發者喜愛的因素之一

package com.battcn.mapper;

import com.battcn.entity.User;
import org.apache.ibatis.annotations.Mapper;
import tk.mybatis.mapper.common.BaseMapper;

/**
 * t_user 操作,繼承 BaseMapper 就可以了,是不是有點類似 JpaRepository
 *
 * @author Levin
 * @since 2018/5/10 0007
 */

@Mapper
public interface UserMapper extends BaseMapper {

    /**
     * 根據用戶名統計(TODO 假設它是一個很複雜的SQL)
     *
     * @param username 用戶名
     * @return 統計結果
     */

    int countByUsername(String username);
}

UserMapper 映射檔案


mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.battcn.mapper.UserMapper">

  <select id="countByUsername" resultType="java.lang.Integer">
      SELECT count(1) FROM t_user WHERE username = #{username}
  select>


mapper>

測試

完成資料訪問層接口後,編寫一個junit測試類來檢驗代碼的正確性。

package com.battcn;

import com.battcn.entity.User;
import com.battcn.mapper.UserMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

/**
 * @author Levin
 */

@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter7ApplicationTests {

    private static final Logger log = LoggerFactory.getLogger(Chapter7ApplicationTests.class);

    @Autowired
    private UserMapper userMapper;

    @Test
    public void test1() throws Exception {
        final User user1 = new User("u1""p1");
        final User user2 = new User("u1""p2");
        final User user3 = new User("u3""p3");
        userMapper.insertSelective(user1);
        log.info("[user1回寫主鍵] - [{}]", user1.getId());
        userMapper.insertSelective(user2);
        log.info("[user2回寫主鍵] - [{}]", user2.getId());
        userMapper.insertSelective(user3);
        log.info("[user3回寫主鍵] - [{}]", user3.getId());
        final int count = userMapper.countByUsername("u1");
        log.info("[呼叫自己寫的SQL] - [{}]", count);

        // TODO 模擬分頁
        userMapper.insertSelective(new User("u1""p1"));
        userMapper.insertSelective(new User("u1""p1"));
        userMapper.insertSelective(new User("u1""p1"));
        userMapper.insertSelective(new User("u1""p1"));
        userMapper.insertSelective(new User("u1""p1"));
        userMapper.insertSelective(new User("u1""p1"));
        userMapper.insertSelective(new User("u1""p1"));
        userMapper.insertSelective(new User("u1""p1"));
        userMapper.insertSelective(new User("u1""p1"));
        userMapper.insertSelective(new User("u1""p1"));
        // TODO 分頁 + 排序 this.userMapper.selectAll() 這一句就是我們需要寫的查詢,有了這兩款插件無縫切換各種資料庫
        final PageInfo pageInfo = PageHelper.startPage(110).setOrderBy("id desc").doSelectPageInfo(() -> this.userMapper.selectAll());
        log.info("[lambda寫法] - [分頁信息] - [{}]", pageInfo.toString());

        PageHelper.startPage(110).setOrderBy("id desc");
        final PageInfo userPageInfo = new PageInfo<>(this.userMapper.selectAll());
        log.info("[普通寫法] - [{}]", userPageInfo);
    }
}

總結

  1. Mybatis官方文件: http://www.mybatis.org/mybatis-3/zh/index.html

  2. 通用Mapper文件: https://gitee.com/free/Mapper/wikis/1.1-java?parent=1.integration

  3. 分頁插件文件: https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md

目前很多大佬都寫過關於 SpringBoot 的教程了,如有雷同,請多多包涵,本教程基於最新的 spring-boot-starter-parent:2.0.1.RELEASE編寫,包括新版本的特性都會一起介紹…

說點什麼

全文代碼:https://github.com/battcn/spring-boot2-learning/tree/master/chapter7

666. 彩蛋




如果你對 Dubbo 感興趣,歡迎加入我的知識星球一起交流。

知識星球

目前在知識星球(https://t.zsxq.com/2VbiaEu)更新瞭如下 Dubbo 原始碼解析如下:

01. 除錯環境搭建
02. 專案結構一覽
03. 配置 Configuration
04. 核心流程一覽

05. 拓展機制 SPI

06. 執行緒池

07. 服務暴露 Export

08. 服務取用 Refer

09. 註冊中心 Registry

10. 動態編譯 Compile

11. 動態代理 Proxy

12. 服務呼叫 Invoke

13. 呼叫特性 

14. 過濾器 Filter

15. NIO 服務器

16. P2P 服務器

17. HTTP 服務器

18. 序列化 Serialization

19. 集群容錯 Cluster

20. 優雅停機

21. 日誌適配

22. 狀態檢查

23. 監控中心 Monitor

24. 管理中心 Admin

25. 運維命令 QOS

26. 鏈路追蹤 Tracing


一共 60 篇++

赞(0)

分享創造快樂