SpringBoot教程(第4版)課件 第5章 Spring Boot數據庫開發(fā)_第1頁
SpringBoot教程(第4版)課件 第5章 Spring Boot數據庫開發(fā)_第2頁
SpringBoot教程(第4版)課件 第5章 Spring Boot數據庫開發(fā)_第3頁
SpringBoot教程(第4版)課件 第5章 Spring Boot數據庫開發(fā)_第4頁
SpringBoot教程(第4版)課件 第5章 Spring Boot數據庫開發(fā)_第5頁
已閱讀5頁,還剩134頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第5章SpringBoot數據庫開發(fā)——數據庫與持久層框架SpringBoot實用教程(第4版)數據庫與持久層框架目前最為常用的持久層框架有:MyBatis、JPA、DataRedis和DataMongoDB等,其中MyBatis、JPA通過驅動操作各種關系數據庫(如MySQL、SQLServer等),而DataRedis和DataMongoDB則分別用于操作NoSQL型的Redis和MongoDB數據庫,如圖5.1所示。第5章SpringBoot數據庫開發(fā)——MyBatis開發(fā)基礎目錄01MyBatis簡介MyBatis簡介MyBatis是一個支持定制化SQL、存儲過程以及高級映射的優(yōu)秀持久層框架,它避免了幾乎所有的JDBC代碼、手動設置參數以及獲取結果集,可以對配置和原生Map使用簡單的注解,將接口和Java的POJO映射成數據庫中的記錄。MyBatis采用的是一種基于SQL到POJO的模型,它需要開發(fā)者提供SQL、映射關系和POJO類。對于SQL與POJO的映射關系,它提供了自動映射和駝峰映射等,大大減少了開發(fā)者的工作量;由于沒有屏蔽SQL,使開發(fā)者可以盡可能地通過SQL去優(yōu)化性能,也可以做少量的改變以適應靈活多變的互聯(lián)網環(huán)境,這些對于追求高響應和高性能的互聯(lián)網應用系統(tǒng)是十分重要的。與此同時,它還能支持動態(tài)SQL,以適應需求的變化。因而MyBatis隨著中國互聯(lián)網產業(yè)的發(fā)展日趨流行并成為國內市場的主流持久層框架。MyBatis社區(qū)為了整合Spring早就發(fā)布了相應的開發(fā)包,SpringBoot則進一步將其整合進來作為SQL依賴的一個基本組件,我們可以在開發(fā)時勾選MyBatis社區(qū)提供的starter,就可以直接在項目中使用MyBatis。目錄02MyBatis原理MyBatis原理MyBatis是一個基于SqlSessionFactory構建的框架,SqlSessionFactory的作用是生成SqlSession接口對象,這個接口對象是MyBatis操作的核心。由于SqlSessionFactory的作用是單一(僅用于創(chuàng)建SqlSession)的,故其在MyBatis應用的生命周期中往往會以單例模式(即只存在一個SqlSessionFactory對象)運行。SpringBoot將MyBatis框架整合進來,提供了兩個類:MapperFactoryBean和MapperScannerConfigurer,這里的MapperFactoryBean是針對一個接口配置,而MapperScannerConfigurer則負責掃描裝配,如圖5.2所示。MyBatis原理生成SqlSessionFactory是通過配置類來完成的,它會給予用戶在配置文件(perties)中進行配置的選項,從圖5.2中可以了解MyBatis可配置的主要內容有:properties(屬性):在實際應用中一般采用Spring而非MyBatis來配置屬性文件。mappers(映射器):是MyBatis最核心的組件,它提供SQL與POJO類的映射關系,這是MyBatis開發(fā)的核心。objectFactory(對象工廠):在MyBatis生成返回的POJO時會調用這個工廠類,實際開發(fā)一般使用MyBatis默認提供的對象工廠類(DefaultObjectFactory),無須額外配置。settings(設置):可以配置映射規(guī)則(如自動映射或駝峰映射)、執(zhí)行器類型、緩存等,決定MyBatis的底層行為,比較復雜,具體配置項可參考MyBatis官網說明。plugins(插件):也稱為攔截器,它通過動態(tài)代理和責任鏈模式來完成,可以修改MyBatis底層的功能實現(xiàn)。typeAliases(類型別名):MyBatis會對常用的類提供默認別名,由于類的全限定名通常會比較冗長,通過typeAliases配置自定義的別名能增強可讀性。databaseIdProvider(數據庫廠商標識):允許MyBatis配置多類型數據庫的支持,不常用。environments(數據庫環(huán)境):可配置數據庫連接的內容和事務,通常這些都交由Spring托管。typeHandlers(類型處理器):在MyBatis寫入和讀取數據庫的過程中對于不同類型的數據進行自定義轉換,但在大多數情況下用不到,因為MyBatis本身就已經定義好了很多現(xiàn)成的typeHandler,框架會自動識別并實現(xiàn)各種常用類型的轉換。目錄03MyBatis注解1.基礎注解2.映射注解3.高級注解MyBatis注解1.基礎注解增刪改查是所有關系數據庫最基本的業(yè)務操作,MyBatis提供下面四個基礎注解供用戶構建自己的SQL語句:@Select:用于構建查詢(SELECT)語句。@Insert:用于構建插入(INSERT)語句。@Update:用于構建更新(UPDATE)語句。@Delete:用于構建刪除(DELETE)語句。MyBatis注解2.映射注解映射注解用于建立實體與關系的映射,MyBatis提供的映射注解有以下三個:@Result:用于填寫結果集的單個字段的映射關系。@Results:用于填寫結果集的多個字段的映射關系。@ResultMap:根據ID關聯(lián)XML里面的<resultMap>。3.高級注解MyBatis對應基礎的增刪改查提供有以下四個高級注解:@SelectProvider:用于構建動態(tài)查詢SQL。@InsertProvider:用于構建動態(tài)插入SQL。@UpdateProvider:用于構建動態(tài)更新SQL。@DeleteProvider:用于構建動態(tài)刪除SQL。目錄04MyBatis應用實例1.準備數據2.創(chuàng)建項目3.配置連接4.MyBatis實現(xiàn)商品管理5.分頁功能MyBatis應用實例【實例5.1】通過MyBatis操作MySQL實現(xiàn)“商品信息管理系統(tǒng)”的“商品管理”(包括商品添加、刪除、修改、查詢和分頁顯示)功能。1.準備數據本例演示程序功能需要商品表(commodity)及其樣本記錄,而商品表又以外鍵關聯(lián)于商品分類表(category)和商家表(supplier)的記錄,故要先分別創(chuàng)建這幾個表及錄入必需的樣本數據。通過NavicatPremium連上MySQL,在其查詢編輯器中執(zhí)行SQL語句。(1)創(chuàng)建商品分類表(category)及錄入樣本執(zhí)行SQL語句為:USEnetshop;CREATETABLEcategory( TCode char(3) NOTNULLPRIMARYKEY, /*商品分類編碼*/ TName varchar(8) NOTNULL /*商品分類名稱*/);INSERTINTOcategory VALUES ('11A','蘋果'), ('11B','梨');MyBatis應用實例(2)錄入商家表(supplier)的樣本商家表在做前面章節(jié)實例的時候已經創(chuàng)建好了,此處只須錄入樣本,執(zhí)行SQL語句為:USEnetshop;INSERTINTOsupplier(SCode,SName,SweiXin,Tel)VALUES('SDYT002A','山東煙臺棲霞蘋果批發(fā)市場','8234561-','0535-823456X');INSERTINTOsupplier(SCode,SName,SWeiXin,Tel)VALUES('XJAK003A','新疆阿克蘇地區(qū)紅旗坡農場','8345612-','0997-834561X');INSERTINTOsupplier(SCode,SName,SWeiXin,Tel)VALUES('XJAK005B','新疆安利達果業(yè)有限公司','8456123-','0996-845612X');INSERTINTOsupplier(SCode,SName,SWeiXin,Tel)VALUES('AHSZ006B','安徽碭山皇冠梨供應公司','8561234-','0557-856123X');(3)創(chuàng)建商品表(commodity)及錄入樣本執(zhí)行SQL語句為。MyBatis應用實例2.創(chuàng)建項目創(chuàng)建SpringBoot項目,項目名為MyBatis,在出現(xiàn)的向導界面“Dependencies”列表中勾選SpringBoot基本框架(“Web”→“SpringWeb”)、Thymeleaf引擎組件(“TemplateEngines”→“Thymeleaf”)、Lombok模型簡化組件(“DeveloperTools”→“Lombok”)、MyBatis框架(“SQL”→“MyBatisFramework”)以及MySQL的驅動(“SQL”→“MySQLDriver”)。3.配置連接打開項目工程目錄樹src→main→resources下的perties文件,在其中配置對MySQL數據庫的連接,內容如下:spring.datasource.url=jdbc:mysql://:3306/netshop?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=truespring.datasource.username=rootspring.datasource.password=123456spring.datasource.driver-class-name=com.mysql.cj.jdbc.DriverMyBatis應用實例4.MyBatis實現(xiàn)商品管理(1)設計模型本例用到的模型就是一個商品類,在項目工程目錄樹的com.example.mybatis節(jié)點下創(chuàng)建model包,其中創(chuàng)建Commodity.java,代碼為:packagecom.example.mybatis.model;

