分類
發燒車訊

這款美系家轎省油又舒適,看看車主怎麼說

配置上沒能显示百公里油耗。輪胎用的是佳通195,真令人無語。升降窗戶按鈕並沒有夜光燈,晚上是要瞎摸的節奏。目前行駛里程:現在開了2000公里,油耗穩定在6。9L/100km,手動擋果然是省油利器。車主:123木頭人購買車型:2016款 15N 自動精英型裸車購買價:10。

前言

英朗在中國一直給人居家好車的形象,因此銷量一直都很不錯。無論是底盤的厚實感,還是隔音都給人不錯的印象,事實到底怎麼樣,下面請看幾位車主的說法。

車主:DJ

購買車型:2016款 15N 自動精英型

裸車購買價:9.89萬

最滿意的點:性價比很高,開起來也比較容易上手。車裡的空間和座椅的舒適性都很好,之前車子載着4個人出外旅遊,無論前後左右的空間,都很寬敞。這車操控性不錯,指向也精準,很容易開。

最不滿意的點:油耗略微偏高了一點,門板上的儲物空間並不充足。動力也不是很充足,上長坡時會顯得乏力。內飾設計缺乏亮點,別克的車很擅於營造豪華感,但英朗就是一個特例。

目前行駛里程:現在已經開了3000公里,首保之前的油耗在8.2L/100km,做完首保以後就逐漸下降到7.2L/100km,還是很令人滿意。

車主:梁先生

購買車型:2016款 15N 手動進取型

裸車購買價:8.99萬

最滿意的點:外觀相當漂亮,特別是那銳利的日間行車燈,簡直攝人心魄。這個價位帶有車身穩定系統也很厚道。油耗很令我滿意。底盤的濾震有厚實感,面對坑窪以及橋頭跳都可以很安穩地應對。

最不滿意的點:作為一個20年的老煙槍,這車只配點煙器而沒有煙缸,確實太不像話了。配置上沒能显示百公里油耗。輪胎用的是佳通195,真令人無語。升降窗戶按鈕並沒有夜光燈,晚上是要瞎摸的節奏。

目前行駛里程:現在開了2000公里,油耗穩定在6.9L/100km,手動擋果然是省油利器。

車主:123木頭人

購買車型:2016款 15N 自動精英型

裸車購買價:10.19萬

最滿意的點:外觀時尚靚麗,紅色車身看起來更顯高貴。操控算是很優良,轉向基本指哪打哪。座椅的材質較為柔軟,後排座椅可以放倒,而前排也可以放得很低。性價比夠高,許多該有配置都有了。

最不滿意的點:動力很一般,油門響應也不夠快,緊急超車時動力並不能很好跟上。白色車身不耐臟,而且髒了以後,清潔麻煩。內飾設計比較普通,沒有別克應有的水準,感覺略微有點失望。

目前行駛里程:到現在為止,已經開了8700公里,百公里綜合油耗為7.5L左右,上到高速可以下降到6.5左右,很令我滿意。

編者總結:

從以上三位車主的說法中,可以看出英朗確實是一款居家好車,省心舒適。不過,如果你想要動力與很好的操控,就不該對它有所眷戀了。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※教你寫出一流的銷售文案?

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※推薦台中搬家公司優質服務,可到府估價

分類
發燒車訊

聚焦共享車新政 海馬汽車與易鑫金融達成20000台戰略合作

福美來品牌新變 樹立共享車市場典範自九月底以來,海馬汽車開啟聚焦福美來品牌的全新戰略,將福美來從產品品牌升級為品類品牌,繼福美來轎車、福美來七座版后,再將福美來專車版納入福美來品牌體系,並與福美來七座版一道作為福美來家轎品牌下的首發明星組合進軍汽車租賃市場以及互聯網+汽車金融時代的家庭用車市場,則是福美來品牌新變后的一大重要營銷舉措。

月初,隨着《網絡預約出租汽車經營服務管理暫行辦法》的正式實施,各地的網約車細則也在陸續出台,共享車市場面臨整肅和洗牌,不少車型被網約車准入指標的高門檻拒之門外。不過,隨着汽車共享經濟的異軍突起,共享車市場發展趨勢不可逆轉。新政策的出台對廣大車企而言既是挑戰,更是機遇。抓住機會,創新變革,則有望分得共享經濟紅利。而福美來旗下的兩大車型–福美來七座版和福美來專車版便是新政施行之初的首批獲益者。

11月25日,海馬汽車與易鑫金融共享車合作暨福美來系列20000台訂單簽約儀式在海馬汽車大本營–海南海口成功舉行,福美來旗下兩大車型福美來七座版和福美來專車版分別憑藉七座大空間、愉悅尊貴等產品力優勢,以及穩定可靠的產品品質獲得易鑫金融的青睞。雙方達成20000輛車的供車合作協議,共同發力共享車市場。

易鑫金融是中國領先的互聯網汽車金融交易平台,易鑫金融旗下的易鑫車貸App及daikuan.com為廣大消費者提供新車貸款、二手車貸款、車主貸款,汽車租賃以及汽車保險等全方位的汽車金融服務。目前,累計服務用戶超1000萬人,日均線上個人車貸需求金額20億元,資產規模近200億元

福美來兩大旗艦車型 全面滿足共享車市場需求

作為2016年9月上市的多座版家用轎車,福美來七座版的超大空間、舒適安全等優點廣受市場認可。福美來七座版在整車尺寸上極具優勢,同時內部座椅角度也可進行靈活調整,實現了60種座椅組合方式,真正將空間的靈活多變性發揮到了極致,可最大限度滿足多人集體出行、商務接待、載物等需求。此外,福美來七座版在安全上也下足了功夫。

除了諸多厚道的主、被動安全配備,海馬自身對車輛實地安全測試和安全舒適駕乘做到嚴格把關,真正讓消費者感到安心和舒心,並且以互聯網思維為原點,結合家庭用戶兼顧商務用戶的使用需求,配備了HM-Link極智車載互聯繫統、高效T動力、及多項科技配置,使得福美來七座版給消費者帶來超越同級的舒適尊享駕乘感。

