MySql、Oracle(通用方法)遞迴查詢生成檔案目錄樹(JAVA實現 遞迴過程中不訪問資料庫,遞迴之前只訪問兩次 進行遞迴前資料準備)
阿新 • • 發佈:2019-01-08
查詢檔案樹
實體類
public class TradeInfoFile { // 檔案編碼(子) private String fileCode; // 所屬檔案編碼(父) private String belongFileCode; // 交易資訊編碼 private String finTradeCode; // 是否是資料夾 private Boolean isDirFlag; //最後修改時間 private Date lastModifyTime; private String fmtLastModifyTime; /* children屬性不與資料庫中TRADER_INFO_FILE標建立對映關係 */ @Transient private List<TradeInfoFile> children; //省略set/get方法....................... // 建立檔案根節點 public static TradeInfoFile createRoot(List<TradeInfoFile> fileTree) { TradeInfoFile root = new TradeInfoFile(); root.setFileCode("-1"); root.setBelongFileCode("根節點"); root.setChildren(fileTree); return root; } }
Controller層
@RestController @RequestMapping("/trade-file") public class TradeInfoController { @Autowired private TradeInfoService tradeInfoService; // 查詢檔案樹,一個交易資訊編碼可以對應多個檔案和資料夾 @GetMapping(value = "/{id}/file-tree") // 交易資訊編碼 public TradeInfoFile getFileTree(@RequestParam(name = "id") String finTradeCode) { return tradeInfoService.getFileTree(finTradeCode); } }
Service層
public interface TradeInfoService { public TradeInfoFile getFileTree(String finTradeCode); } @Service public class TradeInfoFileServiceImpl implements TradeInfoService{ @Autowired private TradeInfoFileMapper tradeInfoFileMapper; @Override // 查詢目錄樹 public TradeInfoFile getFileTree(String finTradeCode) { /* * 思路:為了減輕資料庫的壓力,減少資料庫的訪問次數,採用少次訪問資料庫獲得檔案樹的資料,存放在 * Map中,遞迴時,從Map中取數,不在訪問資料庫 * 引數準備: * rootMap:根目錄所有檔案和資料夾(遞迴時,下一級檔案裡一層的檔案和資料夾) * Map<fileCode, tradeInfoFile> * allMap:所有檔案和資料夾 * Map<fileCode, tradeInfoFile> * allBelongFileCodeMap:以belongFileCode為key對應的Map集合 * Map<belongFileCode, Map<fileCode, tradeInfoFile>> */ Map<String, TradeInfoFile> rootMap = new HashMap<>(); Map<String, TradeInfoFile> allMap = new HashMap<>(); Map<String, Map<String, TradeInfoFile>> allBelongFileCodeMap = new HashMap<>(); getParameterMap(finTradeCode, rootMap, allMap, allBelongFileCodeMap); // 呼叫遞迴方法, List<TradeInfoFile> tempTree = getTree(rootMap, allMap, allBelongFileCodeMap); List<TradeInfoFile> tree = new ArrayList<>(); TradeInfoFile tradeInfoFile = TradeInfoFile.createRoot(tree); // 解除地址引用 for (TradeInfoFile item : tempTree) { tree.add(item); } return tradeInfoFile; } // 遞迴查詢生成目錄樹 private List<TradeInfoFile> getTree(Map<String, TradeInfoFile> rootMap, Map<String, TradeInfoFile> allMap, Map<String, Map<String, TradeInfoFile>> allBelongFileCodeMap){ // 臨時檔案樹 List<TradeInfoFile> tempTree = new ArrayList<>(); for (String fileCode : rootMap.keySet()) { TradeInfoFile tradeInfoFile = rootMap.get(fileCode); /* * 資料夾: * 非空資料夾:繼續遞迴 * 空資料夾:新增到檔案樹中 * 檔案: * 新增到檔案樹中 */ if(tradeInfoFile.getIsDirFlag()) { //資料夾 /* * 獲取當前資料夾裡 的一層的 檔案和資料夾 nextRootMap,作為遞迴的引數 */ Map<String, TradeInfoFile> nextRootMap = allBelongFileCodeMap.get(fileCode); if(null != nextRootMap){ // 非空資料夾 List<TradeInfoFile> childrenTree = getTree(nextRootMap, allMap, allBelongFileCodeMap); tradeInfoFile.setChildren(childrenTree); } } tempTree.add(tradeInfoFile); } // 對查詢出來的檔案樹 進行排序 Collections.sort(tempTree, new Comparator<TradeInfoFile>() { @Override public int compare(TradeInfoFile o1, TradeInfoFile o2) { // 同級目錄 優先按資料夾排序 降序 if(!o2.getIsDirFlag().equals(o1.getIsDirFlag())){ return o2.getIsDirFlag().compareTo(o1.getIsDirFlag()); } //其次 按照 最後修改時間 排序 倒序 return o2.getLastModifyTime().compareTo(o1.getLastModifyTime()); } }); return tempTree; } // 遞迴查詢目錄樹前引數準備 private void getParameterMap(String finTradeCode, Map<String, TradeInfoFile> rootMap, Map<String, TradeInfoFile> allMap, Map<String, Map<String, TradeInfoFile>> allBelongFileCodeMap) { // 查詢 所有 檔案和資料夾 TradeInfoFile entity = new TradeInfoFile(); entity.setFinTradeCode(finTradeCode); List<TradeInfoFile> allEntitys = tradeInfoFileMapper.selectByEntity(entity); // 查詢根目錄下的 所有 檔案和資料夾 entity.setBelongFileCode("0"); List<TradeInfoFile> rootEntitys = tradeInfoFileMapper.selectByEntity(entity); for (TradeInfoFile item : allEntitys) { String fileCode = item.getFileCode(); String belongFileCode = item.getBelongFileCode(); // 檔案時間格式化 item.setFmtLastModifyTime(new SimpleDateFormat("YYYY-MM-DD").format(item.getLastModifyTime())); allMap.put(fileCode, item); // 第一次,allBelongFileCodeMap中對應K=belongFileCode的value為null;所以,new HashMap一次,給一個地址,後續使用好往裡面塞值(put進去) if(null == allBelongFileCodeMap.get(belongFileCode)){ allBelongFileCodeMap.put(belongFileCode, new HashMap<String, TradeInfoFile>()); } /* * Map<String, Map<String, TradeInfoFile>> allBelongFileCodeMap * Map是引用型別,allBelongFileCodeMap.get(belongFileCode)取出是一個Map, * allBelongFileCodeMap.get(belongFileCode).put(fileCode, item); * 就可以使allBelongFileCodeMap中belongFileCode對應value:map的值發生變化;(主要是地址的引用) */ allBelongFileCodeMap.get(belongFileCode).put(fileCode, item); } for (TradeInfoFile item : rootEntitys) { // 檔案時間格式化 item.setFmtLastModifyTime(new SimpleDateFormat("YYYY-MM-DD").format(item.getLastModifyTime())); rootMap.put(item.getFileCode(), item); } } }