一般我們不把數據庫的配置信息寫死在代碼中。
寫好代碼后,編譯、調試,成功后只把輸出目錄中的東西(jar包、.class文件、資源文件等)拷貝到服務器上,由運維來管理。服務器上是沒有源文件的(.java文件),我們我們把數據庫的配置信息寫死在代碼中,運維就不能修改數據庫的配置了,如果要換服務器、要換數據庫、要改數據庫的密碼了,運維是改不了的,只能由我們修改源碼,重新編譯、部署。
通常的做法是,把配置信息寫在配置文件(文本文件)中,從配置文件中加載配置信息,這樣運維就可以直接修改配置了,無需改動源碼。
示例:
1、項目根目錄下新建文件夾resource,右鍵標識為資源根目錄
Source Root是源碼的根目錄,默認為src;
Test Source Root是調試的根目錄,比如JUnit調試的根目錄;
Resource Root是資源文件的根目錄,常用來放置配置文件,也可以放置其他資源文件,比如新建子文件夾images,下面放置圖片。
2、在resource下新建文件mysql.properties,內容如下:
driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/my_db?serverTimezone=GMT user=chy password=abcd
3、在.java文件中獲取配置信息
1 //從properties文件中加載數據庫配置 2 Properties properties = new Properties(); 3 FileInputStream inputStream = new FileInputStream("resource/mysql.properties"); //注意路徑 4 properties.load(inputStream); 5 6 String driver = properties.getProperty("driver"); 7 String url = properties.getProperty("url"); 8 String user = properties.getProperty("user"); 9 String pwd=properties.getProperty("password"); 10 11 Class.forName(driver); 12 Connection connection = DriverManager.getConnection(url, user, pwd); 13 14 //....
運行,效果正常。
但是,還是有問題。
FileInputStream inputStream = new FileInputStream("resource/mysql.properties");
這種加載資源的方式是從原項目中加載資源的,不是從部署的項目(輸出目錄)中加載資源的,你把部署好的項目拷給運維,運行報錯:找不到這個資源文件。
實際上,你不把resource文件夾標識為資源根目錄,效果也是對的。因為是從原項目中加載的資源文件。
標識為Resource Root后,運行|調試時才會把這個目錄復制到輸出目錄(部署目錄)。
正確的做法:通過反射(Class對象)來加載資源文件
InputStream inputStream = 當前類的Class對象.getResourceAsStream("/mysql.properties");
獲取當前類的Class對象,有3種方式:
(1)通過當前類的實例來獲取Class對象
InputStream inputStream = this.getClass().getResourceAsStream("/mysql.properties"); //注意路徑
getClass()是實例方法,只能通過對象來引用,不能通過類名來引用。
這種方式有個缺陷,因為使用的是this,所以這句代碼所在的方法不能是靜態的(static,類方法)。
當然,硬要寫成靜態方法也行:
InputStream inputStream = new test.Test().getClass().getResourceAsStream("/mysql.properties");
不使用this,而是new一個當前類的實例。
(2)通過當前類的class屬性來獲取Class對象
InputStream inputStream=Test.class.getResourceAsStream("/mysql.properties"); //每個類都有class屬性
(3)通過Class.forName("全類名")來獲取Class對象
InputStream inputStream=Class.forName("test.Test").getResourceAsStream("/mysql.properties"); //forName()里是當前類的全類名
路徑問題
可以看到,這2種寫法,資源文件的路徑都是/開頭,路徑中並沒有resource文件夾。
這2種都是從輸出目錄(部署目錄)中加載資源文件。只有標識為Resource Root的文件夾run|debug時才會拷貝到輸出目錄|目錄,拷貝時不拷貝資源根目錄resource,直接把resource下的子文件、子文件夾拷貝到輸出目錄中項目的根目錄下,所以路徑以/開頭,/表示項目的根目錄。