springboot~Mongodb的集成與使(shi)用
說說springboot與大叔lind.ddd的淵源
Mongodb在Lind.DDD中被二(er)次封裝過(guo)(大叔的(de).net和.net core),將(jiang)它當成是一(yi)(yi)種倉儲(chu)來(lai)使用,對于開發人(ren)員來(lai)說只公開curd幾個標準的(de)接口(kou)(kou)即可(ke),而在springboot框架(jia)里,它與(yu)大叔lind有(you)些類似(si)之(zhi)處,同樣是被二(er)次封裝了,開發人(ren)員只需(xu)要關注自己的(de)業務(wu)即可(ke),而標準的(de)curd操作完成由springboot幫助我們(men)來(lai)實現,一(yi)(yi)般地,我們(men)會設計一(yi)(yi)個與(yu)實體對象的(de)接口(kou)(kou)倉儲(chu),讓它去繼承mongo的(de)標準接口(kou)(kou),然(ran)后(hou)在springboot的(de)依賴注入框架(jia)里把標準的(de)實現注入進來(lai),這一(yi)(yi)切都是框架(jia)幫助我們(men)實現的(de)!
在項目中實現mongodb
如果(guo)項(xiang)目需要使用mongodb去(qu)持久化數據,一般可以(yi)經(jing)過(guo)下面幾個(ge)步驟來實現:
1 添加(jia)包依賴build.gradle
compile('org.springframework.boot:spring-boot-starter-data-mongodb')
如果有單(dan)元(yuan)測試(shi)項目(mu),可以使用內嵌的mongodb,這樣它不需要與外部資源進行通信,工作原理:從遠(yuan)程下(xia)載mongodb包,啟動它,測試(shi)完(wan)成(cheng)(cheng)后(hou)刪除生成(cheng)(cheng)的集合
testCompile('de.flapdoodle.embed:de.flapdoodle.embed.mongo:2.0.3')
2 添(tian)加(jia)默認的配置(zhi)項application.yml
spring: data: mongodb: uri: mongodb://192.168.99.100:27017/Test password: guest username: guest
3 添加mongodb集合對應的實體類(lei)
/** * 地址. */ @Data @NoArgsConstructor @AllArgsConstructor public class Address { /** * 編(bian)號. */ @Id private String id; /** * 省. */ private String province; /** * 市. */ private String city; /** * 區. */ private String district; /** * 狀態. */ private Status status; }
4 添(tian)加實(shi)體(ti)所對應(ying)的(de)倉(cang)(cang)(cang)庫類(lei),它(ta)需要(yao)(yao)繼承extends標(biao)準的(de)mongodb倉(cang)(cang)(cang)儲,同(tong)時(shi)Mongodb倉(cang)(cang)(cang)儲支持自動定約定的(de)方法(fa),開發人員可以通過@Query注釋來(lai)確定返(fan)回的(de)字段列表(biao),這對于大數據文檔是(shi)很必要(yao)(yao)的(de),如(ru)果默認的(de)接口不能滿足我們的(de)要(yao)(yao)求,我們需要(yao)(yao)定義個性
化的接口,并去實現它,下面的例子中,我們的AddressExtRepository就是一個個性化接口,我們對外的接口AddressRepository 需要繼承它,注意(yi),大叔認(ren)為這樣破獲了面向對(dui)象的開(kai)閉原(yuan)則,元(yuan)芳,你(ni)怎(zen)么看!
/** * 對外提供的地址(zhi)倉儲接(jie)口,繼(ji)承(cheng)所(suo)有(you)地址(zhi)相關(guan)的接(jie)口. */ public interface AddressRepository extends
AddressExtRepository,
MongoRepository<Address, String> { /** * 根(gen)據省,拿地址列(lie)表. * * @param province * @return */ @Query(fields = "{'province': 0}") List<Address> findAddressesByProvince(String province); /** * 根據省(sheng)和省(sheng),拿地址列表. * * @param province * @param city * @return */ @Query()//fields表示(shi)包含的字(zi)段(duan) List<Address> findAddressesByProvinceAndCityAndDistrict(String province, String city, String district); }
個性(xing)化(hua)倉儲實現,使用MongoTemplate對象與mongodb數(shu)據庫進行交互!
/** * 特殊(shu)規(gui)則的倉儲實(shi)現. */ public class AddressExtRepositoryImpl implements AddressExtRepository { @Autowired MongoTemplate mongoTemplate; @Override public Address findByProvinceAndCity(String province, String city) { Query query = new Query(Criteria.where("province").is(province).and("city").is(city)); return mongoTemplate.findOne(query, Address.class, "address"); } }
5 controller中直接通過@Autowired注解(jie)來訪問倉儲和業務對象即可
@RestController public class MongoController { // 倉儲. @Autowired private AddressRepository repository; // 用(yong)戶業(ye)務. @Autowired private UserService userService; /** * 得到地(di)址(zhi)列(lie)表. * * @return */ @RequestMapping("/address/{province}") public Address getAddress(@PathVariable("province") String province) { System.out.println("1,province=" + province); return userService.getAddress(province); } }
感謝各位的閱讀!
對知識的(de)探索(suo)我們還(huan)在繼(ji)續!