importlombok.Data;

@DatapublicclassCommodity{ privateintpid; //商品號 privateStringtcode; //商品分類編碼 privateStringscode; //商家編碼 privateStringpname; //商品名稱 privatefloatpprice; //商品價格 privateintstocks; //商品庫存}MyBatis應用實例(2)定義數據接口使用MyBatis的持久層數據接口還是需要由用戶自己來開發(fā)定義的。在項目工程目錄樹的com.example.mybatis節(jié)點下創(chuàng)建mapper包,其中創(chuàng)建接口ComMapper,在接口中以MyBatis的注解分別構建對商品模型實體增刪改查的各個SQL語句。接口ComMapper.java的定義代碼為:(3)開發(fā)控制器由于本例業(yè)務邏輯很簡單,且旨在演示MyBatis持久層的操作機制,故省去業(yè)務層的開發(fā),直接用控制器來調用Mapper接口中的方法。在項目工程目錄樹的com.example.mybatis節(jié)點下創(chuàng)建controller包,其中創(chuàng)建控制器類MyBController,代碼顯示。MyBatis應用實例(4)運行啟動SpringBoot項目,打開瀏覽器,分別測試MyBatis對商品記錄增刪改查的操作。①查詢商品號為1的商品記錄地址欄輸入http://localhost:8080/com/get?pid=1回車,看到1號商品記錄信息如圖5.3所示。MyBatis應用實例②查詢所有的商品記錄地址欄輸入http://localhost:8080/com/getall回車,看到當前數據庫商品表中所有的商品記錄信息如圖5.4所示。MyBatis應用實例③添加商品記錄添加一個商品號為1002的商品,通過URL請求參數傳遞該商品的各項基本信息,在地址欄輸入http://localhost:8080/com/add?pid=1002&tcode=11B&scode=AHSZ006B&pname=碭山梨5斤箱裝特大果&pprice=17.90&stocks=6834回車,運行結果如圖5.5所示,打開數據庫商品表,可看到新添加的商品。MyBatis應用實例④更新商品庫存修改新添加的1002號商品的庫存(增加1000),地址欄輸入http://localhost:8080/com/set?pid=1002&stocks=7834回車,運行結果如圖5.6所示,打開數據庫商品表,看到庫存已更新。MyBatis應用實例⑤刪除商品記錄刪除剛添加的1002號商品,地址欄輸入http://localhost:8080/com/del?pid=1002回車,運行結果如圖5.7所示。運行完再次打開商品表,看到已沒有了1002號商品記錄。MyBatis應用實例5.分頁功能在實際開發(fā)中,如果要顯示的商品信息記錄數很多,就要采用分頁顯示,分頁功能可以通過PageHelper來實現(xiàn),步驟如下。(1)添加PageHelper插件PageHelper是MyBatis框架的一個插件,專用于支持在MyBatis應用中執(zhí)行分頁操作,使用前需要先添加依賴到項目中。打開項目的pom.xml文件,添加內容如下:<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>4.1.6</version></dependency>MyBatis應用實例(2)開發(fā)配置類PageHelper需要以Java配置的方式注入SpringBoot容器中才能使用,為此要先開發(fā)一個配置類。在項目工程目錄樹的com.example.mybatis節(jié)點下創(chuàng)建configer包,其中創(chuàng)建配置類PageConfiger.java,代碼顯示。說明:Properties為PageHelper設置屬性,這里設了3個屬性:“offsetAsPageNum”設為true,將RowBounds第1個參數offset作為頁碼(pageNum);“rowBoundsWithCount”設為true,在使用RowBounds分頁時進行count查詢;“reasonable”啟用合理化,若pageNum小于1,查詢首頁,若pageNum大于總頁數(pages),則查詢尾頁。MyBatis應用實例(3)開發(fā)控制器在項目controller包中創(chuàng)建分頁控制器類PageController,代碼顯示。說明:①控制器方法通過兩個參數start和size分別接收當前頁碼及每頁要顯示的記錄數。②調用PageHelper的startPage方法(傳入start和size參數)執(zhí)行分頁,還可以設置排序方式,這里設為“"PidDESC"”表示按商品號降序排列。③分頁插件通過一個PageInfo類型的對象來創(chuàng)建分頁形式的數據集合,將其直接傳遞(通過addAttribute方法添加)給視圖即可在前端頁面上顯示。(4)設計前端頁面在項目工程目錄樹的src→main→resources→templates節(jié)點下創(chuàng)建前端頁面index.html,代碼顯示。MyBatis應用實例(5)運行啟動項目,打開瀏覽器,地址欄輸入http://localhost:8080/compage/getall回車,看到分頁表格顯示的商品信息,可以通過點擊表格底部的“下一頁”、“上一頁”、“尾頁”和“首頁”等鏈接翻看不同頁的記錄,如圖5.8所示。第5章SpringBoot數據庫開發(fā)——JPA開發(fā)基礎目錄01JPA簡

介JPA簡介JPA(JavaPersistenceAPI)最初是由Java官方提出的一個持久化規(guī)范,它通過注解或XML描述對象—關系(表)的映射關系,并將內存中的實體對象持久化到數據庫。JPA屬于JSR-220(EJB3.0)規(guī)范的一部分,但是JSR-220規(guī)定實體對象(EntityBean)由JPA進行支持,所以JPA不僅僅局限于EJB3.0,在傳統(tǒng)輕量級JavaEE開發(fā)時代,著名的持久層框架Hibernate實現(xiàn)了完全的JPA規(guī)范,JPA也就隨著Hibernate的廣泛應用而流行起來。后來,Spring推出了一個名為SpringData的子項目,旨在統(tǒng)一和簡化各類型數據的持久化存儲方式,其中的SpringDataJPA封裝了Hibernate作為JPA規(guī)范的默認實現(xiàn),這也就是當前SpringBoot中所支持的JPA,即通常所謂的“JPA框架”,如圖5.9所示。目錄02JPA實現(xiàn)“一對一”關聯(lián)1.創(chuàng)建關聯(lián)表2.創(chuàng)建項目3.配置連接4.設計關聯(lián)實體5.開發(fā)持久層6.編寫控制器7.運行演示“一對一”JPA實現(xiàn)“一對一”關聯(lián)【實例5.2】保存商品圖片的同時向商品表中添加對應商品的記錄,刪除圖片時也聯(lián)動一起刪除該商品記錄。1.創(chuàng)建關聯(lián)表之前做實例時已經在數據庫中創(chuàng)建了商品表(commodity),現(xiàn)在還需要建一個與之關聯(lián)的商品圖片表(commodityimage)。執(zhí)行如下SQL語句:USEnetshop;CREATETABLEcommodityimage( Pid int(8) NOTNULLPRIMARYKEY, /*商品號*/ Image blob NOTNULL, /*商品圖片(最大64KB)*/

FOREIGNKEY(Pid)REFERENCEScommodity(Pid) ONDELETECASCADEONUPDATECASCADE);JPA實現(xiàn)“一對一”關聯(lián)2.創(chuàng)建項目創(chuàng)建SpringBoot項目,項目名為JpaOneToOne,在出現(xiàn)的向導界面“Dependencies”列表中勾選SpringBoot基本框架(“Web”→“SpringWeb”)、Lombok模型簡化組件(“DeveloperTools”→“Lombok”)、JPA框架(“SQL”→“SpringDataJPA”)以及MySQL的驅動(“SQL”→“MySQLDriver”)。3.配置連接在項目perties文件中配置對MySQL數據庫的連接,內容如下:spring.datasource.url=jdbc:mysql://:3306/netshop?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=truespring.datasource.username=rootspring.datasource.password=123456spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.jpa.show-sql=trueJPA實現(xiàn)“一對一”關聯(lián)4.設計關聯(lián)實體在項目工程目錄樹的com.example.jpaonetoone節(jié)點下創(chuàng)建entity包,其中創(chuàng)建兩個關聯(lián)的實體類。(1)商品實體商品實體對應的是商品表(commodity),設計實體類Commodity.java,代碼如下:packagecom.example.jpaonetoone.entity;

importlombok.Data;

importjavax.persistence.*;

@Entity //@Entity注解聲明該模型類為一個實體@Data@Table(name="commodity") //@Table注解聲明實體所對應的數據庫表名publicclassCommodity{ @Id //@Id注解標注表的主鍵所對應的實體類屬性(這里是商品號pid) privateintpid; privateStringtcode; privateStringscode; privateStringpname; privatefloatpprice; privateintstocks;}JPA實現(xiàn)“一對一”關聯(lián)(2)商品圖片實體商品圖片實體對應的是商品圖片表(commodityimage),設計實體類Commodityimage.java,代碼如下:packagecom.example.jpaonetoone.entity;

importlombok.Data;

importjavax.persistence.*;

@Entity@Data@Table(name="commodityimage")publicclassCommodityimage{ @Id privateintpid; privatebyte[]image; @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="Pid") privateCommoditycommodity; //添加定義與之對應的商品實體對象屬性}JPA實現(xiàn)“一對一”關聯(lián)5.開發(fā)持久層有了JPA框架,持久層的開發(fā)就變得極為簡單,只須定義接口繼承JPA的JpaRepository接口即可,用戶完全不用自己去編寫任何實現(xiàn)代碼。在項目工程目錄樹的com.example.jpaonetoone節(jié)點下創(chuàng)建repository包,其中創(chuàng)建兩個接口,分別對應操作兩個實體。(1)操作商品實體的接口創(chuàng)建接口ComRepository.java,其定義代碼如下:packagecom.example.jpaonetoone.repository;

importcom.example.jpaonetoone.entity.Commodity;importorg.springframework.data.jpa.repository.JpaRepository;

publicinterfaceComRepositoryextendsJpaRepository<Commodity,Integer>{ CommodityqueryByPid(intpid); //根據商品號查詢商品實體}JPA實現(xiàn)“一對一”關聯(lián)(2)操作商品圖片實體的接口創(chuàng)建接口ImgRepository.java,其定義代碼如下:packagecom.example.jpaonetoone.repository;

importcom.example.jpaonetoone.entity.Commodityimage;importorg.springframework.data.jpa.repository.JpaRepository;

publicinterfaceImgRepositoryextendsJpaRepository<Commodityimage,Integer>{ voiddeleteById(intpid); //根據商品號刪除商品圖片實體}JPA實現(xiàn)“一對一”關聯(lián)說明:上面接口中的兩個方法queryByPid和deleteById都是JPA框架內置的,只要用戶自定義的接口繼承了JPA的JpaRepository就可以直接拿來用,在編程時由JPA按默認約定自動提示用戶鍵入所需的方法名,如圖5.10所示操作即可。JPA實現(xiàn)“一對一”關聯(lián)6.編寫控制器要測試以上建立的一對一關聯(lián)是否成立,需要編寫測試程序,本例的測試主程序代碼寫在控制器中。在項目工程目錄樹的com.example.jpaonetoone節(jié)點下創(chuàng)建controller包,其中創(chuàng)建控制器類JpaController.java,代碼顯示。7.運行演示“一對一”(1)準備本例需要用到的商品圖片保存在C:\CommodityPictures\(與控制器代碼中指定的要一致)目錄,圖片名為“碭山梨.jpg”,如圖5.11所示。啟動項目,打開瀏覽器。JPA實現(xiàn)“一對一”關聯(lián)(2)測試關聯(lián)添加地址欄輸入http://localhost:8080/com/add?pid=1002&tcode=11B&scode=AHSZ006B&pname=碭山梨5斤箱裝特大果&pprice=17.90&stocks=6834回車,商品號1002的記錄隨著圖片一起保存到了數據庫,前端顯示從數據庫查到的商品記錄,如圖5.12所示。JPA實現(xiàn)“一對一”關聯(lián)打開數據庫,可看到同步保存的圖片與商品記錄,如圖5.13所示。JPA實現(xiàn)“一對一”關聯(lián)從IDEA開發(fā)環(huán)境底部子窗口的輸出中可看到,JPA先后執(zhí)行了兩條INSERT語句,如圖5.14所示。JPA實現(xiàn)“一對一”關聯(lián)(3)測試聯(lián)動刪除地址欄輸入http://localhost:8080/com/del?pid=1002回車,前端顯示信息如圖5.15所示。再次打開數據庫,可看到圖片及商品記錄都已經一并刪除了。從IDEA輸出中也可看到JPA是先后執(zhí)行了兩條DELETE語句,如圖5.16所示。目錄03JPA實現(xiàn)“一對多”關聯(lián)1.創(chuàng)建項目2.配置連接3.設計關聯(lián)實體4.開發(fā)持久層5.編寫控制器6.運行演示“一對多”JPA實現(xiàn)“一對多”關聯(lián)【實例5.3】向商品表中添加商品記錄,并顯示某商家所提供的全部商品的信息。本例所涉及的關聯(lián)表:商家表(supplier)和商品表(commodity)在之前做實例的時候都已經建好了。1.創(chuàng)建項目創(chuàng)建SpringBoot項目,項目名為JpaOneToMany,在出現(xiàn)的向導界面“Dependencies”列表中勾選SpringBoot基本框架(“Web”→“SpringWeb”)、Lombok模型簡化組件(“DeveloperTools”→“Lombok”)、JPA框架(“SQL”→“SpringDataJPA”)以及MySQL的驅動(“SQL”→“MySQLDriver”)。2.配置連接在項目perties文件中配置MySQL數據庫連接,配置內容與【實例5.2】的完全相同,略。JPA實現(xiàn)“一對多”關聯(lián)3.設計關聯(lián)實體在項目工程目錄樹的com.example.jpaonetomany節(jié)點下創(chuàng)建entity包,其中創(chuàng)建關聯(lián)實體類。(1)商品實體商品實體對應商品表(commodity),實體類Commodity.java,其設計代碼與【實例5.2】相同,可直接拿來復用(僅所在包名修改一致即可),略。JPA實現(xiàn)“一對多”關聯(lián)(2)商家實體商家實體對應商家表(supplier),設計實體類Supplier.java,代碼如下:packagecom.example.jpaonetomany.entity;

importlombok.Data;

importjavax.persistence.*;importjava.util.List;

@Entity@Data@Table(name="supplier")publicclassSupplier{ @Id privateStringscode; privateStringsname; @OneToMany(cascade=CascadeType.ALL)//單向關系的一對多注解,用于“一”(商家)一方 @JoinColumn(name="SCode") //商品表通過外鍵SCode(商家編碼)關聯(lián)商家表 privateList<Commodity>commodityList;//添加定義列表(集合)類型的屬性}JPA實現(xiàn)“一對多”關聯(lián)4.開發(fā)持久層在項目工程目錄樹的com.example.jpaonetomany節(jié)點下創(chuàng)建repository包,其中創(chuàng)建兩個接口。(1)操作商品實體的接口創(chuàng)建接口ComRepository.java,其定義代碼如下:packagecom.example.jpaonetomany.repository;

importcom.example.jpaonetomany.entity.Commodity;importorg.springframework.data.jpa.repository.JpaRepository;

publicinterfaceComRepositoryextendsJpaRepository<Commodity,Integer>{}(2)操作商家實體的接口創(chuàng)建接口SupRepository.java,其定義代碼如下:packagecom.example.jpaonetomany.repository;

importcom.example.jpaonetomany.entity.Supplier;importorg.springframework.data.jpa.repository.JpaRepository;

publicinterfaceSupRepositoryextendsJpaRepository<Supplier,String>{ SupplierfindSupplierByScode(Stringscode); //根據商家編碼查詢商家實體}JPA實現(xiàn)“一對多”關聯(lián)5.編寫控制器在控制器中編寫程序來測試以上一對多的關聯(lián)。在項目工程目錄樹的com.example.jpaonetomany節(jié)點下創(chuàng)建controller包,其中創(chuàng)建控制器類JpaController.java,代碼顯示。6.運行演示“一對多”啟動項目,打開瀏覽器。(1)添加商品地址欄輸入http://localhost:8080/sup/addcom?pid=1002&tcode=11B&scode=AHSZ006B&pname=碭山梨5斤箱裝特大果&pprice=17.90&stocks=6834回車,將商品號1002的記錄添加到數據庫,前端顯示如圖5.17所示。JPA實現(xiàn)“一對多”關聯(lián)而數據庫商家表中,1002號商品的商家編碼“AHSZ006B”所對應的商家名稱也正是“安徽碭山皇冠梨供應公司”,如圖5.18所示。JPA實現(xiàn)“一對多”關聯(lián)(2)顯示某商家提供的商品信息地址欄輸入http://localhost:8080/sup/findcom?scode=AHSZ006B回車,顯示出商家“AHSZ006B”所提供的全部商品信息,如圖5.19所示,這與數據庫中的記錄也是一致的。目錄04JPA實現(xiàn)“多對多”關聯(lián)1.創(chuàng)建關聯(lián)表2.創(chuàng)建項目3.配置連接4.設計關聯(lián)實體5.開發(fā)持久層6.編寫控制器7.運行演示“多對多”JPA實現(xiàn)“多對多”關聯(lián)【實例5.4】創(chuàng)建兩個用戶,將同一種商品加入購物車。1.創(chuàng)建關聯(lián)表“多對多”關聯(lián)只能通過中間表的方式進行映射,而不能通過外鍵。于是在本例中,就要涉及到用戶表(user)、商品表(commodity)以及它們的中間表購物車表(preshop),一共是3個表。其中,用戶表和商品表在之前做實例時已經創(chuàng)建好了,下面來創(chuàng)建購物車表。執(zhí)行如下SQL語句:USEnetshop;CREATETABLEpreshop( UCode char(16) NOTNULL, /*用戶編碼*/ Pid int(8) NOTNULL, /*商品號*/ PRIMARY KEY(UCode,Pid));為了后面運行程序的需要,先刪除前面已經添加的商品號1002的記錄,執(zhí)行語句:DELETEFROMcommodityWHEREPid=1002;JPA實現(xiàn)“多對多”關聯(lián)2.創(chuàng)建項目創(chuàng)建SpringBoot項目,項目名為JpaManyToMany,在出現(xiàn)的向導界面“Dependencies”列表中勾選SpringBoot基本框架(“Web”→“SpringWeb”)、Lombok模型簡化組件(“DeveloperTools”→“Lombok”)、JPA框架(“SQL”→“SpringDataJPA”)以及MySQL的驅動(“SQL”→“MySQLDriver”)。3.配置連接在項目perties文件中配置MySQL數據庫連接,配置內容與【實例5.2】的完全相同,略。JPA實現(xiàn)“多對多”關聯(lián)4.設計關聯(lián)實體由于是“多對多”關聯(lián),關系的任何一方都可以作為主控方,故在雙方的實體中都要定義一個集合類型的對方的對象屬性。在項目工程目錄樹的com.example.jpamanytomany節(jié)點下創(chuàng)建entity包,其中創(chuàng)建實體類。(1)用戶實體用戶實體對應用戶表(user),設計實體類User.java,代碼顯示。(2)商品實體商品實體對應商品表(commodity),設計實體類Commodity.java,代碼顯示。JPA實現(xiàn)“多對多”關聯(lián)5.開發(fā)持久層在項目工程目錄樹的com.example.jpamanytomany節(jié)點下創(chuàng)建repository包,其中創(chuàng)建兩個接口。(1)操作用戶實體的接口創(chuàng)建接口UserRepository.java,定義代碼為:packagecom.example.jpamanytomany.repository;

importcom.example.jpamanytomany.entity.User;importorg.springframework.data.jpa.repository.JpaRepository;

publicinterfaceUserRepositoryextendsJpaRepository<User,String>{}(2)操作商品實體的接口創(chuàng)建接口ComRepository.java,定義代碼為:packagecom.example.jpamanytomany.repository;

importcom.example.jpamanytomany.entity.Commodity;importorg.springframework.data.jpa.repository.JpaRepository;

publicinterfaceComRepositoryextendsJpaRepository<Commodity,Integer>{}JPA實現(xiàn)“多對多”關聯(lián)6.編寫控制器在控制器中編寫程序來測試以上多對多的關聯(lián)。在項目工程目錄樹的com.example.jpamanytomany節(jié)點下創(chuàng)建controller包,其中創(chuàng)建控制器類JpaController.java,代碼如下:7.運行演示“多對多”啟動項目,打開瀏覽器,地址欄輸入http://localhost:8080/user/add?pid=1002&tcode=11B&scode=AHSZ006B&pname=碭山梨5斤箱裝特大果&pprice=17.90&stocks=6834回車,前端顯示如圖5.20所示。JPA實現(xiàn)“多對多”關聯(lián)此時,用戶表里添加了兩條新的用戶記錄,商品表里也添加進了1002號商品,這些都是在控制器主程序中通過持久層接口調用save方法顯式保存進數據庫的,如圖5.21所示。JPA實現(xiàn)“多對多”關聯(lián)因為在用戶實體與商品實體間存在“多對多”關聯(lián),而我們在程序中用“commodity.setUsers(users)”設置了與1002號商品關聯(lián)的用戶實體集,相當于這個實體集中的用戶都要購買1002號商品(加入購物車),故JPA還會自動在購物車表中添加記錄,如圖5.22所示。JPA實現(xiàn)“多對多”關聯(lián)另外,從IDEA輸出中也可看到JPA操作購物車表的SQL語句,如圖5.23所示。第5章SpringBoot數據庫開發(fā)——NoSQL開發(fā)基礎目錄01Redis開發(fā)入門與應用1.Redis簡介2.Redis安裝3.模板操作Redis實例4.緩存注解操作Redis實例Redis開發(fā)入門與應用1.Redis簡介Redis是一種運行在內存的數據庫,它是開源的、使用ANSIC語言編寫、遵守BSD協(xié)議、支持網絡、并提供多種語言的API。由于Redis是基于內存的,所以它的運行速度很快(大約是關系數據庫幾倍到幾十倍),在已報道的某些測試中,甚至可以完成每秒10萬次的讀寫,性能十分高效。現(xiàn)實應用中,數據的查詢要遠多于更新,據統(tǒng)計,一個正常網站日常查詢與更新之比大約是9:1到7:3,若是將常用的數據存儲在Redis中來代替關系數據庫的査詢訪問,將可以大幅提高網站的性能。Redis開發(fā)入門與應用Redis擁有十分豐富的應用場景,主要如下:計數器電商APP商品的瀏覽量、短視頻APP視頻的播放次數等信息都會被統(tǒng)計,以便用于運營或產品市場分析。為了保證數據實時生效,對用戶的每一次瀏覽都得計數,這會導致非常高的并發(fā)量。這時可以用Redis提供的incr命令來實現(xiàn)計數器功能,由于一切操作都在內存中進行,所以性能極佳。社交互動使用Redis提供的散列、集合等數據類型,可以很方便地實現(xiàn)網站(或APP)中的點贊、踩、關注共同好友等社交場景的基本功能。排行榜可以利用Redis提供的有序集合數據類型實現(xiàn)各種復雜的排行榜應用,如京東、淘寶的銷量榜,將商品按時間、銷量排行等。Redis開發(fā)入門與應用最新列表Redis可以通過LPUSH在列表頭部插入一個內容ID作為關鍵字,通過LTRIM限制列表的數量,這樣列表永遠為N個ID,無須查詢最新的列表,直接根據ID查找對應的內容即可。分布式會話在集群模式下,一般都會搭建以Redis等內存數據庫為中心的會話(Session)服務,它不再由容器管理,而是由會話服務及內存數據庫管理。高并發(fā)讀寫Redis特別適合將方法的運行結果放入緩存,以便后續(xù)在請求方法時直接去緩存中讀取。這對執(zhí)行耗時、但結果不頻繁變動的SQL查詢的支持極好。在高并發(fā)的情況下,應盡量避免請求直接訪問關系數據庫,這時可以使用Redis進行緩存操作,讓請求先訪問Redis。Redis開發(fā)入門與應用2.Redis安裝(1)下載RedisRedis下載地址為/tporadowski/redis/releases,如圖5.24所示,點頁面上的“Redis-x64-5.0.10.zip”鏈接下載ZIP壓縮版。Redis開發(fā)入門與應用本書使用Redis5.0的Windows版,下載得到的壓縮包文件名為Redis-x64-5.0.10.zip。解壓后將其中所有文件復制存盤到一個指定的目錄(筆者保存在C:\redis),如圖5.25所示。Redis開發(fā)入門與應用(2)啟動Redis打開Windows命令行,用cd命令進入保存Redis的目錄,輸入如下命令啟動Redis:redis-server.exeredis.windows.conf命令行輸出如圖5.26所示信息,表示成功啟動Redis。Redis開發(fā)入門與應用(3)安裝Redis服務圖5.26雖然啟動了Redis,但關閉命令行窗口后Redis也就關停了,為方便使用,需要把Redis安裝成Windows操作系統(tǒng)下的一個服務。關閉命令行窗口,重新打開,再次進入保存Redis的目錄,執(zhí)行如下命令:redis-server--service-installredis.windows-service.conf--loglevelverbose稍候片刻,如果沒有報錯,如圖5.27所示,表示安裝成功。Redis開發(fā)入門與應用此時,打開操作系統(tǒng)的“計算機管理”窗口,在系統(tǒng)服務列表中可以找到一個名為“Redis”的Windows服務,如圖5.28所示。Redis開發(fā)入門與應用(4)試用Redis在Redis服務啟動的情況下,通過命令行進入保存Redis的目錄,輸入以下命令連接到Redis:redis-cli.exe-h-p6379該命令創(chuàng)建了一個地址為(本地)、端口號6379的Redis數據庫連接,然后就可以使用setkeyvalue和getkey命令保存和獲得數據。這里先試著往Redis數據庫中保存一個鍵名username、值為zhouhejun的記錄,依次輸入如下命令:setusernamezhouhejun

getusername以上整個過程的命令行輸入和顯示內容如圖5.29所示。Redis開發(fā)入門與應用(5)客戶端操作Redis以上對Redis的操作都是通過命令行執(zhí)行,比較麻煩且不夠直觀。目前,已經有一些第三方開發(fā)的專用于操作Redis的可視化客戶端軟件。本書提供一個用Java開發(fā)的Redis客戶端RedisClient,下載地址是/caoxinyu/RedisClient,如圖5.30所示。Redis開發(fā)入門與應用下載得到的壓縮包文件名為RedisClient-windows.zip,解壓后直接雙擊運行RedisClient-windows\release目錄下的redisclient-win32.x86_64.2.0.jar,打開如圖5.31所示的界面。Redis開發(fā)入門與應用右擊左側子窗口中的“Redisservers”節(jié)點,點擊彈出的“Addserver”選項(或者選擇主菜單“Server”→“Add”),出現(xiàn)“Addserver”設置對話框,如圖5.32所示,在其中配置Redis連接。Redis開發(fā)入門與應用創(chuàng)建連接后,可看到“Redisservers”節(jié)點下面多了個“MyRedis”節(jié)點,雙擊展開可看到其中的數據庫,Redis中預置了db0~db15共16個數據庫。其中,db0是默認的當前數據庫,也就是說,前面通過命令行存進去的鍵名username的記錄就在該數據庫中。雙擊db0,在右邊區(qū)域“Redisdataexplorer”選項頁中即可看到username條目,點擊記錄條目,在下方打開的選項頁中就可以看到該記錄的鍵名(Key)和值(Value),與命令行存入的一模一樣,如圖5.33所示。Redis開發(fā)入門與應用3.模板操作Redis實例SpringBoot提供了StringRedisTemplate和RedisTemplate兩個模板來進行Redis數據操作,其中,StringRedisTemplate只針對鍵值都是字符串類型的數據,而RedisTemplate則可以操作對象類型的數據。這兩個模板提供的主要數據訪問方法如表5.1所示。方法功能opsForValue()操作只有簡單屬性的數據opsForHash()操作含有散列的數據opsForList()操作含有列表類型的數據opsForSet()操作含有集合類型的數據opsForZSet()操作含有有序集合的數據Redis開發(fā)入門與應用【實例5.5】通過模板方式操作Redis,向其中存入商品信息。本例程序先用MyBatis從MySQL數據庫中讀取商品信息,然后再通過StringRedisTemplate/RedisTemplate模板操作將讀取的商品信息轉存入Redis內存數據庫。(1)創(chuàng)建項目創(chuàng)建SpringBoot項目,項目名為RedisTemplate,在出現(xiàn)的向導界面“Dependencies”列表中勾選SpringBoot基本框架(“Web”→“SpringWeb”)、Lombok模型簡化組件(“DeveloperTools”→“Lombok”)、MyBatis框架(“SQL”→“MyBatisFramework”)以及MySQL的驅動(“SQL”→“MySQLDriver”)、Redis框架(“NoSQL”→“SpringDataRedis(Access+Driver)”)。(2)配置連接在項目perties文件中配置MySQL數據庫連接,配置內容與【實例5.1】的相同,略。Redis開發(fā)入門與應用(3)設計模型由于存儲到Redis的數據必須序列化,所以本例的商品模型類也要實現(xiàn)Java的序列化接口Serializable。在項目工程目錄樹的com.example.redistemplate節(jié)點下創(chuàng)建model包,其中創(chuàng)建Commodity.java,代碼為:packagecom.example.redistemplate.model;

importlombok.Data;

importjava.io.Serializable;

@DatapublicclassCommodityimplementsSerializable{ //必須序列化 privateintpid; //商品號 privateStringtcode; //商品分類編碼 privateStringscode; //商家編碼 privateStringpname; //商品名稱 privatefloatpprice; //商品價格 privateintstocks; //商品庫存}Redis開發(fā)入門與應用(4)定義數據接口在項目工程目錄樹的com.example.redistemplate節(jié)點下創(chuàng)建mapper包,其中創(chuàng)建接口ComMapper.java,定義為:packagecom.example.redistemplate.mapper;

importcom.example.redistemplate.model.Commodity;importorg.apache.ibatis.annotations.*;

@MapperpublicinterfaceComMapper{ @Select("SELECT*FROMcommodityWHEREPid=#{pid}") CommodityqueryByPid(@Param("pid")intpid);}Redis開發(fā)入門與應用(5)開發(fā)操作Redis的業(yè)務層通常開發(fā)中,讀取關系數據庫(如MySQL)的操作在持久層進行,而操作NoSQL的工作卻是由業(yè)務層的服務實體來承擔的,這樣做使代碼分工明確,各模塊職能清晰。①定義業(yè)務接口在項目工程目錄樹的com.example.redistemplate節(jié)點下創(chuàng)建service包,其下定義名為ComService的接口,代碼為:packagecom.example.redistemplate.service;

importcom.example.redistemplate.model.Commodity;

publicinterfaceComService{ publicStringgetPNameFromRedis(intpid); //從Redis獲取商品名稱 publicCommoditygetComFromRedis(intpid); //從Redis獲取商品記錄對象}②開發(fā)服務實體在service包下創(chuàng)建業(yè)務接口的實現(xiàn)類ComServiceImpl,代碼顯示。Redis開發(fā)入門與應用(6)編寫控制器在項目工程目錄樹的com.example.redistemplate節(jié)點下創(chuàng)建controller包,其中創(chuàng)建控制器類ComController,代碼顯示。(7)自定義配置RedisTemplateSpringBoot默認配置的RedisTemplate使用JdkSerializationRedisSerializer來序列化數據,由于JdkSerializationRedisSerializer是以二進制形式存儲數據的,這對我們通過RedisClient可視化查看很不方便,故需要對RedisTemplate進行配置,自定義其序列化器。在項目主啟動文件RedisTemplateApplication.java中進行配置,添加代碼(加黑)如下。Redis開發(fā)入門與應用(8)運行啟動項目,打開瀏覽器。①從Redis獲取商品名稱地址欄輸入http://localhost:8080/com/getpname?pid=1回車,獲取商品號1的記錄的商品名稱,顯示如圖5.34所示。Redis開發(fā)入門與應用此時,打開Redis客戶端,可看到其中存儲的鍵名為pname的商品名稱字符串,與前端顯示是一致的,如圖5.35所示。Redis開發(fā)入門與應用②從Redis獲取商品記錄對象地址欄輸入http://localhost:8080/com/getcom?pid=1回車,獲取商品號1的記錄對象,顯示如圖5.36所示。Redis開發(fā)入門與應用此時,打開Redis客戶端,可看到其中存儲的鍵名為1的商品記錄對象,其各字段內容與前端顯示也是一致的,如圖5.37所示。Redis開發(fā)入門與應用4.緩存注解操作Redis實例模板雖然能夠有效地操作Redis,但仍然需要用戶自己編程調用方法來實現(xiàn)操作,并不能完全自動化。為了進一步簡化Redis的使用,SpringBoot提供了緩存注解,只要將注解加在需要操作Redis的方法上,在程序執(zhí)行方法代碼的時候就會自動進行Redis的存取而無須用戶干預,這種方式在實際中用得更加普遍?!緦嵗?.6】用緩存注解方式操作Redis,實現(xiàn)內存中商品信息的增刪改查。(1)創(chuàng)建項目創(chuàng)建SpringBoot項目,項目名為RedisCache,在出現(xiàn)的向導界面“Dependencies”列表中勾選SpringBoot基本框架(“Web”→“SpringWeb”)、Lombok模型簡化組件(“DeveloperTools”→“Lombok”)、MyBatis框架(“SQL”→“MyBatisFramework”)以及MySQL的驅動(“SQL”→“MySQLDriver”)、Redis框架(“NoSQL”→“SpringDataRedis(Access+Driver)”)。Redis開發(fā)入門與應用(2)配置連接在項目perties文件中配置MySQL數據庫連接,內容如下:spring.datasource.url=jdbc:mysql://:3306/netshop?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=truespring.datasource.username=rootspring.datasource.password=123456spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver.example.rediscache=debug(3)設計模型本例也只用到了商品模型類Commodity.java,與【實例5.5】的完全一樣,也需要實現(xiàn)Java序列化Serializable接口,可以直接復用【實例5.5】的模型類,將其復制到項目的com.example.rediscache.model包下,改一下包路徑即可,代碼略。Redis開發(fā)入門與應用(4)定義數據接口在項目工程目錄樹的com.example.rediscache節(jié)點下創(chuàng)建mapper包,其中創(chuàng)建接口ComMapper.java,定義為:packagecom.example.rediscache.mapper;

importcom.example.rediscache.model.Commodity;importorg.apache.ibatis.annotations.*;

@MapperpublicinterfaceComMapper{ @Select("SELECT*FROMcommodityWHEREPid=#{pid}") CommodityqueryByPid(@Param("pid")intpid);

@Insert("INSERTINTOcommodity(Pid,TCode,SCode,Pname,PPrice,Stocks)VALUES(#{pid},#{tcode},#{scode},#{pname},#{pprice},#{stocks})") intinsertOne(Commoditycommodity);

@Update("UPDATEcommoditySETStocks=#{stocks}WHEREPid=#{pid}") intupdateByPid(@Param("pid")intpid,@Param("stocks")intstocks);

@Delete("DELETEFROMcommodityWHEREPid=#{pid}") intdeleteByPid(intpid);}Redis開發(fā)入門與應用(5)開發(fā)業(yè)務層①定義業(yè)務接口在項目工程目錄樹的com.example.rediscache節(jié)點下創(chuàng)建service包,其下定義名為ComService的接口,代碼為:packagecom.example.rediscache.service;

importcom.example.rediscache.model.Commodity;

publicinterfaceComService{ publicCommoditygetComFromRedis(intpid); //從Redis獲取商品記錄

publicintaddComToRedis(intpid,Commoditycommodity); //往Redis添加商品記錄

publicintsetComToRedis(intpid,intstocks); //更新Redis中的商品庫存

publicintdelComFromRedis(intpid); //從Redis刪除商品記錄}②開發(fā)服務實體在service包下創(chuàng)建業(yè)務接口的實現(xiàn)類ComServiceImpl,代碼顯示。Redis開發(fā)入門與應用說明:(a)@Cacheable(value="commoditys",key="#pid"):注解@Cacheable標注在getComFromRedis方法上,表示當該方法中的代碼執(zhí)行從關系數據庫查詢(這里是通過調用MyBatis接口的queryByPid方法)數據操作的同時,就自動將查到的結果存一份進Redis,下一次再執(zhí)行該方法時就直接從Redis得到數據,不再訪問關系數據庫。注解的key屬性指定查詢所依據的鍵為#pid(商品號)。(b)@CachePut(value="commoditys",key="#pid"):注解@CachePut通常標注在對關系數據庫進行插入或更新操作的方法上,方法中的程序代碼每操作一次關系數據庫,SpringBoot都會自動將操作的結果(插入的記錄、更新后的記錄)存入一份進Redis或替換掉Redis中原有的舊數據,使得Redis內容始終保持與關系數據庫中的最新值同步一致。(c)@CachePut(value="commoditys",condition="#result!='null'",key="#pid"):condition屬性指定當結果返回為空(比如關系數據庫中并不存在要更新的記錄)時,不操作Redis。(d)@CacheEvict(value="commoditys",key="#pid"):注解@CacheEvict標注的方法在對關系數據庫執(zhí)行了刪除操作之后,SpringBoot也會同步刪除Redis中指定鍵(#pid)的記錄。Redis開發(fā)入門與應用(6)編寫控制器在項目工程目錄樹的com.example.rediscache節(jié)點下創(chuàng)建controller包,其中創(chuàng)建控制器類ComController,代碼顯示。(7)啟用緩存注解最后,還要在項目主啟動文件RedisCacheApplication.java中用@EnableCaching來啟用緩存注解,使之生效,如下:packagecom.example.rediscache;

importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.cache.annotation.EnableCaching;

@EnableCaching //啟用緩存注解@SpringBootApplicationpublicclassRedisCacheApplication{ publicstaticvoidmain(String[]args){ SpringApplication.run(RedisCacheApplication.class,args); }}Redis開發(fā)入門與應用(8)運行①獲取商品記錄(未用緩存)為了對比說明,先來測試一下未使用緩存時的情形。注釋掉程序中的“@Cacheable(value="commoditys",key="#pid")”,如圖5.38所示,然后啟動項目。打開瀏覽器,地址欄輸入http://localhost:8080/com/getcom?pid=1002回車,獲取商品號1002的記錄對象,顯示如圖5.39所示。Redis開發(fā)入門與應用在上圖5.39的瀏覽器頁面上右擊鼠標,點“重新加載”,向后臺再請求獲取一次該商品的記錄對象。回到IDEA環(huán)境,從底部子窗口的輸出中可以看到,系統(tǒng)先后執(zhí)行了兩次SELECT語句查詢MySQL的商品表,而并未使用Redis緩存。Redis開發(fā)入門與應用②獲取商品記錄(啟用緩存)將代碼“//@Cacheable(value="commoditys",key="#pid")”前的注釋去掉,重新啟動項目,打開瀏覽器。地址欄輸入http://localhost:8080/com/getcom?pid=1002回車,看到頁面顯示記錄對象后,再重新加載一次頁面。此時打開Redis客戶端,可看到其中db0數據庫節(jié)點下多了個“commoditys”子節(jié)點,點開后就能看到Redis中緩存的1002號商品記錄,如圖5.41所示。Redis開發(fā)入門與應用再回到IDEA環(huán)境,從底部子窗口輸出中看到整個過程中系統(tǒng)僅執(zhí)行了一次SELECT語句查詢MySQL商品表,如圖5.42所示。Redis開發(fā)入門與應用③刪除商品記錄(同步清除緩存)地址欄輸入http://localhost:8

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論