第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

首頁(yè) 慕課教程 Spring Boot 入門教程 Spring Boot 入門教程 Spring Boot 集成 Druid 數(shù)據(jù)源

Spring Boot 集成 Druid 數(shù)據(jù)源

1. 前言

首先要理解數(shù)據(jù)源的作用,數(shù)據(jù)源實(shí)際上是一個(gè)接口 javax.sql.DataSource 。 Spring Boot 在操作數(shù)據(jù)庫(kù)時(shí),是通過(guò)數(shù)據(jù)源類型的組件實(shí)現(xiàn)的。

數(shù)據(jù)源的類型有很多,但是都實(shí)現(xiàn)了 javax.sql.DataSource 接口,所以 Spring Boot 可以盡情地更換各類數(shù)據(jù)源以實(shí)現(xiàn)不同的需求。

其中 Druid 數(shù)據(jù)源就是數(shù)據(jù)源中比較出類拔萃的存在,而且是阿里開發(fā)的。國(guó)人出品的東西,咱們能支持的必須得支持啊,當(dāng)然這是建立在人家做的確實(shí)好的基礎(chǔ)上。

圖片描述

Druid 是阿里巴巴數(shù)據(jù)庫(kù)事業(yè)部出品

本篇我們使用 Druid 替換默認(rèn)的數(shù)據(jù)源,然后做一下性能對(duì)比測(cè)試。網(wǎng)上有很多文章寫 Druid 性能如何如何強(qiáng)悍,但是很多并沒(méi)有事實(shí)依據(jù)。我們做程序員還是要嚴(yán)謹(jǐn),相信實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)。所以本篇的內(nèi)容就是研究下 Druid 如何使用,及其性能到底是否足夠優(yōu)異。

2. 使用默認(rèn)數(shù)據(jù)源(HikariDataSource)

Spring Boot 2.2.5 版本使用的默認(rèn)數(shù)據(jù)源是 HikariDataSource ,該數(shù)據(jù)源號(hào)稱擁有全世界最快的數(shù)據(jù)庫(kù)連接池,嗯,我們來(lái)試試它的深淺。

2.1 準(zhǔn)備數(shù)據(jù)庫(kù)

還是使用之前的商城數(shù)據(jù)庫(kù)(shop)及商品信息數(shù)據(jù)表(goods),表結(jié)構(gòu)如下:

實(shí)例:

CREATE TABLE `goods` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '唯一編號(hào)',
  `name` varchar(255) DEFAULT '' COMMENT '商品名稱',
  `price` decimal(10,2) DEFAULT '0.00' COMMENT '商品價(jià)格',
  `pic` varchar(255) DEFAULT '' COMMENT '圖片文件名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.2 使用 Spring Initializr 創(chuàng)建項(xiàng)目

Spring Boot 版本選擇 2.2.5 , Group 為 com.imooc , Artifact 為 spring-boot-hikari ,生成項(xiàng)目后導(dǎo)入 Eclipse 開發(fā)環(huán)境。

2.3 引入項(xiàng)目依賴

我們引入 Web 項(xiàng)目依賴、熱部署依賴。由于本項(xiàng)目需要訪問(wèn)數(shù)據(jù)庫(kù),所以引入 spring-boot-starter-jdbc 依賴和 mysql-connector-java 依賴。

pom.xml 文件中依賴項(xiàng)如下:

實(shí)例:

	    <!-- 熱部署 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
		<!-- web -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- jdbc -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<!-- myql驅(qū)動(dòng) -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>

2.4 構(gòu)建商品類和商品數(shù)據(jù)訪問(wèn)類

定義商品類,對(duì)應(yīng)商品表:

實(shí)例:

/**
 * 商品類
 */
public class GoodsDo {
	/**
	 * 商品id
	 */
	private Long id;
	/**
	 * 商品名稱
	 */
	private String name;
	/**
	 * 商品價(jià)格
	 */
	private String price;
	/**
	 * 商品圖片
	 */
	private String pic;
	// 省略get set方法
}

定義商品數(shù)據(jù)庫(kù)訪問(wèn)類:

實(shí)例:

/**
 * 商品數(shù)據(jù)庫(kù)訪問(wèn)類
 */
@Repository // 標(biāo)注數(shù)據(jù)訪問(wèn)類
public class GoodsDao {
	@Autowired
	private JdbcTemplate jdbcTemplate;

	/**
	 * 新增
	 */
	public void insert(GoodsDo goods) {
		jdbcTemplate.update("insert into goods(name,price,pic)values(?,?,?)", goods.getName(), goods.getPrice(),
				goods.getPic());
	}

	/**
	 * 刪除
	 */
	public void delete(Long id) {
		jdbcTemplate.update("delete from goods where id =?", id);
	}