憑藉七座大空間的核心優勢、結合安靜舒適、強力安全和智能科技等強悍產品力,福美來七座版為多人出行提供更具溫情和性價比的解決方案,全面滿足了商務與多口之家的出行所需,從眾多車型中脫穎而出,成為了汽車租賃市場的先行者。

七座大空間,福美來七座版完美承載多人出行

相對於福美來七座版的適合多人出行優勢,福美來專車版在整車尊享駕控方面同樣惹人注目。據悉,福美來專車版是在海馬M8的基礎上針對共享車市場進行升級的定製版本,是福美來品牌升級后的又一重磅舉措。

兼具舒適與安全,福美來專車版精準駕控愉悅尊享

福美來專車版是海馬汽車在整車造車技術上的最高體現,在自主中高級車市場中,以整體造車解決方案獨樹一幟,轎跑底盤配合渦輪增壓發動機營造出強悍T動力,并力求通過精準駕控、全面安全、愉悅尊享等智能技術的應用為消費者提供了尊享高檔的駕乘享受,是一款充分洞察消費者用車需求后傾力打造的中高級座駕,非常適用於專車市場以及互聯網+汽車金融時代的家庭用車市場。

福美來品牌新變 樹立共享車市場典範

自九月底以來,海馬汽車開啟聚焦福美來品牌的全新戰略,將福美來從產品品牌升級為品類品牌,繼福美來轎車、福美來七座版后,再將福美來專車版納入福美來品牌體系,並與福美來七座版一道作為福美來家轎品牌下的首發明星組合進軍汽車租賃市場以及互聯網+汽車金融時代的家庭用車市場,則是福美來品牌新變后的一大重要營銷舉措。

海馬汽車集團股份有限公司執行董事、一汽海馬汽車有限公司總經理盧國綱說道:“借力此次合作,福美來品牌正式開啟共享車模式,一方面希望可以幫助有用車需求的用戶提供更加靈活方便、更高性價比、更豐富的車型選擇;幫助用戶避免不必要的消費,以租賃代替購買,養成更加共享和環保的出行方式,另一方面,希望可以解決大城市公共交通無法消化的出行需求。”福美來20000輛車進軍共享車市場,從租賃車和專車兩方面入手,在滿足廣大用戶高端出行需求的同時,也以強力安全、安靜舒適為駕乘者提供尊享優越的出行體驗,使用戶以更低費用獲取更具性價比的超值服務。

共享車經濟的發展,對汽車行業而言既是挑戰也是機遇。此次海馬與易鑫金融的聯袂合作,不僅是一汽海馬以市場為導向的积極應對,更是其在“互聯網+共享車+汽車營銷+移動出行”方面做出的前瞻布局。我們有理由相信,海馬攜手易鑫金融飲得共享車市場頭啖湯的同時,也必將成為汽車業和金融資本開展互聯網營銷創新的理想範本。

海馬汽車概況

海馬汽車集團股份有限公司(簡稱海馬汽車集團)位於海南省海口市金盤工業區金盤路12-8號,註冊資金16.5億元,總資產150億元,在深交所掛牌上市,股票代碼為000572,以汽車產業為主業,致力於中國民族汽車工業的發展。

海馬汽車集團旗下有海馬轎車有限公司、海馬商務汽車有限公司、一汽海馬汽車有限公司、上海海馬研發有限公司、海馬財務有限公司、金盤實業有限公司等。

二十餘年來,海馬汽車集團貼近中國汽車市場,秉承“開放合作、學習創新、自主多贏”的發展理念,堅持“先做精、后做強、再做穩、不爭大”的經營理念,建成海口、鄭州和上海三個產業基地,產品覆蓋麵包車、轎車、MpV、SUV和新能源汽車五大領域,直屬員工1萬多人,關聯企業員工3萬多人,年產值100多億元,累計納稅150多億元。

海馬汽車集團規劃年產銷整車一百萬輛。

易鑫金融概況

易鑫金融是中國領先的互聯網汽車金融交易平台,由易車、騰訊、京東、百度等互聯網巨頭注資60億元。易鑫金融旗下的易鑫車貸App及daikuan.com為廣大消費者提供新車貸款、二手車貸款、車主貸款,汽車租賃以及汽車保險等全方位的汽車金融服務。在線提供230個品牌汽車、2300餘家銀行及金融機構的金融產品可供用戶選擇,線下擁有5000人購車顧問、3萬餘家合作經銷商,服務遍及全國300多個城市。截至目前,累計服務用戶超1000萬人,日均線上個人車貸需求金額20億元,資產規模近200億元。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

※別再煩惱如何寫文案,掌握八大原則!

※回頭車貨運收費標準

※教你寫出一流的銷售文案?

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

網頁設計最專業,超強功能平台可客製化

分類
發燒車訊

新創酷9.99萬起售 這麼超值是要砸場子的節奏?

很久很久以前小編美美並不是做編輯而是說書的今天小編美美就來說一個古老而又神秘的故事。

很久很久以前

小編美美並不是做編輯

而是

說書的

今天小編美美就來說一個古老

而又神秘的故事

本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※回頭車貨運收費標準

※推薦評價好的iphone維修中心

※超省錢租車方案

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

※推薦台中搬家公司優質服務,可到府估價

分類
發燒車訊

又大又漂亮SUV僅5.89萬?11月上市的這幾款性價比特高

4T渦輪增壓發動機,最大功率達到143馬力,匹配6速手自一體變速箱或6速手動變速箱。編者點評:新款創酷設計一下子變得年輕、運動。這樣的設計風格無疑對20多歲的朋友們更有吸引力。而且自動擋車型的起售價僅11。99萬,還採用了1。

