Druid數(shù)據(jù)庫連接 | Spring Boot 集成 Druid實現(xiàn)數(shù)據(jù)庫連接和SQL監(jiān)控
我們知道,應(yīng)用系統(tǒng)最頻繁,最主要的操作還是數(shù)據(jù)庫的操作,所以數(shù)據(jù)庫的性能和安全對于整個系統(tǒng)平臺的重要性不言而喻。為了提高數(shù)據(jù)庫性能,我們可以使用數(shù)據(jù)庫連接池,有時候我們需要增加一些列的日志或是數(shù)據(jù)庫性能監(jiān)控工具來確保數(shù)據(jù)庫的性能,同時還得防范數(shù)據(jù)庫的SQL注入等安全問題。
所以,今天我們來介紹一款集數(shù)據(jù)庫連接池、數(shù)據(jù)庫監(jiān)控、SQL執(zhí)行日志于一身的神器:Druid。
一、Druid簡介
Druid 是阿里巴巴開源平臺上的一個數(shù)據(jù)庫連接池項目,它結(jié)合了 C3P0、DBCP 等數(shù)據(jù)庫池的優(yōu)點,同時加入了SQL日志和SQL性能監(jiān)控的功能。可以很好的監(jiān)控數(shù)據(jù)庫池連接和 SQL 的執(zhí)行情況,可以說是針對監(jiān)控而生的數(shù)據(jù)庫連接池框架。
Druid 是目前比較流行的高性能的,分布式列存儲的OLAP框架(具體來說是MOLAP)。它有如下幾個特點:
1、亞秒級查詢:Druid提供了快速的聚合能力以及亞秒級的OLAP查詢能力,多租戶的設(shè)計,是面向用戶分析應(yīng)用的理想方式。
2、實時數(shù)據(jù)注入:Druid支持流數(shù)據(jù)的注入,并提供了數(shù)據(jù)的事件驅(qū)動,保證在實時和離線環(huán)境下事件的實效性和統(tǒng)一性
3、可擴展的PB級存儲:Druid集群可以很方便的擴容到PB的數(shù)據(jù)量,每秒百萬級別的數(shù)據(jù)注入。即便在加大數(shù)據(jù)規(guī)模的情況下,也能保證其時效性
4、多環(huán)境部署:Druid既可以運行在商業(yè)的硬件上,也可以運行在云上。它可以從多種數(shù)據(jù)系統(tǒng)中注入數(shù)據(jù),包括hadoop,spark,kafka,storm和samza等
目前 Druid 已經(jīng)在阿里巴巴部署了超過600個應(yīng)用,經(jīng)過生產(chǎn)環(huán)境大規(guī)模部署的嚴苛考驗。
二、Druid對Spring Boot的支持
Driud 同樣對Spring Boot 提供了支持。為Spring Boot項目提供了druid-spring-boot-starter組件,可以幫助我們在Spring Boot項目中輕松集成Druid數(shù)據(jù)庫連接池和監(jiān)控。
Github地址:https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
我們知道 Spring Boot 2.0 以上默認使用 Hikari 數(shù)據(jù)源,可以說 Hikari 與 Driud 是當(dāng)前 Java Web 開發(fā)中最優(yōu)秀的數(shù)據(jù)源。
三、Spring Boot集成Druid
Druid 提供的druid-spring-boot-starter組件可以幫助我們在Spring Boot 項目中輕松集成Druid。下面通過示例演示如何在Spring Boot 項目中集成Druid。
1、引入依賴包
修改pom.xml 文件,引入druid、jdbc等依賴包,具體如下所示:
<dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starterartifactId>dependency><dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-webartifactId>dependency><dependency><groupId>com.alibabagroupId><artifactId>druid-spring-boot-starterartifactId><version>1.1.10version>dependency><dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-jdbcartifactId>dependency><dependency><groupId>mysqlgroupId><artifactId>mysql-connector-javaartifactId>dependency>
上面的示例中,我們引入了druid、jdbc、mysql-connector等依賴組件,其中druid的組件包不是Spring Boot 提供,所以版本號與Spring Boot不一致,我們需要單獨添加對應(yīng)的版本號:1.1.10。
2、修改配置文件
接下來,修改application.properties 配置文件,配置數(shù)據(jù)庫連接,Druid等相關(guān)配置。具體如下所示:
spring.datasource.type=com.alibaba.druid.pool.DruidDataSourcespring.datasource.url=jdbc:mysql://localhost:3306/druid_test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=truespring.datasource.username=rootspring.datasource.password=rootspring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver# 初始化最大、最?、最連接數(shù)spring.datasource.druid.initial-size=3spring.datasource.druid.min-idle=3spring.datasource.druid.max-active=10# 配置獲取連接等待超時的時間spring.datasource.druid.max-wait=60000# 監(jiān)控后臺賬號和密碼spring.datasource.druid.stat-view-servlet.login-username=adminspring.datasource.druid.stat-view-servlet.login-password=123456# 配置 StatFilterspring.datasource.druid.filter.stat.log-slow-sql=truespring.datasource.druid.filter.stat.slow-sql-millis=2000
上面的示例,我們配置了Mysql數(shù)據(jù)庫連接,已經(jīng)Druid的基礎(chǔ)配置和后臺監(jiān)控的賬號密碼。通過此賬號密碼,即可登錄Druid后臺,查看SQL的執(zhí)行情況。
3、運行驗證
前面這兩步,我們就把druid集成到Spring Boot項目中了。啟動項目訪問地址:http://localhost:8080/druid,就會出現(xiàn) Druid 監(jiān)控后臺的登錄頁面,輸入前面配置的賬戶和密碼后,就會進入首頁。