	/**
	 * 更新
	 */
	public void update(GoodsDo goods) {
		jdbcTemplate.update("update goods set name=?,price=?,pic=? where id=?", goods.getName(), goods.getPrice(),
				goods.getPic(), goods.getId());
	}

	/**
	 * 按id查詢
	 */
	public GoodsDo getById(Long id) {
		return jdbcTemplate.queryForObject("select * from goods where id=?", new RowMapper<GoodsDo>() {
			@Override
			public GoodsDo mapRow(ResultSet rs, int rowNum) throws SQLException {
				GoodsDo goods = new GoodsDo();
				goods.setId(rs.getLong("id"));
				goods.setName(rs.getString("name"));
				goods.setPrice(rs.getString("price"));
				goods.setPic(rs.getString("pic"));
				return goods;
			}
		}, id);
	}

	/**
	 * 查詢商品列表
	 */
	public List<GoodsDo> getList() {
		return jdbcTemplate.query("select * from goods", new RowMapper<GoodsDo>() {
			@Override
			public GoodsDo mapRow(ResultSet rs, int rowNum) throws SQLException {
				GoodsDo goods = new GoodsDo();
				goods.setId(rs.getLong("id"));
				goods.setName(rs.getString("name"));
				goods.setPrice(rs.getString("price"));
				goods.setPic(rs.getString("pic"));
				return goods;
			}
		});
	}
}

2.5 配置數(shù)據(jù)源信息

通過(guò)配置文件,設(shè)置數(shù)據(jù)源信息。

實(shí)例:

# 配置數(shù)據(jù)庫(kù)驅(qū)動(dòng)
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 配置數(shù)據(jù)庫(kù)url
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/shop?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
# 配置數(shù)據(jù)庫(kù)用戶名
spring.datasource.username=root
# 配置數(shù)據(jù)庫(kù)密碼
spring.datasource.password=Easy@0122

2.6 測(cè)試

通過(guò)測(cè)試類發(fā)起測(cè)試,此處我們簡(jiǎn)單執(zhí)行 1000 次插入,看看執(zhí)行時(shí)間。

需要注意的是,Spring Boot 進(jìn)行測(cè)試時(shí),需要添加注解 @SpringBootTest 。添加注解后該類可以直接通過(guò) @Test 標(biāo)注的方法發(fā)起單元測(cè)試,容器環(huán)境都已準(zhǔn)備好,非常方便。

實(shí)例:

@SpringBootTest // 通過(guò)該注解,開啟測(cè)試類功能,當(dāng)測(cè)試方法啟動(dòng)時(shí),啟動(dòng)了Spring容器
class SpringBootHikariApplicationTests {
	@Autowired
	private DataSource dataSource;// 自動(dòng)注入數(shù)據(jù)源
	@Autowired
	private GoodsDao goodsDao;

	/**
	 * 打印數(shù)據(jù)源信息
	 */
	@Test // 測(cè)試方法
	void printDataSource() {
		System.out.println(dataSource);
	}

	/**
	 * 批量插入測(cè)試
	 */
	@Test
	void insertBatch() {
		// 開始時(shí)間
		long startTime = System.currentTimeMillis();
		// 執(zhí)行1000次插入
		GoodsDo goods = new GoodsDo();
		goods.setName("測(cè)試");
		goods.setPic("測(cè)試圖片");
		goods.setPrice("1.0");
		for (int i = 0; i < 1000; i++) {
			goodsDao.insert(goods);
		}
		// 輸出操作時(shí)間
		System.out.println("use time:" + (System.currentTimeMillis() - startTime)+"ms");
	}
}

輸出結(jié)果如下,可見(jiàn)默認(rèn)數(shù)據(jù)源類型為 HikariDataSource ,插入 1000 條數(shù)據(jù)的時(shí)間大概為 1500ms (注意時(shí)間可能跟電腦性能等很多因素相關(guān),此處只是進(jìn)行簡(jiǎn)單的對(duì)比測(cè)試)。

use time:1518ms
com.zaxxer.hikari.HikariDataSource

3. 使用 Druid 數(shù)據(jù)源

接下來(lái)我們使用 Druid 數(shù)據(jù)源進(jìn)行對(duì)比測(cè)試。

3.1 準(zhǔn)備數(shù)據(jù)庫(kù)

與上面的商城數(shù)據(jù)庫(kù)(shop)及商品信息數(shù)據(jù)表(goods)一致。

3.2 使用 Spring Initializr 創(chuàng)建項(xiàng)目

Spring Boot 版本選擇 2.2.5 , Group 為 com.imooc , Artifact 為 spring-boot-druid ,生成項(xiàng)目后導(dǎo)入 Eclipse 開發(fā)環(huán)境。

3.3 引入項(xiàng)目依賴