在11月份,因為廣州車展的緣故,各大汽車廠商都在這個月里推出了今年最後一波重點新車!今天編者就和大家聊聊這個月上市的重點高性價比新SUV,要買SUV不妨多看看這些新車!

奇瑞汽車-瑞虎3x

指導價:5.89-8.09萬

奇瑞全新的小型SUV–瑞虎3x也在本月上市,5.89萬的起售價,讓很多粉絲都在後台跟我們聊過這款車。

其實瑞虎3x的車身長寬高為4200*1760*1570mm,軸距為2555mm。編者此前親身體驗過這款車的空間,它的乘坐空間夠用,基本上頭部、腿部空間都有富餘。而且後備廂的空間也不錯。

動力方面,其採用1.5L發動機最大功率106馬力,最大扭矩為135牛米。搭配4擋自動變速箱或5擋手動變速箱。

編者點評:

如果你想要買人生的第一輛車的話,瑞虎3x這一類的低價、年輕化的SUV車型可以說是比較合適的。它賣點在於不錯的外觀內飾設計、不錯的空間實用性,還有較高的性價比。另外較高的坐姿,在行車過程中也更方便察看前方的車流。

上汽通用雪佛蘭-創酷

指導價:9.99—14.99萬

在前幾天,雪佛蘭2017款創酷正式上市了。這次上市的為中期改款車型,它的外觀運用了雪佛蘭全新家族化設計,在前臉造型的變化尤為明顯!

其採用立體雙格柵的造型、修長的大燈,較老款車型更有運動感。大燈中還帶有U型LED日間行車燈,配置方面,新車提供胎壓監測、智能啟停功能、ESp、7英寸觸摸屏等亮點配置。

動力系統方面,它搭載的是1.4T渦輪增壓發動機,最大功率達到143馬力,匹配6速手自一體變速箱或6速手動變速箱。

編者點評:

新款創酷設計一下子變得年輕、運動。這樣的設計風格無疑對20多歲的朋友們更有吸引力。而且自動擋車型的起售價僅11.99萬,還採用了1.4T發動機,動力表現十分充沛。喜歡這個價位SUV車型的朋友可以多關注它!

東風標緻-標緻4008

指導價:18.57-27.37萬

因為漂亮、科幻的外觀而備受期待的法系全新SUV,標緻4008也在這個月上市!18.57-27.37萬的售價區間讓它比起翼虎、途觀這些對手車型的指導價要稍低一些。

在外觀和內飾設計方面,標緻4008足夠前衛、時尚。而在動力方面它搭載1.6T、1.8T渦輪增壓發動機,最大功率分別為167馬力、204馬力。匹配6擋手自一體變速箱!

pSA集團採用的這兩套動力系統其實在動力、平順性、油耗方面都有比較出色的表現,如果你需求動力充沛、提速給力的車型,標緻4008可以成為你重點考慮的車型之一。

編者點評:

外觀和內飾的超前的設計、三大件不錯的性能,讓標緻4008的競爭力表現不錯。雖然低配車型的舒適性配置有些缺失,但是其安全性配置還是很厚道的,所以不失為一款競爭力出色的歐系SUV。

最後總結:

上面提到的車型都是本月已經上市的高關注度SUV車型,在性價比方面都表現不錯,而我個人比較喜歡標緻4008,前衛的設計和不錯的操控性是它能打動我的地方!本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※回頭車貨運收費標準

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※推薦評價好的iphone維修中心

※教你寫出一流的銷售文案?

台中搬家公司教你幾個打包小技巧,輕鬆整理裝箱!

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

分類
發燒車訊

天哪!手動編寫mybatis雛形竟然這麼簡單

前言

mybaits 在ORM 框架中,可算是半壁江山了,由於它是輕量級,半自動加載,靈活性和易拓展性。深受廣大公司的喜愛,所以我們程序開發也離不開mybatis 。但是我們有對mabtis 源碼進行研究嗎?或者想看但是不知道怎麼看的苦惱嗎?

歸根結底,我們還是需要知道為什麼會有mybatis ,mybatis 解決了什麼問題?
想要知道mybatis 解決了什麼問題,就要知道傳統的JDBC 操作存在哪些痛點才促使mybatis 的誕生。
我們帶着這些疑問,再來一步步學習吧。

原始JDBC 存在的問題

所以我們先來來看下原始JDBC 的操作:
我們知道最原始的數據庫操作。分為以下幾步:
1、獲取connection 連接
2、獲取preparedStatement
3、參數替代佔位符
4、獲取執行結果resultSet
5、解析封裝resultSet 到對象中返回。

如下是原始JDBC 的查詢代碼,存在哪些問題?

