1. 程式人生 > >NoSQL + MongoDB + springBoot 2.0.3 + thymeleaf 開發檔案伺服器

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傻瓜式操作不用多講!!