一,什么是JNDI數據源?
我們看下百度百科的描述
JNDI(Java Naming and Directory Interface,Java命名和目錄接口)是SUN公司提供的一種標准的Java命名系統接口,JNDI提供統一的客戶端API,通過不同的訪問提供者接口JNDI服務供應接口(SPI)的實現,由管理者將JNDI API映射為特定的命名服務和目錄系統,使得Java應用程序可以和這些命名服務和目錄服務之間進行交互。
看完了之后,是不是感覺很抽象?這里我們需要理解這么幾點
(1)JNDI是J2EE的規范之一。
(2)JNDI主要有兩部分組成:應用程序編程接口和服務供應商接口。應用程序編程接口提供了Java應用程序訪問各種命名和目錄服務的功能,服務供應商接口提供了任意一種服務的供應商使用的功能。
(3)J2EE 規范要求全部 J2EE 容器都要提供 JNDI 規范的實現。
(4)JNDI 提出的目的是為了解藕,避免了程序與數據庫之間的緊耦合,使應用更加易於配置、易於部署。
以上概念內容摘抄自大佬博客,以下內容皆為筆者親歷親為所得所感悟!
JNDI的出現,讓數據庫連接代碼交給容器管理,比如Tomcat、JBOSS等容器,這樣對於開發者就不用關心數據庫配置是什么,使用的什么數據庫驅動連接數據庫等
傳統的JNDI是依賴web容器的,例如spring框架,在容器中配置好數據源(或者多數據源)配置,然后在spring項目的配置文件中指定數據源名稱,然后把spring項目打成war包部署到容器中運行,就可以使用JNDI數據源了!
spring項目外置tomcat集成jndi數據源請參考
https://www.cnblogs.com/springboot-wuqian/archive/2004/01/13/9418180.html
https://cnsyear.com/posts/9b26f7c2.html
https://cnsyear.com/posts/ceb1797.html
但今天的重點是springboot集成jndi數據源,其實按道理來說,springboot使用的是內置tomcat,也應該可以集成jndi,結果是可以,不過真的走了很多彎路,跳了很多坑,今天就來給大家講一下springboot內置tomcat如何集成jndi數據源!
二,springboot內置tomcat開始集成JNDI
1,添加依賴
環境所需依賴包括:mysql驅動,mybatis-starter
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
上面的依賴是必需的,連接和操作數據庫少不了的,關鍵是下面的tomcat依賴,竟然卡了我一天,沒有它還真不行,如果沒有它的話,當你配置好了數據源信息並注入到spring容器中,會報錯提示找不到數據源,亦或者是無法創建數據源
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<version>${tomcat.version}</version>
</dependency>
2,啟動類
需要在啟動類上加一個注解
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
這個注解的作用是:在springboot啟動並自動配置時排除自動配置數據源信息,排除之后,在application.yml或application.properties中即使沒有配置dataSource仍正常運行,否則會因為自動配置了數據源而找不到數據源的配置報錯!
上面的是同行們的經驗!但是我發現,即使不配置好像也沒關系!一臉懵逼
3,配置dataSource數據源信息
創建一個數據源配置類,配置數據源信息,多個數據源可以配置多個Resource
@Configuration
public class DBConfiguration {
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
tomcat.enableNaming();//啟用默認禁用的JNDI命名
return super.getTomcatWebServer(tomcat);
}
@Override
protected void postProcessContext(Context context) {
//數據源 1
//構建一個ContextResource對象,然后添加到Context對象中
ContextResource resource = new ContextResource();
resource.setName("jdbc/MyFirstMySql");
resource.setType(DataSource.class.getName());
resource.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
resource.setProperty("url", "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC");
resource.setProperty("username", "root");
resource.setProperty("password","1234");
context.getNamingResources().addResource(resource);
//數據源 2
//構建一個ContextResource對象,然后添加到Context對象中
ContextResource resource1 = new ContextResource();
resource1.setName("jdbc/MySecondMySql");
resource1.setType(DataSource.class.getName());
resource1.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
resource1.setProperty("url", "jdbc:mysql://localhost:3306/guli?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC");
resource1.setProperty("username", "root");
resource1.setProperty("password","1234");
context.getNamingResources().addResource(resource1);
super.postProcessContext(context);
}
};
return tomcat;
}
}
4,配置yml文件
只需要在yml文件中指定要使用的數據源名稱即可,其他的不需要配置
spring:
datasource:
jndi-name: jdbc/MySecondMySql
到這里其實集成jndi數據源就已經結束了,就可以使用了,下面來進行測試!
5,開始測試
創建mapper文件,並注入到ctrl中進行測試,運行項目訪問
content這張表在上面的兩個數據庫中同時存在,不過在guli數據庫中是多條數據,而在test數據庫中是只有一條數據,這樣可以區分開來看效果!
@Mapper
public interface TestMapper {
@Select(value = "select * from content")
List<Map> getList();
}
@Autowired
TestMapper testMapper;
@RequestMapping("/getList")
@ResponseBody
public List<Map> getList(){
return testMapper.getList();
}
首先更改yml配置的jndi數據源名稱為MyFirstMySql,重啟項目,訪問接口http://localhost:8080/getList
更改yml配置的jndi數據源名稱為MySecondMySql,重啟項目,訪問接口http://localhost:8080/getList
三,總結
以下幾種情況分別集成jndi數據源區別還是很大的,多注意一下!
1,spring外部容器集成jndi
2,springboot外部容器集成jndi
3,springboot1.X內部容器集成jndi
4,springboot2.X內部容器集成jndi
詳情參考
https://www.cnblogs.com/springboot-wuqian/archive/2004/01/13/9540439.html
就到這里了,再見!