DB數據源之SpringBoot+MyBatis踏坑過程(三)手工+半自動註解配置數據源與加載Mapper.xml掃描html
liuyuhang原創,未經容許禁止轉載 java
系列目錄鏈接mysql
DB數據源之SpringBoot+Mybatis踏坑過程實錄(一)web
1.環境說明spring
Springboot初學者,須要學習手工配置數據源,不須要多數據源配置的狀況下sql
建議使用本說明進行配置。數據庫
springboot,parent 2.0.2.和1.5.3.都已經測試過,apache
在java8和java7環境下測試過。前者配java8,後者配java7,json
使用MyEclipse 2017 C1 64x,MyEclipse 2016以前的版本沒法使用java8tomcat
pom.xml核心以下:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <dependencies> <!-- 添加MySQL依賴 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- 添加JDBC依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- mybaits基礎依賴 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.0</version> </dependency> <!-- mybatis插件依賴 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <!-- mapper依賴 --> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper</artifactId> <version>3.3.7</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
2.配置思路
2.1.建立SystemConfig類,使用@ConfigurationProperties註解獲取application.properties文件中的屬性;
2.2.注入SystemConfig到Mybatis的SessionFactory的配置類
2.3.建立數據源DataSource;
2.4.注入數據源屬性;
2.5.建立SqlSessionFactory;
2.6.SqlSessionFactory配置DataSource;
2.7.SqlSessionFactory配置掃描MyBatis-config.xml文件;
2.8.SqlSessionFactory配置掃描Mapper.xml所在包;
2.9.獲取session查詢數據庫進行測試;
3.所需類與結構
3.0.application.properties文件與相應內容做爲數據源;
3.1.SystemConfig類,用於獲取application.properties中的property;
3.2.DataConfig類,用於獲取SqlSessionFactory;
3.3.ExampleController類,用於測試;
3.4.AppRun類,springboot的啓動入口,將DataConfig初始化;
3.5.mapper.xml內容
4.代碼
4.0.application.properties文件,代碼以下:
1 master.url=jdbc:mysql://qqq.jjj.xxx.iii:3306/master?characterEncoding=utf8 2 master.username=root 3 master.password=root 4 master.driver=com.mysql.jdbc.Driver 5 #master.driver-class-name=com.mysql.jdbc.Driver 通常是使用這個命名模式
4.1.SystemConfig類,代碼以下:
1 package com.FM.config; 2 3 import org.springframework.boot.context.properties.ConfigurationProperties; 4 import org.springframework.stereotype.Component; 5 6 @Component//做爲組件交給spring管理 7 @ConfigurationProperties(prefix = "master")//讀取application文件前綴爲master的屬性 8 public class SystemConfig { 9 10 String url; 11 String driver; 12 String username; 13 String password; 14 15 //提供setter給spring,提供setter自用 16 public String getUrl() { 17 return url; 18 } 19 20 public void setUrl(String url) { 21 this.url = url; 22 } 23 24 public String getDriver() { 25 return driver; 26 } 27 28 public void setDriver(String driver) { 29 this.driver = driver; 30 } 31 32 public String getUsername() { 33 return username; 34 } 35 36 public void setUsername(String username) { 37 this.username = username; 38 } 39 40 public String getPassword() { 41 return password; 42 } 43 44 public void setPassword(String password) { 45 this.password = password; 46 } 47 48 }
4.2.DataConfig類,用於獲取SqlSessionFactory,代碼以下:
1 package com.FM.config; 2 3 import java.util.HashMap; 4 5 import javax.sql.DataSource; 6 7 import org.apache.ibatis.session.SqlSessionFactory; 8 import org.mybatis.spring.SqlSessionFactoryBean; 9 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.boot.jdbc.DataSourceBuilder; 11 import org.springframework.context.annotation.Configuration; 12 import org.springframework.core.io.DefaultResourceLoader; 13 import org.springframework.core.io.Resource; 14 import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 15 16 /** 17 * DataConfig,獲取數據源,配置給SqlSessionFactory,並以此獲取session 18 * @author liuyuhang 19 */ 20 @Configuration//做爲配置,交給spring管理 21 public class DataConfig { 22 23 @Autowired//注入SystemConfig類,注意變量名 24 private SystemConfig systemConfig; 25 26 /** 27 * 手動獲取sessionFactory並配置用例 28 * @param dataSourcePerfix 29 * @return 30 * @throws Exception 31 */ 32 public SqlSessionFactory getSessionFactory() throws Exception { 33 34 String masterUrl = systemConfig.getUrl(); 35 String masterDriver = systemConfig.getDriver(); 36 String masterUsername = systemConfig.getUsername(); 37 String masterPassword = systemConfig.getPassword(); 38 // 建立數據源 39 DataSourceBuilder create = DataSourceBuilder.create(); 40 create.url(masterUrl); 41 create.driverClassName(masterDriver); 42 create.username(masterUsername); 43 create.password(masterPassword); 44 DataSource source = create.build(); 45 // 建立sessionFactory 46 SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); 47 factoryBean.setDataSource(source);// 加載數據源 48 // 掃描mapper.xml 49 Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:com/FM/mapper/*.xml"); 50 factoryBean.setMapperLocations(resources); 51 // 讀取config 52 factoryBean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:mybatis-config.xml")); 53 SqlSessionFactory sessionFactory = factoryBean.getObject(); 54 return sessionFactory; 55 } 56 57 }
4.3.ExampleController類,用於測試;
1 package com.FM.controller; 2 3 import java.util.HashMap; 4 import java.util.List; 5 import java.util.Map; 6 7 import javax.servlet.http.HttpServletRequest; 8 9 import org.apache.ibatis.session.SqlSession; 10 import org.apache.ibatis.session.SqlSessionFactory; 11 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.web.bind.annotation.RequestMapping; 13 import org.springframework.web.bind.annotation.RestController; 14 15 import com.FM.config.DataConfig; 16 import com.FM.tool.reqUtils; 17 18 @RestController //等同於responseBody + controller雙重註解 19 public class ExampleController { 20 21 @Autowired 22 DataConfig dataConfig; 23 24 /** 25 * 手動建立session查詢數據庫用例,該方法能夠建立多個sessionFactory,用多線程 26 * @param request 27 * @return 28 * @throws Exception 29 */ 30 @RequestMapping("/helloMybatis") 31 public List helloMybatis(HttpServletRequest request) throws Exception { 32 SqlSessionFactory sessionFactory = dataConfig.getSessionFactory();//獲取sessionfactory 33 SqlSession session = sessionFactory.openSession();//獲取session 34 List<Object> selectList = session.selectList("com.FM.mapper.MySqlMapper.getUser"); 35 return selectList;//自動轉換爲json 36 }
}
4.4.AppRun類,springboot的啓動入口,將DataConfig初始化;
1 package com.FM; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.SpringBootConfiguration; 5 import org.springframework.boot.autoconfigure.SpringBootApplication; 6 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 7 import org.springframework.boot.web.servlet.ServletComponentScan; 8 9 @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) // 禁用默認的單數據源配置 10 @SpringBootConfiguration // springboot基礎配置註解 11 @ServletComponentScan // springboot servlet filter 12 // @EnableConfigurationProperties//該註解於springboot1.5以上廢棄 13 public class AppRun { 14 15 public static void main(String[] args) throws Exception { 16 SpringApplication.run(AppRun.class, args); 17 } 18 }
4.5.mapper.xml內容:略,前篇有
5.說明
通常來說是配置數據源,用Mybatis的sessionFactory來讀取dao;
而後將dao注入給service,再將service注入給controller。
說明一下,這幾個註解本質上是一個意思,即@Repository,@Service,@Controller,
本質上是一樣的功能,只是爲了分層而使用這種方式,spring的注入是十分靈活的
我平時寫業務,習慣寫樂觀鎖,將事務和代碼都控制在controller層,
所以在這一層直接獲取session並進行操做,省略dao,service兩層
不習慣的自行更改
注:本文配置方式會產生幾個問題
springboot以這種方式配置的數據源,本質上是交給內置的tomcat來管理的,內置的tomcat來管理會涉及到鏈接池的問題。
若是數據庫對於鏈接數量沒有擴容,而內置tomcat的鏈接池沒有配置,短期內會產生大量鏈接而不銷燬,會致使鏈接
拒絕,而報錯。
可能報出的兩個常見的錯誤,主要內容以下:
a:Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 14,595,596 milliseconds ago. The last packet sent successfully to the server was 14,595,612 milliseconds ago.
該錯誤的緣由一般是由於session沒有保證關閉引發的
b: o.a.tomcat.jdbc.pool.ConnectionPool : Unable to create initial connections of pool.
Data source rejected establishment of connection, message from server: "Too many connections"
本示例中使用的是MySql數據庫,Threads_connected設置的數值是512,所以報上述錯誤。
該錯誤的緣由不只有Mysql數據庫優化的問題,同時也有鏈接池管理配置的問題
以上列舉問題將在後文中處理,更新後將在文尾插入鏈接!
6.測試
結果以下圖:
以上!