一塊兒來學SpringBoot | 第八篇:通用Mapper與分頁插件的集成

SpringBoot 是爲了簡化 Spring 應用的建立、運行、調試、部署等一系列問題而誕生的產物, 自動裝配的特性讓咱們能夠更好的關注業務自己而不是外部的XML配置,咱們只需遵循規範,引入相關的依賴就能夠輕易的搭建出一個 WEB 工程

一塊兒來學SpringBoot | 第七篇:整合Mybatis一文中,咱們介紹了Mybatis這款優秀的框架,順便說起了民間大神開發的兩款插件通用MapperPageHelper,今後告別簡單CURD代碼的編寫....html

<!-- more -->java

插件介紹

如下兩款插件做者均是同一我的,若是你想深刻了解Mybatis以及插件開發能夠購買做者的書籍mysql

MyBatis 從入門到精通

分頁插件

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

通用Mapper

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

導入依賴

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

<!-- 通用Mapper插件
 文檔地址:https://gitee.com/free/Mapper/wikis/Home -->
<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-spring-boot-starter</artifactId>
    <version>2.0.2</version>
</dependency>
<!-- 分頁插件
 文檔地址:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.5</version>
</dependency>
<!-- MYSQL包 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 默認就內嵌了Tomcat 容器,如須要更換容器也極其簡單-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 測試包,當咱們使用 mvn package 的時候該包並不會被打入,由於它的生命週期只在 test 以內-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

屬性配置

application.properties 文件中分別添加上數據庫Mybatis通用MapperPageHelper的屬性配置,這裏只提供了常見場景的配置,更全的配置能夠參考上文所述的文文檔(#^.^#)spring

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文件添加以下內容sql

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

具體編碼

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

表結構

建立一張 t_user 的表apache

CREATE TABLE `t_user` (
  `id` int(8) NOT NULL AUTO_INCREMENT COMMENT '主鍵自增',
  `username` varchar(50) NOT NULL COMMENT '用戶名',
  `password` varchar(50) NOT 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<T> 就能夠了,這點是否是有點相似 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<T> 就能夠了,是否是有點相似 JpaRepository
 *
 * @author Levin
 * @since 2018/5/10 0007
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {

    /**
     * 根據用戶名統計(TODO 假設它是一個很複雜的SQL)
     *
     * @param username 用戶名
     * @return 統計結果
     */
    int countByUsername(String username);
}
UserMapper 映射文件
<?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.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<Object> pageInfo = PageHelper.startPage(1, 10).setOrderBy("id desc").doSelectPageInfo(() -> this.userMapper.selectAll());
        log.info("[lambda寫法] - [分頁信息] - [{}]", pageInfo.toString());

        PageHelper.startPage(1, 10).setOrderBy("id desc");
        final PageInfo<User> 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編寫,包括新版本的特性都會一塊兒介紹...

說點什麼

  • 我的QQ:1837307557
  • battcn開源羣(適合新手):391619659
  • 微信公衆號(歡迎調戲):battcn

公衆號

我的博客:http://blog.battcn.com/

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

相關文章
相關標籤/搜索