<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      補(bǔ)習(xí)系列(17)-springboot mongodb 內(nèi)嵌數(shù)據(jù)庫(kù)

      簡(jiǎn)介

      前面的文章中,我們介紹了如何在SpringBoot 中使用MongoDB的一些常用技巧。
      那么,與使用其他數(shù)據(jù)庫(kù)如 MySQL 一樣,我們應(yīng)該怎么來(lái)做MongoDB的單元測(cè)試呢?

      使用內(nèi)嵌數(shù)據(jù)庫(kù)的好處是不需要依賴于一個(gè)外部環(huán)境,如果每一次跑單元測(cè)試都需要依賴一個(gè)穩(wěn)定的外部環(huán)境,那么這樣的測(cè)試是極不穩(wěn)定的。
      為了更歡快的使用MongoDB,這里提供兩種使用內(nèi)嵌數(shù)據(jù)庫(kù)做單元測(cè)試的方式。

      一、使用 flapdoodle.embed.mongo

      開(kāi)源地址
      該組件的大致原理是,在當(dāng)前環(huán)境中自動(dòng)下載MongoDB并拉起進(jìn)程,測(cè)試后再做關(guān)閉。
      先演示一遍如何使用:

      A. 引入依賴

              <dependency>
                  <groupId>de.flapdoodle.embed</groupId>
                  <artifactId>de.flapdoodle.embed.mongo</artifactId>
                  <version>1.50.5</version>
                  <scope>test</scope>
              </dependency>
      

      B. 準(zhǔn)備測(cè)試類(lèi)

      編寫(xiě)一個(gè)基礎(chǔ)類(lèi):

      @RunWith(SpringRunner.class)
      @SpringBootTest(classes = DemoBoot.class)
      @ActiveProfiles("test")
      public class BaseEmbededMongoTest {
      
          private static final Logger logger = LoggerFactory.getLogger(BaseEmbededMongoTest.class);
          protected static final MongodStarter starter = MongodStarter.getDefaultInstance();
          protected static MongodExecutable _mongodExe;
          protected static MongodProcess _mongod;
      
          // 確保與配置一致
          protected static final String host = "127.0.0.1";
          protected static final int port = 27027;
      
          @BeforeClass
          public static void setUp() throws Exception {
              _mongodExe = starter.prepare(new MongodConfigBuilder().version(Version.Main.PRODUCTION)
                      .net(new Net(host, port, Network.localhostIsIPv6())).build());
              _mongod = _mongodExe.start();
      
              logger.info("mongod started on {}:{}", host, port);
          }
      
          @AfterClass
          public static void tearDown() throws Exception {
              _mongod.stop();
              _mongodExe.stop();
          }
      }
      

      BaseEmbededMongoTest 實(shí)現(xiàn)了:

      • 測(cè)試啟動(dòng)前啟動(dòng)MongoDB進(jìn)程;
      • 測(cè)試完成后關(guān)閉MongoDB進(jìn)程;

      讓業(yè)務(wù)測(cè)試類(lèi)繼承于基礎(chǔ)類(lèi):

      public class BookServiceTest extends BaseEmbededMongoTest{
      
          @Autowired
          private BookService bookService;
      
          @Autowired
          private BookRepository bookRepository;
         ...
      

      C. 完善配置

      為了避免沖突,需要關(guān)閉EmbeddedMongoAutoConfiguration

      @SpringBootApplication
      @EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class})
      public class BootSampleMongo {
      ...
      

      最后一步,為了讓業(yè)務(wù)代碼能連接到自啟動(dòng)的MongoDB,需要做對(duì)應(yīng)的配置:

      在src/test/resources目錄中編輯 application-test.properties

      spring.data.mongodb.host=localhost
      spring.data.mongodb.port=27027
      spring.data.mongodb.database=test
      

      D. 啟動(dòng)測(cè)試

      執(zhí)行業(yè)務(wù)測(cè)試類(lèi),可以看到一系列輸出:

      //下載
      Download PRODUCTION:Windows:B64 START
      Download PRODUCTION:Windows:B64 DownloadSize: 147911698
      Download PRODUCTION:Windows:B64 0% 1% 2% 3% 4% 5% 6% 7% 8% 9% 10% 11%
      ...
      //啟動(dòng)繼承
      [mongod output] 2019-03-02T15:43:01.948+0800 I CONTROL  [initandlisten] db version v3.2.1
      [mongod output] 2019-03-02T15:43:01.948+0800 I CONTROL  [initandlisten] git version: a14d55980c2cdc565d4704a7e3ad37e4e535c1b2
      [mongod output] 2019-03-02T15:43:01.948+0800 I CONTROL  [initandlisten] allocator: tcmalloc
      [mongod output] 2019-03-02T15:43:01.948+0800 I CONTROL  [initandlisten] modules: none
      [mongod output] 2019-03-02T15:43:01.948+0800 I CONTROL  [initandlisten] build environment:
      [mongod output] 2019-03-02T15:43:01.948+0800 I CONTROL  [initandlisten]     distmod: 2008plus
      [mongod output] 2019-03-02T15:43:01.948+0800 I CONTROL  [initandlisten]     distarch: x86_64
      [mongod output] 2019-03-02T15:43:01.948+0800 I CONTROL  [initandlisten]     target_arch: x86_64
      ...
      [mongod output] 2019-03-02T15:43:02.070+0800 I NETWORK  [initandlisten] waiting for connections on port 27027
      //單元測(cè)試
      ...
      //關(guān)閉進(jìn)程
      [mongod output] 2019-03-02T15:43:20.838+0800 I COMMAND  [conn3] terminating, shutdown command received
      [mongod output] 2019-03-02T15:43:20.838+0800 I FTDC     [conn3] Shutting down full-time diagnostic data capture
      [mongod output] 2019-03-02T15:43:20.846+0800 I CONTROL  [conn3] now exiting
      [mongod output] 2019-03-02T15:43:20.846+0800 I NETWORK  [conn3] shutdown: going to close listening sockets...
      [mongod output] 2019-03-02T15:43:20.846+0800 I NETWORK  [conn3] closing listening socket: 456
      [mongod output] 2019-03-02T15:43:20.846+0800 I NETWORK  [conn3] shutdown: going to flush diaglog...
      [mongod output] 2019-03-02T15:43:20.846+0800 I NETWORK  [conn3] shutdown: going to close sockets...
      [mongod output] 2019-03-02T15:43:20.911+0800 I NETWORK  [conn1] end connection 127.0.0.1:52319 (2 connections now open)
      [mongod output] 2019-03-02T15:43:20.911+0800 I STORAGE  [conn3] WiredTigerKVEngine shutting down
      [mongod output] 2019-03-02T15:43:20.916+0800 I NETWORK  [conn2] end connection 127.0.0.1:52320 (1 connection now open)
      [mongod output] 2019-03-02T15:43:20.943+0800 I STORAGE  [conn3] shutdown: removing fs lock...
      [mongod output] 2019-03-02T15:43:20.943+0800 I CONTROL  [conn3] dbexit:  rc: 0
      

      注:首次使用該組件時(shí)需要下載安裝包,過(guò)程比較緩慢需要些耐心..

      細(xì)節(jié)

      細(xì)心的同學(xué)可能注意到了,我們?yōu)槭裁匆貏e規(guī)避EmbeddedMongoAutoConfiguration這個(gè)類(lèi)呢?

      在SpringBoot 官方文檔中提到了 EmbeddedMongoAutoConfiguration,其作用主要是:

      • 自動(dòng)檢測(cè) flapdoodle.embed.mongo組件是否被引入;
      • 如果當(dāng)前的運(yùn)行環(huán)境中能找到組件,則會(huì)自動(dòng)啟動(dòng)組件,并在程序退出時(shí)做銷(xiāo)毀

      我們簡(jiǎn)單看一下其實(shí)現(xiàn):

      @Configuration
      @EnableConfigurationProperties({ MongoProperties.class, EmbeddedMongoProperties.class })
      @AutoConfigureBefore(MongoAutoConfiguration.class)
      @ConditionalOnClass({ Mongo.class, MongodStarter.class })
      public class EmbeddedMongoAutoConfiguration {
          private final MongoProperties properties;
          private final EmbeddedMongoProperties embeddedProperties;
      
          @Bean(initMethod = "start", destroyMethod = "stop")
          @ConditionalOnMissingBean
          public MongodExecutable embeddedMongoServer(IMongodConfig mongodConfig)
                  throws IOException {
              Integer configuredPort = this.properties.getPort();
              if (configuredPort == null || configuredPort == 0) {
                  setEmbeddedPort(mongodConfig.net().getPort());
              }
              MongodStarter mongodStarter = getMongodStarter(this.runtimeConfig);
              return mongodStarter.prepare(mongodConfig);
          }
      
      

      不難猜到,該配置類(lèi)已經(jīng)完成了我們?cè)趩卧獪y(cè)試中所需要的一切事情,那為什么還需要BaseEmbededMongoTest?
      答案在于,我們可能會(huì)對(duì)MongoDB的連接池做許多定制,如下面的代碼:

      @Configuration
      public void MongoConfig{
          @Bean
          public MongoDbFactory mongoDbFactory(){
              ...
           }
      }
      

      類(lèi)似這樣的定制,會(huì)讓MongoAutoConfiguration失效。即SpringDataMongo 的初始化會(huì)先于Embeded實(shí)例的啟動(dòng),導(dǎo)致失敗。
      通過(guò)自定義的實(shí)現(xiàn)則可以規(guī)避該問(wèn)題,當(dāng)然如果通過(guò)Profile設(shè)定也可以進(jìn)行規(guī)避。

      二、使用Fongo

      開(kāi)源地址
      Fongo 是由 Fousquare 開(kāi)發(fā)團(tuán)隊(duì)開(kāi)源的一款真正的內(nèi)存式MongoDB,非常適用于輕量級(jí)的單元測(cè)試。
      這個(gè)名字.. 不錯(cuò)哈

      Fongo 支持對(duì)Java-Driver的各種CRUD指令進(jìn)行解析,并模擬數(shù)據(jù)在內(nèi)存中的存儲(chǔ)管理操作,可以認(rèn)為其提供了一層JavaDriver的代理。
      同時(shí),該框架是線程安全的,所有的集合讀寫(xiě)操作都能得到同步保護(hù)

      接下來(lái)是如何使用:

      A. 引入框架

      <!-- fongo face mongo -->
      <dependency>
       <groupId>com.github.fakemongo</groupId>
       <artifactId>fongo</artifactId>
       <version>2.1.0</version>
       <scope>test</scope>
       <exclusions>
         <exclusion>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-core</artifactId>
         </exclusion>
         <exclusion>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-databind</artifactId>
         </exclusion>
       </exclusions>
      </dependency>
      

      注:fongo依賴于jackson,可能與SpringBoot項(xiàng)目沖突,這里顯示將其剔除。

      B. 準(zhǔn)備測(cè)試類(lèi)

      編寫(xiě)一個(gè)基于Fongo的類(lèi):

      @ActiveProfiles("test")
      @RunWith(SpringRunner.class)
      @SpringBootTest(classes = BootSampleMongo.class)
      @Import(TestConfig.class)
      public class BaseFongoTest {
      
      }
      

      這里使用@Import導(dǎo)入了一個(gè)TestConfig,用于初始化Fongo實(shí)例,如下:

      @TestConfiguration
      @Profile("test")
      public class TestConfig extends AbstractMongoConfiguration {
      
          @Autowired
          private Environment env;
      
          @Override
          protected String getDatabaseName() {
              return env.getProperty("spring.data.mongodb.database", "test");
          }
      
          @Override
          public Mongo mongo() throws Exception {
              return new Fongo(getDatabaseName()).getMongo();
          }
          
      }
      

      這樣,通過(guò)繼承于AbstractMongoConfiguration,可以省去配置MongoDbFactory之類(lèi)的工作。
      需要注意的是,如果業(yè)務(wù)代碼做了一些連接池的定制,如MongoDbFactory/MongoTemplate的定義,則需要通過(guò)Profile進(jìn)行隔離,避免在測(cè)試過(guò)程中出錯(cuò):

      @Configuration
      @Profile("prod")
      public class ProdMongoConfig {
      ...
      

      C.業(yè)務(wù)測(cè)試

      準(zhǔn)備好上面的工作后,則可以用到業(yè)務(wù)測(cè)試代碼上:

      public class BookServiceTest extends BaseFongoTest{
      
          @Autowired
          private BookService bookService;
      
          @Autowired
          private BookRepository bookRepository;
      

      至此,我們已經(jīng)完成了Fongo 的使用。

      碼云同步代碼

      參考文檔

      springboot-with-mongo-embed
      flapdoodle-embed-mongo-github
      another-embededmongo-fongo

      小結(jié)

      隨著MongoDB 在Web開(kāi)發(fā)中的應(yīng)用越來(lái)越廣,許多配套的框架及工具也在逐步完善。
      本文介紹了兩種在SpringBoot 框架上使用內(nèi)嵌MongoDB的方式,從簡(jiǎn)易性來(lái)看,個(gè)人更推薦Fongo的方案。
      由于Fongo 更接近于H2(一種內(nèi)存SQL數(shù)據(jù)庫(kù))的實(shí)現(xiàn),整個(gè)測(cè)試過(guò)程中不需要開(kāi)啟MongoDB進(jìn)程,也免去了遠(yuǎn)程下載軟件的煩惱。
      所有的操作均在內(nèi)存中完成,會(huì)令整個(gè)測(cè)試更加的高效,然而其僅有的缺點(diǎn)是無(wú)法支持一些原生的MongoDB管理命令(一般也不會(huì)用到)。
      當(dāng)然,讀者也可以根據(jù)自己的需求自行選擇。

      歡迎繼續(xù)關(guān)注"美碼師的補(bǔ)習(xí)系列-springboot篇" ,期待更多精彩內(nèi)容-

      posted @ 2019-03-02 18:43  美碼師  閱讀(2164)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 任你躁国产自任一区二区三区| 日本污视频在线观看| 99RE6在线视频精品免费下载| 福利一区二区1000| 视频一区二区三区四区五区 | 日韩国产成人精品视频| 国产免费无遮挡吸奶头视频| 亚洲成A人片在线观看无码不卡| 国产亚洲一区二区三不卡| 97欧美精品系列一区二区| 亚洲另类激情专区小说图片| 中日韩黄色基地一二三区| 大地资源高清免费观看| 欧美成人精品一级在线观看| 亚洲一区二区三区小蜜桃| xbox免费观看高清视频的软件 | 亚洲狠狠狠一区二区三区| 91热在线精品国产一区| 免费的特黄特色大片| 亚洲国产日韩一区三区| 国产精品日韩av在线播放| 精品中文人妻在线不卡| 国产一区二区亚洲精品| 日韩中文字幕有码av| 亚洲狠狠婷婷综合久久久久图片| 久久爱在线视频在线观看 | 久久久久亚洲av成人网址| 午夜福利片1000无码免费| 久久精品色妇熟妇丰满人| 最新精品国偷自产在线 | mm1313亚洲国产精品| 精品国产福利一区二区在线| 国产高清自产拍av在线| 精品人妻系列无码天堂| 日韩激情成人| 欧美videosdesexo吹潮| 高清在线一区二区三区视频| 国产无码高清视频不卡| 口爆少妇在线视频免费观看 | 人人超碰人摸人爱| 精品一区二区亚洲国产|