springboot整合mybatis 使用HikariCP連接池

個人開源項目

前言

Springboot讓Java開發更加美好,本節主要講的是使用Hikari數據庫連接池,如果需要使用druid連接池的請看我另外一篇博客,springboot Mybatis 整合(這篇文章有詳細搭建springboot項目的過程,對于剛接觸springboot的新手有幫助)。

為什么使用HikariCP

在Springboot2.X版本,數據庫的連接池官方推薦使用HikariCP,官方的原話:

Production database connections can also be auto-configured by using a poolingDataSource. Spring Boot uses the following algorithm for choosing a specific implementation:

  1. We preferHikariCPfor its performance and concurrency. If HikariCP is available, we always choose it.

  2. Otherwise, if the Tomcat poolingDataSourceis available, we use it.

  3. If neither HikariCP nor the Tomcat pooling datasource are available and ifCommons DBCP2is available, we use it.

意思是說:

  1. 我們更喜歡HikariCP的性能和并發性。如果有HikariCP,我們總是選擇它

  2. 否則,如果Tomcat池數據源可用,我們將使用它。

  3. 如果HikariCP和Tomcat池數據源都不可用,如果Commons DBCP2可用,我們將使用它。

那么如何使用HikariCP呢?

如果你的springboot版本是2.X,當你使用spring-boot-starter-jdbc或者spring-boot-starter-data-jpa依賴,springboot就會自動引入HikariCP的依賴了。

使用指定的數據庫連接池

如果你需要使用指定的數據庫連接池,那么你需要在application.properties中配置:spring.datasource.type

環境

  • JDK: 1.8

  • Maven: 3.3.9

  • SpringBoot: 2.0.3.RELEASE

  • 開發工具:Intellij IDEA 2017.1.3

開始使用

本次的配置中我們持久層使用mybatis,使用HikariCP作為數據庫連接池。

引入依賴

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <!--排除默認的tomcat-jdbc-->
                <exclusion>
                    <groupId>org.apache.tomcat</groupId>
                    <artifactId>tomcat-jdbc</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <!-- mybatis一定要使用starter,不然無法自動配置和注入 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

以上的依賴就足夠了,前面介紹過,只需要導入spring-boot-starter-jdbc依賴springboot就默認使用Hikari作為數據庫連接池了。

創建數據表

CREATE DATABASE mytest;

CREATE TABLE t_user(
  userId INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
  userName VARCHAR(255) NOT NULL ,
  password VARCHAR(255) NOT NULL ,
  phone VARCHAR(255) NOT NULL
) ENGINE=INNODB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8;

創建實體類

package com.winterchen.model;

/**
 * Created by Donghua.Chen on 2018/7/25.
 */
public class UserDomain {

    private Integer userId;

    private String userName;

    private String password;

    private String phone;

    // @TODO 省略get/set
}

創建Dao以及mapper映射

創建Dao類

創建一個dao的包,并且在這個包下創建一個UserDao

package com.winterchen.dao;

import com.winterchen.model.UserDomain;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * Created by Donghua.Chen on 2018/7/25.
 */
@Mapper
public interface UserDao {

    int insert(UserDomain record);

    void deleteUserById(@Param("userId") Integer userId);

    void updateUser(UserDomain userDomain);

    List<UserDomain> selectUsers();

}

注意:一定不要忘了使用@Mapper注解,如果沒有這個注解,spring就無法掃描到這個類,導致項目啟動報錯。

創建Mapper映射

上一步我們創建dao數據庫持久層類,由于本文使用的是xml映射的方式,所以我們需要創建一個xml映射文件。

resources文件夾下新建一個文件夾mapper

<?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.winterchen.dao.UserDao" >
    <sql id="BASE_TABLE">
        t_user
    </sql>

    <sql id="BASE_COLUMN">
        userId,userName,password,phone
    </sql>

    <insert id="insert" parameterType="com.winterchen.model.UserDomain">
        INSERT INTO
        <include refid="BASE_TABLE"/>
        <trim prefix="(" suffix=")" suffixOverrides=",">
            userName,password,
            <if test="phone != null">
                phone,
            </if>
        </trim>
        <trim prefix="VALUES(" suffix=")" suffixOverrides=",">
            #{userName, jdbcType=VARCHAR},#{password, jdbcType=VARCHAR},
            <if test="phone != null">
                #{phone, jdbcType=VARCHAR},
            </if>
        </trim>
    </insert>

    <delete id="deleteUserById">
      DELETE FROM
      <include refid="BASE_TABLE"/>
      WHERE
      userId = #{userId, jdbcType=INTEGER}
    </delete>
    <!-- 更新用戶信息,為空的字段不進行置空 -->
    <update id="updateUser" parameterType="com.winterchen.model.UserDomain">
        UPDATE
        <include refid="BASE_TABLE"/>
        <set>
          <if test="userName != null">
              userName = #{userName, jdbcType=VARCHAR},
          </if>
          <if test="password != null">
              password = #{password, jdbcType=VARCHAR},
          </if>
          <if test="phone != null">
              phone = #{phone, jdbcType=VARCHAR},
          </if>
        </set>
        <where>
            userId = #{userId, jdbcType=INTEGER}
        </where>
    </update>

    <select id="selectUsers" resultType="com.winterchen.model.UserDomain">
        SELECT
        <include refid="BASE_COLUMN"/>
        FROM
        <include refid="BASE_TABLE"/>
    </select>