通過上圖可以看到,Druid展示了Spring Boot 項目中使用的 JDK 版本、數(shù)據(jù)庫驅(qū)動、 JVM 等相關(guān)統(tǒng)計信息,同時還有,數(shù)據(jù)源、 SQL 監(jiān)控、 SQL 防火墻、 URI 監(jiān)控、Session監(jiān)控等諸多監(jiān)控功能。從這里也可以看出 Druid 的功能非常強大。
四、Druid+jdbcTemplate實現(xiàn)數(shù)據(jù)庫操作
前面我們在Spring Boot項目中集成了Druid, 操作非常的簡單,只需要添加依賴,簡單配置即可實現(xiàn)。接下來我們通過Druid+jdbcTemplate實現(xiàn)數(shù)據(jù)庫操作,演示Druid 是如何監(jiān)控SQL執(zhí)行的。
1、創(chuàng)建數(shù)據(jù)庫及表
首先,創(chuàng)建druid_test數(shù)據(jù)庫和student 表。具體腳本如下:
CREATE TABLE `student` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',`name` varchar(32) DEFAULT NULL COMMENT '姓名',`sex` int(11) DEFAULT NULL,`age` int(11) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;-- ------------------------------ Records of student-- ----------------------------INSERT INTO `student` VALUES ('3', 'zhangsan', '1', '20');INSERT INTO `student` VALUES ('5', 'weiz多數(shù)據(jù)源', '0', '30');INSERT INTO `student` VALUES ('6', 'weiz', '1', '30');INSERT INTO `student` VALUES ('7', 'weiz2', '1', '30');INSERT INTO `student` VALUES ('10', '李四', '0', '18');INSERT INTO `student` VALUES ('11', 'weiz11', '1', '23');
2、創(chuàng)建Student實體類
接下來,創(chuàng)建student表對應(yīng)的Student實體類,示例代碼如下:
public class Student {private Long id;private String name;private int sex;private int age;public Student(){}public Student(String name, int sex, int age) {this.name = name;this.sex = sex;this.age = age;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getSex() {return sex;}public void setSex(int sex) {this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
3、創(chuàng)建Service 及Impl實現(xiàn)
創(chuàng)建數(shù)據(jù)庫操作的方法StudentRepository及實現(xiàn)StudentRepositoryImpl。具體示例代碼如下:
// StudentRepositorypublic interface StudentRepository {int save(Student user);int update(Student user);int delete(long id);Student findById(long id);}//?StudentRepositoryImplpublic class StudentRepositoryImpl implements StudentRepository {private JdbcTemplate jdbcTemplate;public int save(Student user) {return jdbcTemplate.update("INSERT INTO Student(name, sex, age) values(?, ?, ?)",user.getName(), user.getSex(), user.getAge());}public int update(Student user) {return jdbcTemplate.update("UPDATE Student SET name = ? , sex = ? , age = ? WHERE id=?",user.getName(), user.getSex(), user.getAge(), user.getId());}public int delete(long id) {return jdbcTemplate.update("DELETE FROM Student where id = ? ",id);}public Student findById(long id) {return jdbcTemplate.queryForObject("SELECT * FROM Student WHERE id=?", new Object[] { id }, new BeanPropertyRowMapper(Student.class)); }}
4、創(chuàng)建Controller調(diào)用
最后,創(chuàng)建StudentController,并調(diào)用相關(guān)的數(shù)據(jù)操作方法。示例代碼如下:
public class StudentController {StudentRepository studentRepository;public Student findById( Long id){return studentRepository.findById(id);}}
5、運行驗證
接下來,啟動項目,驗證jdbcTemplate 數(shù)據(jù)操作是否成功。訪問地址:http://localhost:8080/student/findById/3, 查詢學(xué)生信息。

我們看到,后臺成功返回了該學(xué)生的相關(guān)信息,接下來,我們在Druid中查看SQL的執(zhí)行情況。通過http://localhost:8080/druid 進入監(jiān)控后臺,查看SQL的執(zhí)行情況,具體如下圖所示:

如上圖所示,Druid的 SQL 監(jiān)控會將項目中執(zhí)行的所有SQL 打印出來,展示 SQL執(zhí)行了多少次、每次返回多少數(shù)據(jù)、執(zhí)行的時間分布是什么。這些功能非常的實用,方便我們在實際生產(chǎn)中查找出慢 SQL,最后對 SQL 進行調(diào)優(yōu)。
最后
以上,我們介紹了如何在Spring Boot 中集成Druid 實現(xiàn)數(shù)據(jù)庫連接和監(jiān)控的功能。然后通過Druid + jdbcTemplate 實現(xiàn)完整的數(shù)據(jù)操作。?
這個系列課程的完整源碼,也會提供給大家。大家私信我(架構(gòu)師精進),回復(fù):springboot源碼。獲取這個系列課程的完整源碼。