我們引入 Web 項(xiàng)目依賴、熱部署依賴。由于本項(xiàng)目需要訪問(wèn)數(shù)據(jù)庫(kù),所以引入 spring-boot-starter-jdbc 依賴和 mysql-connector-java 依賴,由于使用 Druid ,所以還需要添加 Druid 相關(guān)依賴。

pom.xml 文件中依賴項(xiàng)如下:

實(shí)例:

	    <!-- 熱部署 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
		<!-- web -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- jdbc -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<!-- myql驅(qū)動(dòng) -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<!-- springboot druid -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.22</version>
		</dependency>

3.4 構(gòu)建商品類和商品數(shù)據(jù)訪問(wèn)類

spring-boot-hikari 項(xiàng)目一致。

3.5 配置數(shù)據(jù)源信息

通過(guò)配置文件,設(shè)置數(shù)據(jù)源信息。由于我們不再使用默認(rèn)數(shù)據(jù)源,所以此處需要指定數(shù)據(jù)源類型為 DruidDataSource 。

實(shí)例:

# 指定數(shù)據(jù)源類型
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 配置數(shù)據(jù)庫(kù)驅(qū)動(dòng)
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 配置數(shù)據(jù)庫(kù)url
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/shop?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
# 配置數(shù)據(jù)庫(kù)用戶名
spring.datasource.username=root
# 配置數(shù)據(jù)庫(kù)密碼
spring.datasource.password=Easy@0122

3.6 測(cè)試

測(cè)試類代碼同 spring-boot-hikari 一致,運(yùn)行測(cè)試類后,結(jié)果如下:

use time:1428ms
com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceWrapper

4. 對(duì)比結(jié)果分析

其實(shí)只能得出一個(gè)結(jié)論,在某些場(chǎng)景下 Druid 的速度不比 Hikari 慢,甚至還略勝一籌。

當(dāng)然我們只是對(duì)兩種數(shù)據(jù)源的默認(rèn)配置、單一線程情況進(jìn)行了簡(jiǎn)單測(cè)試,大家感興趣的話可以研究?jī)煞N數(shù)據(jù)源的配置方式,然后通過(guò)多線程進(jìn)行全面測(cè)試。

5. Druid 監(jiān)控

看到這個(gè)結(jié)果,大家可能對(duì)本篇文章不滿了,說(shuō)了半天,也沒(méi)看出 Druid 好在哪兒啊,為啥還費(fèi)勁將默認(rèn)的 Hikari 更換掉呢。

不要著急,我們仔細(xì)看下官方介紹:
圖片描述

Druid 在阿里巴巴開源項(xiàng)目官網(wǎng)的描述

可以看到, Druid 是為監(jiān)控而生,說(shuō)明 Druid 最強(qiáng)大的功能實(shí)際上是監(jiān)控,接下來(lái)我們就演示下如何實(shí)現(xiàn) Druid 監(jiān)控。

添加監(jiān)控相關(guān)的配置類,需要注意的是我們?cè)O(shè)定了監(jiān)控功能的賬號(hào)和密碼。

實(shí)例:

/**
 * Druid配置
 */
@Configuration
public class DruidConfig {
	/**
	 * 注冊(cè)servletRegistrationBean
	 */
	@Bean
	public ServletRegistrationBean servletRegistrationBean() {
		ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),
				"/druid/*");
		servletRegistrationBean.addInitParameter("allow", "");
		// 賬號(hào)密碼
		servletRegistrationBean.addInitParameter("loginUsername", "imooc");
		servletRegistrationBean.addInitParameter("loginPassword", "123456");
		servletRegistrationBean.addInitParameter("resetEnable", "true");
		return servletRegistrationBean;
	}

	/**
	 * 注冊(cè)filterRegistrationBean
	 */
	@Bean
	public FilterRegistrationBean filterRegistrationBean() {
		FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
		// 添加過(guò)濾規(guī)則.
		filterRegistrationBean.addUrlPatterns("/*");
		filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
		return filterRegistrationBean;
	}
}

此時(shí)打開網(wǎng)址 http://127.0.0.1:8080/druid 即可顯示 Druid 登錄頁(yè)面:

圖片描述

Druid 登錄頁(yè)面

我們使用指定的用戶名 imooc 密碼 123456 登錄后,即可查看各類監(jiān)控信息,內(nèi)容還是非常全面的,此處就不再展開介紹了。

圖片描述

Druid 監(jiān)控頁(yè)面

6. 小結(jié)

在實(shí)際研發(fā)與生產(chǎn)測(cè)試過(guò)程中,使用 Druid 的情況還是非常多的, Druid 非常穩(wěn)定、性能也表現(xiàn)相當(dāng)優(yōu)異,更重要的是它提供了全面直觀的監(jiān)控手段,所以現(xiàn)階段還是推薦大家使用 Druid 。