public static void main(String[] args) {
        String dirver="com.mysql.jdbc.Driver";
        String url="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8";
        String userName="root";
        String password="123456";

        Connection connection=null;
        List<User> userList=new ArrayList<>();
        try {
            Class.forName(dirver);
            connection= DriverManager.getConnection(url,userName,password);

            String sql="select * from user where username=?";
            PreparedStatement preparedStatement=connection.prepareStatement(sql);
            preparedStatement.setString(1,"張三");
            System.out.println(sql);
            ResultSet resultSet=preparedStatement.executeQuery();

            User user=null;
            while(resultSet.next()){
                user=new User();
                user.setId(resultSet.getInt("id"));
                user.setUsername(resultSet.getString("username"));
                user.setPassword(resultSet.getString("password"));
                userList.add(user);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (!userList.isEmpty()) {
            for (User user : userList) {
                System.out.println(user.toString());
            }
        }

    }

小夥伴們發現了上面有哪些不友好的地方?
我這裏總結了以下幾點:
1、數據庫的連接信息存在硬編碼,即是寫死在代碼中的。
2、每次操作都會建立和釋放connection 連接,操作資源的不必要的浪費。
3、sql 和參數存在硬編碼。
4、將返回結果集封裝成實體類麻煩,要創建不同的實體類,並通過set方法一個個的注入。

存在上面的問題,所以mybatis 就對上述問題進行了改進。
對於硬編碼,我們很容易就想到配置文件來解決。mybatis 也是這麼解決的。
對於資源浪費,我們想到是用連接池,mybatis 也是這個解決的。
對於封裝結果集麻煩,我們想到是用JDK的反射機制,好巧,mybatis 也是這麼解決的。

設計思路

既然如此,我們就來寫一個自定義吃持久層框架,來解決上述問題,當然是參照mybatis 的設計思路,這樣我們在寫完之後,再來看mybatis 的源碼就恍然大悟,這個地方這樣配置原來是因為這樣啊。
我們分為使用端和框架端兩部分。

使用端

我們在使用mybatis 的時候是不是需要使用SqlMapConfig.xml 配置文件,用來存放數據庫的連接信息,以及mapper.xml 的指向信息。mapper.xml 配置文件用來存放sql 信息。
所以我們在使用端來創建兩個文件SqlMapConfig.xml 和mapper.xml。

框架端

框架端要做哪些事情呢?如下:
1、獲取配置文件。也就是獲取到使用端的SqlMapConfig.xml 以及mapper.xml的 文件
2、解析配置文件。對獲取到的文件進行解析,獲取到連接信息,sql,參數,返回類型等等。這些信息都會保存在configuration 這個對象中。
3、創建SqlSessionFactory,目的是創建SqlSession的一個實例。
4、創建SqlSession ,用來完成上面原始JDBC 的那些操作。

那在SqlSession 中 進行了哪些操作呢?
1、獲取數據庫連接
2、獲取sql,並對sql 進行解析
3、通過內省,將參數注入到preparedStatement 中
4、執行sql
5、通過反射將結果集封裝成對象

使用端實現

好了,上面說了一下,大概的設計思路,主要也是仿照mybatis 主要的類實現的,保證類名一致,方便我們後面閱讀源碼。我們先來配置好使用端吧,我們創建一個maven 項目。
在項目中,我們創建一個User實體類

public class User {
    private Integer id;
    private String username;
    private String password;
    private String birthday;
    //getter()和setter()方法
}

創建SqlMapConfig.xml 和Mapper.xml
SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&amp;characterEncoding=utf8&amp;useUnicode=true&amp;useSSL=false"></property>
    <property name="userName" value="root"></property>
    <property name="password" value="123456"></property>
    
    <mapper resource="UserMapper.xml">
    </mapper>
</configuration>

可以看到我們xml 中就配置了數據庫的連接信息,以及mapper 一個索引。mybatis中的SqlMapConfig.xml 中還包含其他的標籤,只是豐富了功能而已,所以我們只用最主要的。

mapper.xml
是每個類的sql 都會生成一個對應的mapper.xml 。我們這裏就用User 類來說吧,所以我們就創建一個UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<mapper namespace="cn.quellanan.dao.UserDao">
    <select id="selectAll" resultType="cn.quellanan.pojo.User">
        select * from user
    </select>
    <select id="selectByName" resultType="cn.quellanan.pojo.User" paramType="cn.quellanan.pojo.User">
        select * from user where username=#{username}
    </select>
</mapper>

可以看到有點mybatis 裏面文件的味道,有namespace表示命名空間,id 唯一標識,resultType 返回結果集的類型,paramType 參數的類型。
我們使用端先創建到這,主要是兩個配置文件,我們接下來看看框架端是怎麼實現的。

加油哈哈。

框架端實現

框架端,我們按照上面的設計思路一步一步來。

獲取配置

怎麼樣獲取配置文件呢?我們可以使用JDK自帶自帶的類Resources加載器來獲取文件。我們創建一個自定義Resource類來封裝一下:

import java.io.InputStream;
public class Resources {
    public  static InputStream getResources(String path){
        //使用系統自帶的類Resources加載器來獲取文件。
        return Resources.class.getClassLoader().getResourceAsStream(path);
    }
}

這樣通過傳入路徑,就可以獲取到對應的文件流啦。

解析配置文件

上面獲取到了SqlMapConfig.xml 配置文件,我們現在來解析它。
不過在此之前,我們需要做一點準備工作,就是解析的內存放到什麼地方?
所以我們來創建兩個實體類Mapper 和Configuration。

Mapper
Mapper 實體類用來存放使用端寫的mapper.xml 文件的內容,我們前面說了裏面有.id、sql、resultType 和paramType .所以我們創建的Mapper實體如下:

public class Mapper {
    private String id;
    private Class<?> resultType;
    private Class<?> parmType;
    private String sql;
    //getter()和setter()方法
}

這裏我們為什麼不添加namespace 的值呢?
聰明的你肯定發現了,因為mapper裏面這些屬性表明每個sql 都對應一個mapper,而namespace 是一個命名空間,算是sql 的上一層,所以在mapper中暫時使用不到,就沒有添加了。

Configuration
Configuration 實體用來保存SqlMapConfig 中的信息。所以需要保存數據庫連接,我們這裏直接用JDK提供的 DataSource。還有一個就是mapper 的信息。每個mapper 有自己的標識,所以這裏採用hashMap來存儲。如下:

public class Configuration {

    private DataSource dataSource;
    HashMap <String,Mapper> mapperMap=new HashMap<>();
    //getter()和setter方法
    }

XmlMapperBuilder

做好了上面的準備工作,我們先來解析mapper 吧。我們創建一個XmlMapperBuilder 類來解析。通過dom4j 的工具類來解析XML 文件。我這裏用的dom4j 依賴為:

		<dependency>
            <groupId>org.dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>2.1.3</version>
        </dependency>

思路:
1、獲取文件流,轉成document。
2、獲取根節點,也就是mapper。獲取根節點的namespace屬性值
3、獲取select 節點,獲取其id,sql,resultType,paramType
4、將select 節點的屬性封裝到Mapper 實體類中。
5、同理獲取update/insert/delete 節點的屬性值封裝到Mapper 中
6、通過namespace.id 生成key 值將mapper對象保存到Configuration實體中的HashMap 中。
7、返回 Configuration實體
代碼如下:


public class XmlMapperBuilder {
    private Configuration configuration;
    public XmlMapperBuilder(Configuration configuration){
        this.configuration=configuration;
    }

    public Configuration loadXmlMapper(InputStream in) throws DocumentException, ClassNotFoundException {
        Document document=new SAXReader().read(in);

        Element rootElement=document.getRootElement();
        String namespace=rootElement.attributeValue("namespace");

        List<Node> list=rootElement.selectNodes("//select");

        for (int i = 0; i < list.size(); i++) {
            Mapper mapper=new Mapper();
            Element element= (Element) list.get(i);
            String id=element.attributeValue("id");
            mapper.setId(id);
            String paramType = element.attributeValue("paramType");
            if(paramType!=null && !paramType.isEmpty()){
                mapper.setParmType(Class.forName(paramType));
            }
            String resultType = element.attributeValue("resultType");
            if (resultType != null && !resultType.isEmpty()) {
                mapper.setResultType(Class.forName(resultType));
            }
            mapper.setSql(element.getTextTrim());
            String key=namespace+"."+id;
            configuration.getMapperMap().put(key,mapper);
        }
        return configuration;
    }

}

上面我只解析了select 標籤。大家可以解析對應insert/delete/uupdate 標籤,操作都是一樣的。

XmlConfigBuilder

我們再來解析一下SqlMapConfig.xml 配置信息思路是一樣的,
1、獲取文件流,轉成document。
2、獲取根節點,也就是configuration。
3、獲取根節點中所有的property 節點,並獲取值,也就是獲取數據庫連接信息
4、創建一個dataSource 連接池
5、將連接池信息保存到Configuration實體中
6、獲取根節點的所有mapper 節點
7、調用XmlMapperBuilder 類解析對應mapper 並封裝到Configuration實體中
8、完
代碼如下:

public class XmlConfigBuilder {
    private Configuration configuration;
    public XmlConfigBuilder(Configuration configuration){
        this.configuration=configuration;
    }

    public Configuration loadXmlConfig(InputStream in) throws DocumentException, PropertyVetoException, ClassNotFoundException {

        Document document=new SAXReader().read(in);

        Element rootElement=document.getRootElement();

        //獲取連接信息
        List<Node> propertyList=rootElement.selectNodes("//property");
        Properties properties=new Properties();

        for (int i = 0; i < propertyList.size(); i++) {
            Element element = (Element) propertyList.get(i);
            properties.setProperty(element.attributeValue("name"),element.attributeValue("value"));
        }
		//是用連接池
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(properties.getProperty("driverClass"));
        dataSource.setJdbcUrl(properties.getProperty("jdbcUrl"));
        dataSource.setUser(properties.getProperty("userName"));
        dataSource.setPassword(properties.getProperty("password"));
        configuration.setDataSource(dataSource);

        //獲取mapper 信息
        List<Node> mapperList=rootElement.selectNodes("//mapper");
        for (int i = 0; i < mapperList.size(); i++) {
            Element element= (Element) mapperList.get(i);
            String mapperPath=element.attributeValue("resource");
            XmlMapperBuilder xmlMapperBuilder = new XmlMapperBuilder(configuration);
            configuration=xmlMapperBuilder.loadXmlMapper(Resources.getResources(mapperPath));
        }
        return configuration;
    }
}

創建SqlSessionFactory

完成解析后我們創建SqlSessionFactory 用來創建Sqlseesion 的實體,這裏為了盡量還原mybatis 設計思路,也也採用的工廠設計模式。
SqlSessionFactory 是一個接口,裏面就一個用來創建SqlSessionf的方法。
如下:

public interface SqlSessionFactory {
    public SqlSession openSqlSession();
}

單單這個接口是不夠的,我們還得寫一個接口的實現類,所以我們創建一個DefaultSqlSessionFactory。
如下:

public class DefaultSqlSessionFactory implements SqlSessionFactory {

    private Configuration configuration;

    public DefaultSqlSessionFactory(Configuration configuration) {
        this.configuration = configuration;
    }
    public SqlSession openSqlSession() {
        return new DefaultSqlSeeion(configuration);
    }
}

可以看到就是創建一個DefaultSqlSeeion並將包含配置信息的configuration 傳遞下去。DefaultSqlSeeion 就是SqlSession 的一個實現類。

創建SqlSession

在SqlSession 中我們就要來處理各種操作了,比如selectList,selectOne,insert.update,delete 等等。
我們這裏SqlSession 就先寫一個selectList 方法。
如下:

public interface SqlSession {

    /**
     * 條件查找
     * @param statementid  唯一標識,namespace.selectid
     * @param parm  傳參,可以不傳也可以一個,也可以多個
     * @param <E>
     * @return
     */
    public <E> List<E> selectList(String statementid,Object...parm) throws Exception;

然後我們創建DefaultSqlSeeion 來實現SqlSeesion 。

public class DefaultSqlSeeion implements SqlSession {
    private Configuration configuration;
	private Executer executer=new SimpleExecuter();
	
    public DefaultSqlSeeion(Configuration configuration) {
        this.configuration = configuration;
    }

	@Override
    public <E> List<E> selectList(String statementid, Object... parm) throws Exception {
        Mapper mapper=configuration.getMapperMap().get(statementid);
        List<E> query = executer.query(configuration, mapper, parm);
        return query;
    }

}

我們可以看到DefaultSqlSeeion 獲取到了configuration,並通過statementid 從configuration 中獲取mapper。 然後具體實現交給了Executer 類來實現。我們這裏先不管Executer 是怎麼實現的,就假裝已經實現了。那麼整個框架端就完成了。通過調用Sqlsession.selectList() 方法,來獲取結果。

感覺我們都還沒有處理,就框架搭建好了?騙鬼呢,確實前面我們從獲取文件解析文件,然後創建工廠。都是做好準備工作。下面開始我們JDBC的實現。

SqlSession 具體實現

我們前面說SqlSeesion 的具體實現有下面5步
1、獲取數據庫連接
2、獲取sql,並對sql 進行解析
3、通過內省,將參數注入到preparedStatement 中
4、執行sql
5、通過反射將結果集封裝成對象

但是我們在DefaultSqlSeeion 中將實現交給了Executer來執行。所以我們就要在Executer中來實現這些操作。

我們首先來創建一個Executer 接口,並寫一個DefaultSqlSeeion中調用的query 方法。

public interface Executer {

    <E> List<E> query(Configuration configuration,Mapper mapper,Object...parm) throws Exception;

}

接着我們寫一個SimpleExecuter 類來實現Executer 。
然後SimpleExecuter.query()方法中,我們一步一步的實現。

獲取數據庫連接

因為數據庫連接信息保存在configuration,所以直接獲取就好了。

//獲取連接
        connection=configuration.getDataSource().getConnection();

獲取sql,並對sql 進行解析

我們這裏想一下,我們在Usermapper.xml寫的sql 是什麼樣子?

select * from user where username=#{username}

{username} 這樣的sql 我們改怎麼解析呢?

分兩步
1、將sql 找到#{***},並將這部分替換成 ?號

2、對 #{***} 進行解析獲取到裏面的參數對應的paramType 中的值。

具體實現用到下面幾個類。
GenericTokenParser類,可以看到有三個參數,開始標記,就是我們的“#{” ,結束標記就是 “}”, 標記處理器就是處理標記裏面的內容也就是username。

public class GenericTokenParser {

  private final String openToken; //開始標記
  private final String closeToken; //結束標記
  private final TokenHandler handler; //標記處理器

  public GenericTokenParser(String openToken, String closeToken, TokenHandler handler) {
    this.openToken = openToken;
    this.closeToken = closeToken;
    this.handler = handler;
  }

  /**
   * 解析${}和#{}
   * @param text
   * @return
   * 該方法主要實現了配置文件、腳本等片段中佔位符的解析、處理工作,並返回最終需要的數據。
   * 其中,解析工作由該方法完成,處理工作是由處理器handler的handleToken()方法來實現
   */
  public String parse(String text) {
 	 //具體實現
 	 }
  }

主要的就是parse() 方法,用來獲取操作1 的sql。獲取結果例如:

select * from user where username=?

那上面用到TokenHandler 來處理參數。
ParameterMappingTokenHandler實現TokenHandler的類


public class ParameterMappingTokenHandler implements TokenHandler {
	private List<ParameterMapping> parameterMappings = new ArrayList<ParameterMapping>();

	// context是參數名稱 #{id} #{username}

	@Override
	public String handleToken(String content) {
		parameterMappings.add(buildParameterMapping(content));
		return "?";
	}

	private ParameterMapping buildParameterMapping(String content) {
		ParameterMapping parameterMapping = new ParameterMapping(content);
		return parameterMapping;
	}

	public List<ParameterMapping> getParameterMappings() {
		return parameterMappings;
	}

	public void setParameterMappings(List<ParameterMapping> parameterMappings) {
		this.parameterMappings = parameterMappings;
	}

}

可以看到將參數名稱存放 ParameterMapping 的集合中了。
ParameterMapping 類就是一個實體,用來保存參數名稱的。

public class ParameterMapping {

    private String content;

    public ParameterMapping(String content) {
        this.content = content;
    }
	//getter()和setter() 方法。
}

所以我們在我們通過GenericTokenParser類,就可以獲取到解析后的sql,以及參數名稱。我們將這些信息封裝到BoundSql實體類中。

public class BoundSql {

    private String sqlText;
    private List<ParameterMapping> parameterMappingList=new ArrayList<>();
    public BoundSql(String sqlText, List<ParameterMapping> parameterMappingList) {
        this.sqlText = sqlText;
        this.parameterMappingList = parameterMappingList;
    }
    ////getter()和setter() 方法。
  }

好了,那麼分兩步走,先獲取,后解析
獲取
獲取原始sql 很簡單,sql 信息就存在mapper 對象中,直接獲取就好了。

String sql=mapper.getSql()

解析
1、創建一個ParameterMappingTokenHandler 處理器
2、創建一個GenericTokenParser 類,並初始化開始標記,結束標記,處理器
3、執行genericTokenParser.parse(sql);獲取解析后的sql‘’,以及在parameterMappingTokenHandler 中存放了參數名稱的集合。
4、將解析后的sql 和參數封裝到BoundSql 實體類中。

/**
     * 解析自定義佔位符
     * @param sql
     * @return
     */
    private BoundSql getBoundSql(String sql){
        ParameterMappingTokenHandler parameterMappingTokenHandler = new ParameterMappingTokenHandler();
        GenericTokenParser genericTokenParser = new GenericTokenParser("#{","}",parameterMappingTokenHandler);
        String parse = genericTokenParser.parse(sql);
        return new BoundSql(parse,parameterMappingTokenHandler.getParameterMappings());

    }

將參數注入到preparedStatement 中

上面的就完成了sql,的解析,但是我們知道上面得到的sql 還是包含 JDBC的 佔位符,所以我們需要將參數注入到preparedStatement 中。
1、通過boundSql.getSqlText()獲取帶有佔位符的sql.
2、接收參數名稱集合 parameterMappingList
3、通過mapper.getParmType() 獲取到參數的類。
4、通過getDeclaredField(content)方法獲取到參數類的Field。
5、通過Field.get() 從參數類中獲取對應的值
6、注入到preparedStatement 中

		BoundSql boundSql=getBoundSql(mapper.getSql());
        String sql=boundSql.getSqlText();
        List<ParameterMapping> parameterMappingList = boundSql.getParameterMappingList();

        //獲取preparedStatement,並傳遞參數值
        PreparedStatement preparedStatement=connection.prepareStatement(sql);
        Class<?> parmType = mapper.getParmType();

        for (int i = 0; i < parameterMappingList.size(); i++) {
            ParameterMapping parameterMapping = parameterMappingList.get(i);
            String content = parameterMapping.getContent();
            Field declaredField = parmType.getDeclaredField(content);
            declaredField.setAccessible(true);
            Object o = declaredField.get(parm[0]);
            preparedStatement.setObject(i+1,o);
        }
        System.out.println(sql);
        return preparedStatement;

執行sql

其實還是調用JDBC 的executeQuery()方法或者execute()方法

//執行sql
 ResultSet resultSet = preparedStatement.executeQuery();

通過反射將結果集封裝成對象

在獲取到resultSet 后,我們進行封裝處理,和參數處理是類似的。
1、創建一個ArrayList
2、獲取返回類型的類
3、循環從resultSet中取數據
4、獲取屬性名和屬性值
5、創建屬性生成器
6、為屬性生成寫方法,並將屬性值寫入到屬性中
7、將這條記錄添加到list 中
8、返回list

/**
     * 封裝結果集
     * @param mapper
     * @param resultSet
     * @param <E>
     * @return
     * @throws Exception
     */
    private <E> List<E> resultHandle(Mapper mapper,ResultSet resultSet) throws Exception{
        ArrayList<E> list=new ArrayList<>();
        //封裝結果集
        Class<?> resultType = mapper.getResultType();
        while (resultSet.next()) {
            ResultSetMetaData metaData = resultSet.getMetaData();
            Object o = resultType.newInstance();
            int columnCount = metaData.getColumnCount();
            for (int i = 1; i <= columnCount; i++) {
                //屬性名
                String columnName = metaData.getColumnName(i);
                //屬性值
                Object value = resultSet.getObject(columnName);
                //創建屬性描述器,為屬性生成讀寫方法
                PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName,resultType);
                Method writeMethod = propertyDescriptor.getWriteMethod();
                writeMethod.invoke(o,value);
            }
            list.add((E) o);
        }
        return list;
    }

創建SqlSessionFactoryBuilder

我們現在來創建一個SqlSessionFactoryBuilder 類,來為使用端提供一個人口。

public class SqlSessionFactoryBuilder {

    private Configuration configuration;

    public SqlSessionFactoryBuilder(){
        configuration=new Configuration();
    }

    public SqlSessionFactory build(InputStream in) throws DocumentException, PropertyVetoException, ClassNotFoundException {
        XmlConfigBuilder xmlConfigBuilder = new XmlConfigBuilder(configuration);
        configuration=xmlConfigBuilder.loadXmlConfig(in);

        SqlSessionFactory sqlSessionFactory = new DefaultSqlSessionFactory(configuration);
        return sqlSessionFactory;
    }
}

可以看到就一個build 方法,通過SqlMapConfig的文件流將信息解析到configuration,創建並返回一個sqlSessionFactory 。

到此,整個框架端已經搭建完成了,但是我們可以看到,只實現了select 的操作,update、inster、delete 的操作我們在我後面提供的源碼中會有實現,這裏只是將整體的設計思路和流程。

測試

終於到了測試的環節啦。我們前面寫了自定義的持久層,我們現在來測試一下能不能正常的使用吧。
見證奇迹的時刻到啦

我們先引入我們自定義的框架依賴。以及數據庫和單元測試

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>
        <dependency>
            <groupId>cn.quellanan</groupId>
            <artifactId>myself-mybatis</artifactId>
            <version>1.0.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>

然後我們寫一個測試類
1、獲取SqlMapperConfig.xml的文件流
2、獲取Sqlsession
3、執行查找操作

@org.junit.Test
    public void test() throws Exception{
        InputStream inputStream= Resources.getResources("SqlMapperConfig.xml");
        SqlSession sqlSession = new SqlSessionFactoryBuilder().build(inputStream).openSqlSession();
        List<User> list = sqlSession.selectList("cn.quellanan.dao.UserDao.selectAll");

        for (User parm : list) {
            System.out.println(parm.toString());
        }
        System.out.println();

        User user=new User();
        user.setUsername("張三");
        List<User> list1 = sqlSession.selectList("cn.quellanan.dao.UserDao.selectByName", user);
        for (User user1 : list1) {
            System.out.println(user1);
        }

    }

可以看到已經可以了,看來我們自定義的持久層框架生效啦。

優化

但是不要高興的太早哈哈,我們看上面的測試方法,是不是感覺和平時用的不一樣,每次都都寫死statementId ,這樣不太友好,所以我們接下來來點騷操作,通用mapper 配置。
我們在SqlSession中增加一個getMapper方法,接收的參數是一個類。我們通過這個類就可以知道statementId .

/**
     * 使用代理模式來創建接口的代理對象
     * @param mapperClass
     * @param <T>
     * @return
     */
    public <T> T getMapper(Class<T> mapperClass);

具體實現就是利用JDK 的動態代理機制。
1、通過Proxy.newProxyInstance() 獲取一個代理對象
2、返回代理對象
那代理對象執行了哪些操作呢?
創建代理對象的時候,會實現一個InvocationHandler接口,重寫invoke() 方法,讓所有走這個代理的方法都會執行這個invoke() 方法。那這個方法做了什麼操作?
這個方法就是通過傳入的類對象,獲取到對象的類名和方法名。用來生成statementid 。所以我們在mapper.xml 配置文件中的namespace 就需要制定為類路徑,以及id 為方法名。
實現方法:

@Override
    public <T> T getMapper(Class<T> mapperClass) {

        Object proxyInstance = Proxy.newProxyInstance(DefaultSqlSeeion.class.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                //獲取到方法名
                String name = method.getName();
                //類型
                String className = method.getDeclaringClass().getName();
                String statementid=className+"."+name;

                return selectList(statementid,args);
            }
        });


        return (T) proxyInstance;
    }

