NoSQL + MongoDB + springBoot 2.0.3 + thymeleaf 開發檔案伺服器
NoSQL 簡介
NoSQL(NoSQL = Not Only SQL ),意即"不僅僅是SQL"。
在現代的計算系統上每天網路上都會產生龐大的資料量。
這些資料有很大一部分是由關係資料庫管理系統(RDBMS)來處理。 1970年 E.F.Codd's提出的關係模型的論文 "A relational model of data for large shared data banks",這使得資料建模和應用程式程式設計更加簡單。
通過應用實踐證明,關係模型是非常適合於客戶伺服器程式設計,遠遠超出預期的利益,今天它是結構化資料儲存在網路和商務應用的主導技術。
NoSQL 是一項全新的資料庫革命性運動,早期就有人提出,發展至2009年趨勢越發高漲。NoSQL的擁護者們提倡運用非關係型的數
主要特點
- MongoDB 是一個面向文件儲存的資料庫,操作起來比較簡單和容易。
- 你可以在MongoDB記錄中設定任何屬性的索引 (如:FirstName="Sameer",Address="8 Gandhi Road")來實現更快的排序。
- 你可以通過本地或者網路建立資料映象,這使得MongoDB有更強的擴充套件性。
- 如果負載的增加(需要更多的儲存空間和更強的處理能力) ,它可以分佈在計算機網路中的其他節點上這就是所謂的分片。
- Mongo支援豐富的查詢表示式。查詢指令使用JSON形式的標記,可輕易查詢文件中內嵌的物件及陣列。
- MongoDb 使用update()命令可以實現替換完成的文件(資料)或者一些指定的資料欄位 。
- Mongodb中的Map/reduce主要是用來對資料進行批量處理和聚合操作。
- Map和Reduce。Map函式呼叫emit(key,value)遍歷集合中所有的記錄,將key與value傳給Reduce函式進行處理。
- Map函式和Reduce函式是使用Javascript編寫的,並可以通過db.runCommand或mapreduce命令來執行MapReduce操作。
- GridFS是MongoDB中的一個內建功能,可以用於存放大量小檔案。
- MongoDB允許在服務端執行指令碼,可以用Javascript編寫某個函式,直接在服務端執行,也可以把函式的定義儲存在服務端,下次直接呼叫即可。
- MongoDB支援各種程式語言:RUBY,PYTHON,JAVA,C++,PHP,C#等多種語言。
- MongoDB安裝簡單。
前面小編我簡單摘要關於什麼是NoSQL 和 MongoDB 簡介與關係
- 下面我們就開始MongoDB + springBoot 2.0.3開發檔案伺服器
- 既然是基於Springboot2.0.3開發開發檔案伺服器 ,那我們肯定第一搭建開發環境
application.yml 檔案中配置引數
#server 上下文路徑 server: port: 8989 address: 127.0.0.1 #配置thymeleaf spring: thymeleaf: encoding: UTF-8 cache: false mode: HTML5 #分割檔案上載大小 servlet: multipart: max-file-size: 1024KB max-request-size: 1024KB # 自定義獨立配置 MongoDB 服務 # data: # mongodb: # uri: http://localhost:27017 |
pom.xml 新增依賴
<!-- 新增 Spring Data Mongodb 的依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <!-- 新增 Embedded MongoDB 的依賴用於測試 --> <dependency> <groupId>de.flapdoodle.embed</groupId> <artifactId>de.flapdoodle.embed.mongo</artifactId> <scope>test</scope> </dependency> <!-- 新增 Thymeleaf 的依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> |
構建檔案物件的實體類
/** * File 文件類. * @author Administrator * <br> *注意:這裡是非關係資料庫 NoSQL 建立對映實體的物件 */ @Document @Data // lombok.Data; 包含了一系列 getter,setter,toString 方法 public class File { /** * @param id 主鍵 * @param name 檔名稱 * @param contentType 檔案型別 * @param size 檔案大小 * @param uploadDate 上載日期 * @param md5 md5 加密 * @param content 檔案內容 * @param path 檔案路徑 */ @Id private String id; private String name; private String contentType; private long size; private Date uploadDate; private String md5; private Binary content; private String path; protected File() { } public File(String name, String contentType, long size,Binary content) { this.name = name; this.contentType = contentType; this.size = size; this.uploadDate = new Date(); this.content = content; } /** * 重寫equals 方法 */ @Override public boolean equals(Object object) { if (this == object) { return true; } if (object == null || getClass() != object.getClass()) { return false; } File fileInfo = (File) object; return java.util.Objects.equals(size, fileInfo.size) && java.util.Objects.equals(name, fileInfo.name) && java.util.Objects.equals(contentType, fileInfo.contentType) && java.util.Objects.equals(uploadDate, fileInfo.uploadDate) && java.util.Objects.equals(md5, fileInfo.md5) && java.util.Objects.equals(id, fileInfo.id); } /** * 重寫hashCode */ @Override public int hashCode() { return java.util.Objects.hash(name, contentType, size, uploadDate, md5, id); } @Override public String toString() { return "File{" + "name='" + name + '\'' + ", contentType='" + contentType + '\'' + ", size=" + size + ", uploadDate=" + uploadDate + ", md5='" + md5 + '\'' + ", id='" + id + '\'' + '}'; } } |
編寫repository 層,我實現介面應該整合springboot中 MongoDB 提供的介面類
/** * File 儲存庫.<br> * 採用MongoDB操作 * * @author Administrator * */ public interface FileRepository extends MongoRepository<File, String> { } |
編寫Service層,小編我就主要說要一下 MongoDB 分頁查詢實現,這裡我編寫了自己查詢Criteria準則,具體實現在文章結尾提供的github開源原始碼中
/** * File 服務. * @author Administrator * */ @Service public class FileServiceImpl implements FileService { /** * @param fileRepository * @param mongoTemplate */ @Autowired public FileRepository fileRepository; @Autowired protected MongoTemplate mongoTemplate; /** *分頁條件查詢,按上傳時間降序 * @throws Exception */ @Override public Page<File> listFilesByPage(Pageable pageable, MeCriteria meCriteria) throws Exception { List<ExprType> expr= meCriteria.get_expr(); //定義查詢Criteria鏈 List<Criteria> criteriaChain = new ArrayList<Criteria>();; for (ExprType exprType : expr) { String property = exprType.get_property(); if(exprType.get_value()!=null) { Object value = exprType.get_value(); //mongoDB模糊查詢 Pattern pattern = Pattern.compile("^.*" + value + ".*$"); if("name".equals(property)) { criteriaChain.add(Criteria.where("name").regex(pattern)); }else if("contentType".equals(property)) { criteriaChain.add(Criteria.where("contentType").regex(pattern)); } }else if( exprType.get_min() !=null && exprType.get_max()!=null){ Object min = exprType.get_min(); Object max = exprType.get_max(); if(exprType.get_property().equals("uploadDate")) { if(min !=null && max !=null && !"".equals(min) && !"".equals(max)) { //大於最小時間,小於最大時間 criteriaChain.add( Criteria.where("uploadDate").gt(DateUtils.parseDate((String) min, "yyyy-MM-dd HH:mm")) .lt(DateUtils.parseDate((String) max, "yyyy-MM-dd HH:mm"))); } }else if(exprType.get_property().equals("size")){ if(min !=null && max !=null && !"".equals(min) && !"".equals(max)) { //大於最小size,小於最大size criteriaChain.add(Criteria.where("size").gt(Long.parseLong((String)min)).lt(Long.parseLong((String)max))); } }
} } Criteria criteria =new Criteria(); criteria.andOperator(criteriaChain.toArray(new Criteria[criteriaChain.size()])); //查詢,加入criteria組成條件 Query query=new Query(criteria); //分頁查詢 List<File> list = mongoTemplate.find(query.with(pageable), File.class); //返回分頁查詢的物件 Page<File> page = new PageImpl<File>(list , pageable, mongoTemplate.count(query, File.class)); return page; } } |
Controller層摘要部分複雜查詢的程式碼塊
/** *檔案伺服器controller * @author Administrator * */ @CrossOrigin(origins = "*", maxAge = 3600) // 允許所有域名訪問,響應最大時間 @Controller public class FileController { @Autowired private FileService fileService; @Value("${server.address}") private String serverAddress; @Value("${server.port}") private String serverPort; /** * 訪問檔案伺服器首頁 * @param model * @return * @throws Exception */ @RequestMapping(value = "/") public String index(@RequestParam(value = "async", required = false) boolean async, @RequestParam(value = "pageIndex", required = false, defaultValue = "0") Integer pageIndex, @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, Model model) throws Exception { // 展示最新10條資料 Sort sort = new Sort(Direction.DESC,"uploadDate"); Pageable pageable = PageRequest.of(pageIndex, pageSize , sort); Page<File> page = fileService.listFilesByPage(pageable); model.addAttribute("files", page.getContent()); model.addAttribute("page" , page); return "index"; } /** * 分頁攜帶條件查詢檔案 * @param async * @param pageIndex * @param pageSize * @param criteria * @param model * @return * @throws Exception */ @RequestMapping(value = "/queryAction" , method=RequestMethod.POST) public String index(@RequestParam(value = "async", required = false) boolean async, @RequestParam(value = "pageIndex", required = false, defaultValue = "0") Integer pageIndex, @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize, CriteriaType criteriaType, Model model) throws Exception { // 展示最新二十條資料 Sort sort = new Sort(Direction.DESC,"uploadDate"); Pageable pageable = PageRequest.of(pageIndex, pageSize , sort); Page<File> page = fileService.listFilesByPage(pageable , criteriaType.getMeCriteria()); model.addAttribute("files", page.getContent()); model.addAttribute("page" , page); model.addAttribute("meCriteria", criteriaType.getMeCriteria()); return "index"; } } |
html頁面+ thymeleaf 標記實現動態資料展示,小編我遇到一些問題,但也也解決了,我截圖瞧瞧!
現在我們就看下最終成果!!!
上傳至github 原始碼!
-
注意小編這裡我不會把所有的程式碼寫入部落格中,畢竟程式碼量還是很多的,還有一點一定要安裝 MongoDB ,window傻瓜式操作不用多講!!