個人開源項目
前言
Springboot讓Java開發更加美好,本節主要講的是使用Hikari數據庫連接池,如果需要使用druid連接池的請看我另外一篇博客,springboot Mybatis 整合(這篇文章有詳細搭建springboot項目的過程,對于剛接觸springboot的新手有幫助)。
為什么使用HikariCP
在Springboot2.X版本,數據庫的連接池官方推薦使用HikariCP,官方的原話:
Production database connections can also be auto-configured by using a pooling
DataSource
. Spring Boot uses the following algorithm for choosing a specific implementation:
We preferHikariCPfor its performance and concurrency. If HikariCP is available, we always choose it.
Otherwise, if the Tomcat pooling
DataSource
is available, we use it.If neither HikariCP nor the Tomcat pooling datasource are available and ifCommons DBCP2is available, we use it.
意思是說:
我們更喜歡HikariCP的性能和并發性。如果有HikariCP,我們總是選擇它
否則,如果Tomcat池數據源可用,我們將使用它。
如果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錯誤碼;
啟動類
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如何使用多數據源。
源碼地址:戳這里