我們寫一個UserDao

public interface UserDao {
    List<User> selectAll();

    List<User> selectByName(User user);
}

這個是不是我們熟悉的味道哈哈,就是mapper層的接口。
然後我們在mapper.xml 中指定namespace 和id

接下來我們在寫一個測試方法

@org.junit.Test
    public void test2() throws Exception{
        InputStream inputStream= Resources.getResources("SqlMapperConfig.xml");
        SqlSession sqlSession = new SqlSessionFactoryBuilder().build(inputStream).openSqlSession();

        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> users = mapper.selectAll();
        for (User user1 : users) {
            System.out.println(user1);
        }

        User user=new User();
        user.setUsername("張三");
        List<User> users1 = mapper.selectByName(user);
        for (User user1 : users1) {
            System.out.println(user1);
        }

    }

番外

自定義的持久層框架,我們就寫完了。這個實際上就是mybatis 的雛形,我們通過自己手動寫一個持久層框架,然後在來看mybatis 的源碼,就會清晰很多。下面這些類名在mybatis 中都有體現。

這裏拋磚引玉,祝君閱讀源碼愉快。
覺得有用的兄弟們記得收藏啊。

厚顏無恥的求波點贊!!!

本文由博客一文多發平台 OpenWrite 發布!

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※別再煩惱如何寫文案,掌握八大原則!

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※回頭車貨運收費標準

