開發部落格系統的時候有一個需求,就是希望系統啟動時,自動将指定檔案夾中的md檔案寫入到資料庫,這樣我每更新一篇文章隻需将文章拷貝入那個檔案夾即可。(當然也可以開發界面上傳的方式,但我不想搞得那麼複雜,怎麼友善怎麼來)。資料庫表長這樣:

存儲文章的檔案夾長這樣:
這裡用@PostConstruct這個注解很好實作,注意系統啟動時,初始化的順序為:構造方法 -> @Autowired -> @PostConstruct
@Component
@Order(Ordered.HIGHEST_PRECEDENCE) //指定執行順序
public class InitHandler {
@Value("${file.upload.abpath}") //從配置檔案中取出指定檔案夾
private String abpath;
@Autowired
private ArticleService articleService; //引入ArticleService接口操作資料庫
private Logger logger = LoggerFactory.getLogger(this.getClass()); //定義logger寫日志
public InitHandler(){
this.logger.info("開始資料初始化");
}
@PostConstruct
public void init() throws Exception {
this.logger.info("資料庫 初始化開始");
//1.讀取abpath中所有的檔案
//需要過濾的檔案夾,存放image
String imgAbPath=abpath+"assets/";
//需要過濾的檔案夾,測試
String testPath=abpath+"test/";
ArrayList<String> ar=new ArrayList<>();
ar.add(imgAbPath);
ar.add(testPath);
//擷取所有檔案路徑清單
ArrayList<String> fs = FileUtil.getDirsOrFiles(abpath, ar);
List<Article> articles = articleService.queryAll();
//擷取資料庫中所有md檔案title,用一個List接收
List<String> list=new ArrayList<>();
articles.forEach(article -> {
list.add(article.getTitle());
});
for(String s :fs){
File f=new File(s);
//擷取絕對路徑
this.logger.info("originalName: "+f.getAbsolutePath());
String arabpath =f.getAbsolutePath();
//擷取名子
String name=f.getName().split("\\.")[0];
//過濾掉資料庫中已有md檔案,這種方法快,不用重複查資料庫,提高效率
if(list.contains(name)){
continue;
}
//将資料寫入資料庫
Article art=new Article();
art.setCategoryId(1L);
art.setName(f.getName());
art.setTitle(name);
art.setCreateTime(new Timestamp(System.currentTimeMillis()));
articleService.addArticle(art);
this.logger.info(f.getName()+"已寫入資料庫");
}
}
}
這裡用到的getDirsOrFiles(String strPath,ArrayList filterDirs)定義如下:
/**
*
* @param strPath 檔案夾的絕對路徑
* @param filterDirs 檔案夾中需要過濾掉的檔案夾List
* @return 遞歸查詢到的文體絕對路徑清單
* @throws Exception
*/
public static ArrayList<String> getDirsOrFiles(String strPath,ArrayList<String> filterDirs) throws Exception {
ArrayList<String> mfiles = new ArrayList<String>();
try {
File f = new File(strPath);
if (f.isDirectory()) {
File[] fList = f.listFiles();
for (int j = 0; j < fList.length; j++) {
if (fList[j].isDirectory()) {
//如果含有filterDirs中包含的檔案夾則過濾掉
for(String s:filterDirs){
if (fList[j].equals(filterDirs)){
continue;
}
}
// System.out.println("Directory is: " + fList[j].getPath());
getDirsOrFiles(fList[j].getPath(),filterDirs); // 對目前目錄下仍是目錄的路徑進行周遊
}
}
for (int j = 0; j < fList.length; j++) {
if (fList[j].isFile()) {
String name = fList[j].getPath().toString();
// System.out.println("Filename is: " + name);
mfiles.add(fList[j].getPath());
}
}
}
return mfiles;
} catch (Exception e) {
System.err.println("Error: " + e);
return null;
}
}
這個函數的作用是遞歸擷取某檔案夾下所有檔案,同時可以指定在遞歸過程中過濾掉指定的檔案夾,比如指定檔案夾中的assets檔案夾是放圖檔的,我不需要擷取裡面的png或jpg檔案,于是可以将其過濾掉。
啟動系統可以看到日志如下 :
說明系統啟動時成功執行初始化資料庫的操作。