前面介紹了Spring Boot 中的整合Mybatis並實現增刪改查、如何實現事物控制。不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/1657780.html。
Spring Boot 除了Mybatis資料庫框架,還有JdbcTemplate等資料庫操作框架,同樣也比較簡單實用,如果是一般簡單的專案,用JdbcTemplate完全可以實現相關的資料庫操作。它雖然沒有MyBatis功能強大,但使用比較簡單,JdbcTemplate應該算是最簡單的資料持久化方案,所以下面就來給大家介紹Spring Boot 使用JdbcTemplate運算元據庫,配置多資料來源!
一、JDBC簡介
JDBC(Java Data Base Connectivity, Java 資料庫連線)是一種用於執行各種資料庫操作的 API,可以為多種資料庫提供統一訪問介面。所以,JDBC 就像是一套 Java 訪問資料庫的 API 規範,利用這套規範遮蔽了各種資料庫 API 呼叫的差異性。當應用程式需要訪問資料庫時,呼叫 JDBC API 相關程式碼進新操作,再由JDBC呼叫各類資料庫的驅動包進行資料操作,最後資料庫驅動包和對應的資料庫通訊協議完成對應的資料庫操作。
在Java領域,資料持久化有幾個常見的方案,有Spring Boot自帶的JdbcTemplate、有MyBatis,還有JPA,在這些方案中,最簡單的就是Spring Boot自帶的JdbcTemplate,雖然沒有MyBatis功能強大,但是,使用比較簡單,事實上,JdbcTemplate應該算是最簡單的資料持久化方案。
二、快速開始
開始之前,需要建立一個Spring Boot專案,JdbcTemplate的引用很簡單,開發者在建立一個SpringBoot專案時,選上Jdbc以及資料庫驅動依賴即可。之前介紹過如何建立專案這裡就不介紹,直接使用之前建立的專案工程。
1、依賴配置
1、pom新增依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
需要注意的是:
如果是用資料庫連線池,記得新增Druid資料庫連線池依賴。
這裡可以新增專門為Spring Boot打造的druid-spring-boot-starter,JdbcTemplate預設使用Hikari 連線池,如果需要使用druid,需要另外配置。
2、application.properties配置資料來源
接下來需要在application.properties中提供資料的基本配置即可,如下:
spring.datasource.url=jdbc:mysql://localhost:3306/zwz_test spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver
注意:在 Spring Boot 2.1.0 中, com.mysql.jdbc.Driver 已經過期,推薦使用com.mysql.cj.jdbc.Driver
如此之後,所有的配置就算完成了,接下來就可以直接使用JdbcTemplate了,是不是特別方便。其實這就是SpringBoot的自動化配置帶來的好處。
2、資料庫和實體類
1、資料庫表
DROP TABLE IF EXISTS `products`; CREATE TABLE `products` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵id', `name` varchar(32) DEFAULT NULL COMMENT '名稱', `code` varchar(32) DEFAULT NULL COMMENT '編碼', `price` int DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2、實體類
package com.weiz.pojo; public class Product { private Long id; private String name; private String code; private int price; public Product(String name, String code, int price) { this.name = name; this.code = code; this.price = price; } // 省略 getter setter }
實體類的資料型別要和資料庫欄位一一對應,否則會有問題。
3、Serverice封裝
建立ProductService和ProductServiceImpl類
1、建立 UserService 定義我們常用的增刪改查介面
package com.weiz.service; import com.weiz.pojo.Product; public interface ProductService { int save(Product product); int update(Product product); int delete(long id); Product findById(long id); }
2、建立 ProductServiceImpl 類實現 ProductService 類介面
package com.weiz.service.impl; import com.weiz.pojo.Product; import com.weiz.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; @Service public class ProductServiceImpl implements ProductService { @Autowired private JdbcTemplate jdbcTemplate; @Override public int save(Product product) { return jdbcTemplate.update("INSERT INTO products(name, code, price) values(?, ? , ?)", product.getName(), product.getCode(), product.getPrice()); } @Override public int update(Product product) { return jdbcTemplate.update("UPDATE products SET name = ? , code = ? , price = ? WHERE id=?", product.getName(), product.getCode(), product.getPrice(), product.getId()); } @Override public int delete(long id) { return jdbcTemplate.update("DELETE FROM products where id = ? ",id); } @Override public Product findById(long id) { return jdbcTemplate.queryForObject("SELECT * FROM products WHERE id=?", new Object[] { id }, new BeanPropertyRowMapper<Product>(Product.class)); } }
程式碼說明:
UserServiceImpl類上使用 @Service 註解用於標註資料訪問元件,@Autowired 在類中注入 JdbcTemplate,JdbcTemplate是 Spring Boot操作JDBC 提供的工具類 。
除了以上這些基本用法之外,JdbcTemplate也支援其他用法,例如呼叫儲存過程等,這些都比較容易,而且和Jdbc本身都比較相似,這裡也就不做介紹了,有興趣可以留言討論。
三、呼叫測試
接下來我們對jdbc運算元據庫的功能進行測試。
1、建立ProductController
package com.weiz.controller; import com.weiz.pojo.Product; import com.weiz.service.ProductService; import com.weiz.utils.JSONResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("product") public class ProductController { @Autowired private ProductService productService; @RequestMapping("/save") public JSONResult save() { Product product = new Product(); product.setCode("iphone 11"); product.setName("iphone 11"); product.setPrice(100); productService.save(product); return JSONResult.ok("儲存成功"); } @RequestMapping("/update") public JSONResult update() { long pid = 1; Product product = new Product(); product.setCode("iphone 12"); product.setName("iphone 12"); product.setPrice(200); product.setId(pid); productService.update(product); return JSONResult.ok("修改成功"); } @RequestMapping("/delete") public JSONResult delete(long pid) { productService.delete(pid); return JSONResult.ok("刪除成功"); } @RequestMapping("/findbyId") public JSONResult findById(long pid) { Product product = productService.findById(pid); return JSONResult.ok(product); } }
2、啟動專案,在瀏覽器分別輸入增刪改查對應的地址,測試對應的方法是不是正確即可。
四、多資料來源的使用
在實際專案中,經常會碰到使用多個資料來源的情況, 比如:需要使用多個host、需要使用多種資料庫(MySql、Oracle、SqlServer...)。SpringBoot中,對此都有相應的解決方案,不過一般來說,如果有多資料來源的需求,我還是建議首選分散式資料庫中介軟體MyCat。這些都是比較成熟的框架,不需要自己重新寫一套。當然如果一些簡單的需求,還是可以使用多資料來源的,Spring Boot中,JdbcTemplate、MyBatis以及Jpa都可以配置多資料來源。接下來,就在上面的專案的基礎上進行改造,給大家介紹JdbcTemplate 如何配置多資料來源。
1、配置多資料來源
application.properties配置多個資料來源:
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/zwz_test spring.datasource.primary.username=root spring.datasource.primary.password=root spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/zwz_test2 spring.datasource.secondary.username=root spring.datasource.secondary.password=root spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
上面的配置檔案,新增了兩個資料來源,一個是 zwz_test 庫,鈴個是 zwz_test2 庫。
注意:之前單個資料來源的資料庫連線是:spring.datasource.url,這裡多個資料來源使用的是 spring.datasource.*.jdbc-url,因為JdbcTemplate預設使用Hikari 連線池,而 HikariCP 讀取的是 jdbc-url 。
2、配置JDBC初始化
建立DataSourceConfig,在專案啟動的時候讀取配置檔案中的資料庫資訊,並對 JDBC 初始化。
package com.weiz.config; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; @Configuration public class DataSourceConfig { @Primary @Bean(name = "primaryDataSource") @Qualifier("primaryDataSource") @ConfigurationProperties(prefix="spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryDataSource") @Qualifier("secondaryDataSource") @ConfigurationProperties(prefix="spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name="primaryJdbcTemplate") public JdbcTemplate primaryJdbcTemplate ( @Qualifier("primaryDataSource") DataSource dataSource ) { return new JdbcTemplate(dataSource); } @Bean(name="secondaryJdbcTemplate") public JdbcTemplate secondaryJdbcTemplate( @Qualifier("secondaryDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } }
// ProductService 介面 public interface ProductService { int save(Product product, JdbcTemplate jdbcTemplate); // 省略其他方法 } // ProductServiceImpl @Service public class ProductServiceImpl implements ProductService { @Override public int save(Product product,JdbcTemplate jdbcTemplate) { return jdbcTemplate.update("INSERT INTO products(name, code, price) values(?, ? , ?)", product.getName(), product.getCode(), product.getPrice()); } // 省略其他方法 }
4、呼叫測試
同樣,將之前的ProductController 修改如下:
@RestController @RequestMapping("product") public class ProductController { @Autowired private ProductService productService; @Autowired private JdbcTemplate primaryJdbcTemplate; @Autowired private JdbcTemplate secondaryJdbcTemplate; @RequestMapping("/save") public JSONResult save() { Product product = new Product(); product.setCode("iphone 11"); product.setName("iphone 11"); product.setPrice(100); productService.save(product,primaryJdbcTemplate); productService.save(product,secondaryJdbcTemplate); return JSONResult.ok("儲存成功"); } // 省略其他方法 }
在瀏覽器中輸入:/save 地址後,檢視zwz_test 和 zwz_test2資料庫中的products表,都存入一條資料,說明多資料來源插入資料成功,其他方方法也是一樣的。這樣在實際專案中,我們通過傳入不同的JdbcTemplate 例項,就可以操作多個資料庫。
最後
以上,就把Spring Boot 使用jdbcTemplate 運算元據庫介紹完了。同時也介紹瞭如何配置使用多資料來源。在 Spring Boot 專案中 JDBC 運算元據庫是不是非常簡單。
這個系列課程的完整原始碼,也會提供給大家。大家關注我的微信公眾號(架構師精進),回覆:springboot原始碼。獲取這個系列課程的完整原始碼。