台中搬家公司費用怎麼算?

分類
發燒車訊

海水溫度創高 極端氣候警鈴大作

摘錄自2020年4月19日經濟日報報導

根據美國國家環境資訊中心(NCEI),太平洋、大西洋及印度洋的部分海域溫度同創歷史新高,致使研究機構日益擔憂,未來六個月將醞釀適合颶風、野火及強烈雷暴雨等極端氣候發展的環境,使未來半年的極端氣候事件增加。

科羅拉多州立大學(CSU)研究人員庫拉茲巴赫說,墨西哥灣的海水溫度為華氏76.3度(攝氏24.6度),比長期均溫高出華氏1.7度。若墨灣維持溫暖水溫,將增強從墨灣登陸風暴的威力。

CSU發布的第一個2020年風暴報告預測,大西洋今年形成八個颶風的機率將高於平均值,而且6月1日起、為期六個月的颶風季期間,至少會有一個颶風將登陸美國。美國將在下月發布颶風預報。

海洋
全球變遷
生態保育
氣候變遷
生物多樣性
國際新聞
太平洋
大西洋
印度洋
颶風
森林野火
極端氣候
全球暖化

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

※教你寫出一流的銷售文案?

※超省錢租車方案

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※回頭車貨運收費標準

分類
發燒車訊