</mapper>

注意點: 請將namespace="com.winterchen.dao.UserDao"改為你自己項目Dao的路徑,以及下面方法的一些路徑都要改為你自己項目的相關路徑。

配置

server.port=8080

#### 數據庫連接池屬性
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mytest?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=root
#自動提交
spring.datasource.default-auto-commit=true
#指定updates是否自動提交
spring.datasource.auto-commit=true
spring.datasource.maximum-pool-size=100
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
spring.datasource.validation-query=SELECT 1
spring.datasource.test-on-borrow=false
spring.datasource.test-while-idle=true
# 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒
spring.datasource.time-between-eviction-runs-millis=18800
# 配置一個連接在池中最小生存的時間,單位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000

# mybatis對應的映射文件路徑
mybatis.mapper-locations=classpath:mapper/*.xml
# mybatis對應的實體類
mybatis.type-aliases-package=com.winterchen.model

Service層

package com.winterchen.service;

import com.winterchen.model.UserDomain;

import java.util.List;

/**
 * Created by Donghua.Chen on 2018/7/25.
 */
public interface UserService {

    int insert(UserDomain record);

    void deleteUserById(Integer userId);

    void updateUser(UserDomain userDomain);

    List<UserDomain> selectUsers();

}

Service 實現層

package com.winterchen.service.impl;

import com.winterchen.dao.UserDao;
import com.winterchen.model.UserDomain;
import com.winterchen.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by Donghua.Chen on 2018/7/25.
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;//這里會爆紅,請忽略

    @Override
    public int insert(UserDomain record) {
        return userDao.insert(record);
    }

    @Override
    public void deleteUserById(Integer userId) {
        userDao.deleteUserById(userId);
    }

    @Override
    public void updateUser(UserDomain userDomain) {
        userDao.updateUser(userDomain);
    }

    @Override
    public List<UserDomain> selectUsers() {
        return userDao.selectUsers();
    }
}

Controller層

package com.winterchen.controller;

import com.winterchen.model.UserDomain;
import com.winterchen.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

/**
 * Created by Donghua.Chen on 2018/7/25.
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("")
    public ResponseEntity addUser(
            @RequestParam(value = "userName", required = true)
            String userName,
            @RequestParam(value = "password", required = true)
            String password,
            @RequestParam(value = "phone", required = false)
            String phone
    ){
        UserDomain userDomain = new UserDomain();
        userDomain.setUserName(userName);
        userDomain.setPassword(password);
        userDomain.setPhone(phone);
        userService.insert(userDomain);
        return ResponseEntity.ok("添加成功");
    }

    @DeleteMapping("")
    public ResponseEntity deleteUser(@RequestParam(value = "userId", required = true) Integer userId){

        userService.deleteUserById(userId);
        return ResponseEntity.ok("刪除成功");
    }

    @PutMapping("")
    public ResponseEntity updateUser(
            @RequestParam(value = "userId", required = true)
                    Integer userId,
            @RequestParam(value = "userName", required = false)
                    String userName,
            @RequestParam(value = "password", required = false)
                    String password,
            @RequestParam(value = "phone", required = false)
                    String phone
    ){
        UserDomain userDomain = new UserDomain();
        userDomain.setUserId(userId);
        userDomain.setUserName(userName);
        userDomain.setPassword(password);
        userDomain.setPhone(phone);
        userService.updateUser(userDomain);
        return ResponseEntity.ok("更新成功");
    }

    @GetMapping("")
    public ResponseEntity getUsers(){
        return ResponseEntity.ok(userService.selectUsers());
    }
}

強行科普一下:

  • @RequestParam 用于將請求參數區數據映射到功能處理方法的參數上,value:參數名字,即入參的請求參數名字,如userName表示請求的參數區中的名字為userName的參數的值將傳入,required:是否必須,默認是true,表示請求中一定要有相應的參數,否則將報404錯誤碼;

  • @Controller和@RestController的區別?

啟動類

package com.winterchen;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootMybatisHikaricpApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootMybatisHikaricpApplication.class, args);
    }
}

最終項目結構

目錄結構

啟動

啟動項目啟動類

2018-07-25 15:25:42.970  INFO 22602 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-07-25 15:25:43.380  INFO 22602 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-07-25 15:25:43.382  INFO 22602 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'dataSource' has been autodetected for JMX exposure
2018-07-25 15:25:43.389  INFO 22602 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
2018-07-25 15:25:43.450  INFO 22602 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2018-07-25 15:25:43.456  INFO 22602 --- [           main] c.w.SpringBootMybatisHikaricpApplication : Started SpringBootMybatisHikaricpApplication in 6.267 seconds (JVM running for 7.784)

這樣的輸出表示項目啟動成功了!!如果遇到報錯啟動不了,請回頭看看是不是有些地方沒有注意到。

測試

項目成功啟動了,那么可以開始測試了

推薦使用一個強大的http請求工具:Postman

添加

添加

刪除

刪除

更新

更新

查找

查找

最后

在編程的路上肯定會遇到很多的bug,程序員就是要不斷的和bug作斗爭,加油,愿你成為真正的大牛。有機會講講Hikari如何使用多數據源。

源碼地址:戳這里

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,885評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,312評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,993評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,667評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,410評論 6 411
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,778評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,775評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,955評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,521評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,266評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,468評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,998評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,696評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,095評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,385評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,193評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,431評論 2 378

推薦閱讀更多精彩內容