日本研究發現大氣污染導致心臟驟停者增加

摘錄自2020年4月18日共同社報導

日本川崎醫科大學(岡山縣)等團隊17日在美國醫學雜誌上發表研究結果稱,如果大氣污染物之一、細顆粒物PM2.5在大氣中的濃度上升,因在家中、室外等地心臟驟停被緊急送醫的人就會增加。

研究團隊分析了2011年至2016年的約6年期間全國47個都道府縣被送醫的10萬人數據與各地點PM2.5濃度之間的關係。團隊成員、川崎醫科大學循環器內科學教授小島淳表示:「在首次全國範圍的研究中,弄清了大氣污染與心臟驟停有關。」

據該團隊分析,若PM2.5在大氣中的濃度從某一標準上升每立方米10微克(1微克為百萬分之一克),因心臟驟停被送醫的人在全國增加1.6%。

將日本分為三個大區進行調查後發現,愛知到大阪、高知的中央地區14個府縣上升5.9%。此外若僅限於5至10月溫暖的時期,全國增加2.3%。據稱均不清楚詳細原因。進行調查的6年間全國PM2.5平均濃度為每立方米13.9微克。各地濃度使用了各都道府縣政府所在地的觀測數值。

空氣污染
公害污染
污染治理
國際新聞
日本
心臟病
PM2.5

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※別再煩惱如何寫文案,掌握八大原則!

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※超省錢租車方案

※教你寫出一流的銷售文案?

網頁設計最專業,超強功能平台可客製化

※產品缺大量曝光嗎?你需要的是一流包裝設計!

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

分類
發燒車訊

武漢肺炎對全球食品業的衝擊 麵粉大缺貨 牛奶、啤酒、茶葉過剩成廚餘

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※教你寫出一流的銷售文案?

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※推薦台中搬家公司優質服務,可到府估價

分類
發燒車訊

人類全都隔離去了!海獅成群上岸逛大街 嚇壞流浪狗

摘錄自2020年4月20日自由時報報導

武漢肺炎疫情延燒全球,世界多國正在實施隔離封鎖令,民眾非必要不得外出,這也使得許多野生動物活動範圍因而變廣,在南美洲阿根廷的海岸城市,巨大的海豹跑進市區遊蕩,把流浪狗嚇壞了。

根據《俄羅斯衛星通信社》報導,阿根廷知名旅遊勝地馬德普拉塔(Mar del Plata)因實施隔離政策,街道沒人,遊客不來,巨大的海獅得以進入市區四處散步,並沿著海岸追逐難得一見的人類,對平時少見的景象感到相當好奇,但也嚇壞不少原本生活在當地的流浪狗。

生活環境
國際新聞
阿根廷
控制疫情
隔離
海豹

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

※別再煩惱如何寫文案,掌握八大原則!

※回頭車貨運收費標準

※教你寫出一流的銷售文案?

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

網頁設計最專業,超強功能平台可客製化

分類
發燒車訊

英封城期間 販賣機賣肉和菜、直接向漁夫買 掀新商機

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※產品缺大量曝光嗎?你需要的是一流包裝設計!

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※回頭車貨運收費標準

※推薦評價好的iphone維修中心

※超省錢租車方案

台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

※推薦台中搬家公司優質服務,可到府估價