可以Postman,也可以cURL.進來領略下cURL的獨門絕技_台中搬家公司

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

台中搬鋼琴,台中金庫搬運,中部廢棄物處理,南投縣搬家公司,好幫手搬家,西屯區搬家

文章已經收錄在 Github.com/niumoo/JavaNotes ,更有 Java 程序員所需要掌握的核心知識,歡迎Star和指教。
歡迎關注我的公眾號,文章每周更新。

cURL 是一個開源免費項目,主要是命令行工具 cURL 和 libcurl,cURL 可以處理任何網絡傳輸協議,但是不涉及任何具體的數據處理。

cURL 支持的通信協議非常豐富,如 DICT,FILE,FTP,FTPS,GOPHER,HTTP,HTTPS,IMAP,IMAPS,LDAP,LDAPS,MQTT,POP3,POP3S,RTMP, RTMPS,RTSP,SCP,SFTP,SMB,SMBS,SMTP,SMTPS,TELNET 以及 TFTP。查看 cURL 源代碼可以訪問官方 Github。

如果安裝 cURL 呢?

ubuntu / Debian.

sudo apt install curl

CentOS / Fedora.

sudo yum install curl

Windows.

如果你已經安裝了 Git,那麼 Git Bash 自帶 cURL . 如果作為開發者你 git 都沒有,那麼只能官方手動下載。

1. 請求源碼

直接 curl 。

$ curl http://wttr.in/

上面請求的示例網址是一個天氣網站,很有意思,會根據你的請求 ip 信息返回你所在位置的天氣情況。

寫這篇文字時我所在的上海正在下雨,窗外飄雨無休無止。

2. 文件下載

使用 -o 保存文件,類似於 wget 命令,比如下載 README 文本保存為 readme.txt 文件。如果你需要自定義文件名,可以使用 -O自定使用 url 中的文件名。

$ curl -o readme.txt https://mirrors.nju.edu.cn/kali/README
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   159  100   159    0     0   1939      0 --:--:-- --:--:-- --:--:--  1939

下載文件會显示下載狀態,如數據量大小、傳輸速度、剩餘時間等。可以使用 -s 參數禁用進度表。

$ curl -o readme.txt https://mirrors.nju.edu.cn/kali/README
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   159  100   159    0     0   1939      0 --:--:-- --:--:-- --:--:--  1939
$ 
$ curl -o readme.txt https://mirrors.nju.edu.cn/kali/README -s

也可以使用 --process-bar 參數讓進度表显示為進度條。

$ curl -o readme.txt https://mirrors.nju.edu.cn/kali/README --progress-bar
########################################################################################## 100.0%

cURL 作為強大的代名詞,斷點續傳自然手到擒來,使用 -C - 參數即可。下面是斷點續傳下載 ubuntu20.04 鏡像的例子。

$ curl -O https://mirrors.nju.edu.cn/ubuntu-releases/20.04/ubuntu-20.04-desktop-amd64.iso --progress-bar
##                                                                                               1.7%
^C
$ curl -C - -O https://mirrors.nju.edu.cn/ubuntu-releases/20.04/ubuntu-20.04-desktop-amd64.iso --progress-bar
###                                                                                              2.4%
^C
$ curl -C - -O https://mirrors.nju.edu.cn/ubuntu-releases/20.04/ubuntu-20.04-desktop-amd64.iso --progress-bar
###                                                                                               2.7%
^C
$ 

什麼?下載時不想佔用太多網速?使用 --limit-rate 限個速吧。

curl -C - -O https://mirrors.nju.edu.cn/ubuntu-releases/20.04/ubuntu-20.04-desktop-amd64.iso --limit-rate 100k

什麼?你又要從 FTP 服務器下載文件了?不慌。

curl -u user:password -O ftp://ftp_server/path/to/file/

3. Response Headers

使用 -i 參數显示 Response Headers 信息。使用 -I 可以只显示 Response Headers 信息。

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

還在煩惱搬家費用要多少哪?台中大展搬家線上試算搬家費用,從此不再擔心「物品怎麼計費」、「多少車才能裝完」

$ curl -I http://wttr.in
HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Sat, 30 May 2020 09:57:03 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 8678
Connection: keep-alive
Access-Control-Allow-Origin: *

4. 請求方式(GET/POST/…)

使用 -X 輕鬆更改請求方式。

$ curl -X GET http://wttr.in
$ curl -X POST http://wttr.in
$ curl -X PUT http://wttr.in
...

5. 請求參數

以傳入參數 name 值為 未讀代碼 為例。

Get 方式參數直接url拼接參數。

$ curl -X GET http://wttr.in?name=未讀代碼

Post 方式使用 --data 設置參數。

$ curl -X POST --data "name=未讀代碼" http://wttr.in

請求時也可以自定義 header 參數,使用 --harder 添加。

$ curl --header "Content-Type:application/json" http://wttr.in

6. 文件上傳

cURL 的強大遠不止此,表單提交,上傳文件內容也不在話下,只需要使用 -F 或者 -D參數,-F 會自動加上請求頭 Content-Type: multipart/form-data ,而 -D 則是 Content-Type : application/x-www-form-urlencoded.

比如上傳一個 protrait.jpg 圖片。

$ curl -F profile=@portrait.jpg https://example.com/upload

提交一個具有 name 和 age 參數的 form 表單。

curl -F name=Darcy -F age=18 https://example.com/upload

參數對應的內容也可以從文件中讀取。

curl -F "content=<達西的身世.txt" https://example.com/upload

上傳時同時指定內容類型。

curl -F "content=<達西的身世.txt;type=text/html" https://example.com/upload

上傳文件的和其他參數一起。

curl -F 'file=@"localfile";filename="nameinpost"' example.com/upload

7. 網址通配

cURL 可以實現多個網址的匹配,你可以使用 {} 結合逗號分割來標識使用 url 中的某一段,也可以使用 [] 來表示範圍參數。

# 請求 www.baidu.com 和  pan.baidu.com 和 fanyi.baidu.com
$ curl http://{www,pan,fanyi}.baidu.com
# 虛構網址1-10開頭的baidu.com,然後請求
$ curl http://[1-10].baidu.com
# 虛構網址a-z開頭的baidu.com,然後請求
$ curl http://[a-z].baidu.com

這種方式有時候還是很有用處的,比如說你發現了某個網站的 url 規律。

8. 使用 cookie

請求時使用 -c 參數存儲響應的 cookie,使用 -b 可以在請求時帶上指定 cookie.

$ curl -c wdbyte_cookies http://www.wdbyte.com
$ curl -b wdbyte_cookes http://www.wdbyte.com

總結

以上就是 cURL 的常見用法了,最後告訴你一個小技巧,Chrome、Firefox 等瀏覽器可以直接拷貝請求為 cURL 語句。保存之後下次請求測試非常方便。

參考資料

  1. https://curl.haxx.se/docs/manpage.html

最後的話

文章已經收錄在 Github.com/niumoo/JavaNotes ,歡迎Star和指教。更有一線大廠面試點,Java程序員需要掌握的核心知識等文章,也整理了很多我的文字,歡迎 Star 和完善,希望我們一起變得優秀。

文章有幫助可以點個「贊」或「分享」,都是支持,我都喜歡!
文章每周持續更新,要實時關注我更新的文章以及分享的乾貨,可以關注「 未讀代碼 」公眾號或者我的博客。

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

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

還在煩惱搬家費用要多少哪?台中大展搬家線上試算搬家費用,從此不再擔心「物品怎麼計費」、「多少車才能裝完」

過濾器 和 攔截器 6個區別,別再傻傻分不清了_台中搬家

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

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

本文收錄在個人博客:www.chengxy-nds.top,技術資料共享,同進步

周末有個小夥伴加我微信,向我請教了一個問題:老哥,過濾器 (Filter) 和 攔截器 (Interceptor) 有啥區別啊? 聽到題目我的第一感覺就是:簡單!

畢竟這兩種工具開發中用到的頻率都相當高,應用起來也是比較簡單的,可當我準備回復他的時候,竟然不知道從哪說起,支支吾吾了半天,場面炒雞尷尬有木有,工作這麼久一個基礎問題答成這樣,丟了大人了。

平時覺得簡單的知識點,但通常都不會太關注細節,一旦被別人問起來,反倒說不出個所以然來。

歸根結底,還是對這些知識了解的不夠,一直停留在會用的階段,以至於現在一看就會一說就廢!這是典型基礎不紮實的表現,哎·~,其實我也就是個虛胖!

知恥而後勇,下邊結合實踐,更直觀的來感受一下兩者到底有什麼不同?

準備環境

我們在項目中同時配置 攔截器 和 過濾器。

1、過濾器 (Filter)

過濾器的配置比較簡單,直接實現Filter 接口即可,也可以通過@WebFilter註解實現對特定URL攔截,看到Filter 接口中定義了三個方法。

  • init() :該方法在容器啟動初始化過濾器時被調用,它在 Filter 的整個生命周期只會被調用一次。注意:這個方法必須執行成功,否則過濾器會不起作用。

  • doFilter() :容器中的每一次請求都會調用該方法, FilterChain 用來調用下一個過濾器 Filter。

  • destroy(): 當容器銷毀 過濾器實例時調用該方法,一般在方法中銷毀或關閉資源,在過濾器 Filter 的整個生命周期也只會被調用一次

@Component
public class MyFilter implements Filter {
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        System.out.println("Filter 前置");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println("Filter 處理中");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

        System.out.println("Filter 後置");
    }
}

2、攔截器 (Interceptor)

攔截器它是鏈式調用,一個應用中可以同時存在多個攔截器Interceptor, 一個請求也可以觸發多個攔截器 ,而每個攔截器的調用會依據它的聲明順序依次執行。

首先編寫一個簡單的攔截器處理類,請求的攔截是通過HandlerInterceptor 來實現,看到HandlerInterceptor 接口中也定義了三個方法。

  • preHandle() :這個方法將在請求處理之前進行調用。注意:如果該方法的返回值為false ,將視為當前請求結束,不僅自身的攔截器會失效,還會導致其他的攔截器也不再執行。

  • postHandle():只有在 preHandle() 方法返回值為true 時才會執行。會在Controller 中的方法調用之後,DispatcherServlet 返回渲染視圖之前被調用。 有意思的是:postHandle() 方法被調用的順序跟 preHandle() 是相反的,先聲明的攔截器 preHandle() 方法先執行,而postHandle()方法反而會後執行。

  • afterCompletion():只有在 preHandle() 方法返回值為true 時才會執行。在整個請求結束之後, DispatcherServlet 渲染了對應的視圖之後執行。

@Component
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        System.out.println("Interceptor 前置");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        System.out.println("Interceptor 處理中");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        System.out.println("Interceptor 後置");
    }
}

將自定義好的攔截器處理類進行註冊,並通過addPathPatterns、excludePathPatterns等屬性設置需要攔截或需要排除的 URL。

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
        registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**");
    }
}

我們不一樣

過濾器 和 攔截器 均體現了AOP的編程思想,都可以實現諸如日誌記錄、登錄鑒權等功能,但二者的不同點也是比較多的,接下來一一說明。

1、實現原理不同

過濾器和攔截器 底層實現方式大不相同,過濾器 是基於函數回調的,攔截器 則是基於Java的反射機制(動態代理)實現的。

這裏重點說下過濾器!

在我們自定義的過濾器中都會實現一個 doFilter()方法,這個方法有一個FilterChain 參數,而實際上它是一個回調接口。ApplicationFilterChain是它的實現類, 這個實現類內部也有一個 doFilter() 方法就是回調方法。

public interface FilterChain {
    void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
}

ApplicationFilterChain裏面能拿到我們自定義的xxxFilter類,在其內部回調方法doFilter()里調用各個自定義xxxFilter過濾器,並執行 doFilter() 方法。

public final class ApplicationFilterChain implements FilterChain {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response) {
            ...//省略
            internalDoFilter(request,response);
    }
 
    private void internalDoFilter(ServletRequest request, ServletResponse response){
    if (pos < n) {
            //獲取第pos個filter    
            ApplicationFilterConfig filterConfig = filters[pos++];        
            Filter filter = filterConfig.getFilter();
            ...
            filter.doFilter(request, response, this);
        }
    }
 
}

而每個xxxFilter 會先執行自身的 doFilter() 過濾邏輯,最後在執行結束前會執行filterChain.doFilter(servletRequest, servletResponse),也就是回調ApplicationFilterChain的doFilter() 方法,以此循環執行實現函數回調。

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        filterChain.doFilter(servletRequest, servletResponse);
    }

2、使用範圍不同

我們看到過濾器 實現的是 javax.servlet.Filter 接口,而這個接口是在Servlet規範中定義的,也就是說過濾器Filter 的使用要依賴於Tomcat等容器,導致它只能在web程序中使用。

而攔截器(Interceptor) 它是一個Spring組件,並由Spring容器管理,並不依賴Tomcat等容器,是可以單獨使用的。不僅能應用在web程序中,也可以用於Application、Swing等程序中。

3、觸發時機不同

過濾器 和 攔截器的觸發時機也不同,我們看下邊這張圖。

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

台中搬家公司推薦超過30年經驗,首選台中大展搬家

過濾器Filter是在請求進入容器后,但在進入servlet之前進行預處理,請求結束是在servlet處理完以後。

攔截器 Interceptor 是在請求進入servlet后,在進入Controller之前進行預處理的,Controller 中渲染了對應的視圖之後請求結束。

4、攔截的請求範圍不同

在上邊我們已經同時配置了過濾器和攔截器,再建一個Controller接收請求測試一下。

@Controller
@RequestMapping()
public class Test {

    @RequestMapping("/test1")
    @ResponseBody
    public String test1(String a) {
        System.out.println("我是controller");
        return null;
    }
}

項目啟動過程中發現,過濾器的init()方法,隨着容器的啟動進行了初始化。

此時瀏覽器發送請求,F12 看到居然有兩個請求,一個是我們自定義的 Controller 請求,另一個是訪問靜態圖標資源的請求。

看到控制台的打印日誌如下:

執行順序 :Filter 處理中 -> Interceptor 前置 -> 我是controller -> Interceptor 處理中 -> Interceptor 處理后

Filter 處理中
Interceptor 前置
Interceptor 處理中
Interceptor 後置
Filter 處理中

過濾器Filter執行了兩次,攔截器Interceptor只執行了一次。這是因為過濾器幾乎可以對所有進入容器的請求起作用,而攔截器只會對Controller中請求或訪問static目錄下的資源請求起作用。

5、注入Bean情況不同

在實際的業務場景中,應用到過濾器或攔截器,為處理業務邏輯難免會引入一些service服務。

下邊我們分別在過濾器和攔截器中都注入service,看看有什麼不同?

@Component
public class TestServiceImpl implements TestService {

    @Override
    public void a() {
        System.out.println("我是方法A");
    }
}

過濾器中注入service,發起請求測試一下 ,日誌正常打印出“我是方法A”。

@Autowired
    private TestService testService;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println("Filter 處理中");
        testService.a();
        filterChain.doFilter(servletRequest, servletResponse);
    }
Filter 處理中
我是方法A
Interceptor 前置
我是controller
Interceptor 處理中
Interceptor 後置

在攔截器中注入service,發起請求測試一下 ,竟然TM的報錯了,debug跟一下發現注入的service怎麼是Null啊?

這是因為加載順序導致的問題,攔截器加載的時間點在springcontext之前,而Bean又是由spring進行管理。

攔截器:老子今天要進洞房;
Spring:兄弟別鬧,你媳婦我還沒生出來呢!

解決方案也很簡單,我們在註冊攔截器之前,先將Interceptor 手動進行注入。注意:在registry.addInterceptor()註冊的是getMyInterceptor() 實例。

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Bean
    public MyInterceptor getMyInterceptor(){
        System.out.println("注入了MyInterceptor");
        return new MyInterceptor();
    }
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(getMyInterceptor()).addPathPatterns("/**");
    }
}

6、控制執行順序不同

實際開發過程中,會出現多個過濾器或攔截器同時存在的情況,不過,有時我們希望某個過濾器或攔截器能優先執行,就涉及到它們的執行順序。

過濾器用@Order註解控制執行順序,通過@Order控制過濾器的級別,值越小級別越高越先執行。

@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
public class MyFilter2 implements Filter {

攔截器默認的執行順序,就是它的註冊順序,也可以通過Order手動設置控制,值越小越先執行。

 @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**").order(2);
        registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**").order(1);
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").order(3);
    }

看到輸出結果發現,先聲明的攔截器 preHandle() 方法先執行,而postHandle()方法反而會後執行。

postHandle() 方法被調用的順序跟 preHandle() 居然是相反的!如果實際開發中嚴格要求執行順序,那就需要特別注意這一點。

Interceptor1 前置
Interceptor2 前置
Interceptor 前置
我是controller
Interceptor 處理中
Interceptor2 處理中
Interceptor1 處理中
Interceptor 後置
Interceptor2 處理后
Interceptor1 處理后

那為什麼會這樣呢? 得到答案就只能看源碼了,我們要知道controller 中所有的請求都要經過核心組件DispatcherServlet路由,都會執行它的 doDispatch() 方法,而攔截器postHandle()、preHandle()方法便是在其中調用的。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
        try {
         ...........
            try {
           
                // 獲取可以執行當前Handler的適配器
                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

                // Process last-modified header, if supported by the handler.
                String method = request.getMethod();
                boolean isGet = "GET".equals(method);
                if (isGet || "HEAD".equals(method)) {
                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                    if (logger.isDebugEnabled()) {
                        logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                    }
                    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }
                // 注意: 執行Interceptor中PreHandle()方法
                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }

                // 注意:執行Handle【包括我們的業務邏輯,當拋出異常時會被Try、catch到】
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
                applyDefaultViewName(processedRequest, mv);

                // 注意:執行Interceptor中PostHandle 方法【拋出異常時無法執行】
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            }
        }
        ...........
    }

看看兩個方法applyPreHandle()、applyPostHandle()具體是如何被調用的,就明白為什麼postHandle()、preHandle() 執行順序是相反的了。

boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HandlerInterceptor[] interceptors = this.getInterceptors();
        if(!ObjectUtils.isEmpty(interceptors)) {
            for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {
                HandlerInterceptor interceptor = interceptors[i];
                if(!interceptor.preHandle(request, response, this.handler)) {
                    this.triggerAfterCompletion(request, response, (Exception)null);
                    return false;
                }
            }
        }

        return true;
    }
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
        HandlerInterceptor[] interceptors = this.getInterceptors();
        if(!ObjectUtils.isEmpty(interceptors)) {
            for(int i = interceptors.length - 1; i >= 0; --i) {
                HandlerInterceptor interceptor = interceptors[i];
                interceptor.postHandle(request, response, this.handler, mv);
            }
        }
    }

發現兩個方法中在調用攔截器數組 HandlerInterceptor[] 時,循環的順序竟然是相反的。。。,導致postHandle()、preHandle() 方法執行的順序相反。

總結

我相信大部分人都能熟練使用濾器和攔截器,但兩者的差別還是需要多了解下,不然開發中使用不當,時不時就會出現奇奇怪怪的問題,以上內容比較簡單,新手學習老鳥複習,有遺漏的地方還望大家积極補充,如有理解錯誤之處,還望不吝賜教。

原創不易,燃燒秀髮輸出內容

整理了幾百本各類技術电子書, 送給小夥伴們, 我的同名公眾號自行領取。和一些小夥伴們建了一個技術交流群,一起探討技術、分享技術資料,旨在共同學習進步,如果感興趣就加入我們吧!

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

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

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

SpringBoot整合Flyway(數據庫版本遷移工具)_台中搬家公司

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

台中搬鋼琴,台中金庫搬運,中部廢棄物處理,南投縣搬家公司,好幫手搬家,西屯區搬家

簡介

在團隊開發當中,有可能每個人都是使用自己本地的數據庫。當數據庫的表或者字段更新時,往往需要告知團隊的其他同事進行更新。
Flyway數據庫版本遷移工具,目的就是解決該問題而誕生的(我自己想的)。每當我們更新數據庫的時候,只需要添加SQL文件到指定目錄中。Flyway會在數據庫創建一個表,專門記錄已更新的SQL文件。當我們下次執行時則不會執行已記錄並且執行成功的SQL文件。

整合

maven

現在的Flyway的最新版本已經到了6.4.2。我用的是6.3.3。

<!-- https://mvnrepository.com/artifact/org.flywaydb/flyway-core -->
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>6.3.3</version>
</dependency>

application配置

搞定了Flyway的依賴后,修改一下SpringBoot的application.yml或application.xml配置。

spring:
  flyway:
    url: jdbc:mysql://192.168.138.132:3306/hotel-server?useUnicode=true&characterEncoding=UTF-8 
    user: johnson 
    password: 123456 
    table: flyway_schema_history
    enabled: true
    locations: classpath:db/migration
    clean-disabled: false

flyway配置詳解

url:連接數據庫的Url 默認為spring.datasource.url
user:連接數據庫的賬號 默認為spring.datasource.username
password:連接數據庫的密碼 默認為spring.datasource.password
table:自定義數據庫版本管理表 默認為 flyway_schema_history
enabled:是否開啟 默認為開啟
locations:SQL文件存放路徑 默認 classpath:db/migration

SQL文件

上面的locations參數配置的SQL文件存放路徑為 classpath:db/migration,classpath對應的目錄就是resources目錄,創建后的目錄如下圖:

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

還在煩惱搬家費用要多少哪?台中大展搬家線上試算搬家費用,從此不再擔心「物品怎麼計費」、「多少車才能裝完」

SQL文件如上圖,SQL文件名必須為V1.0.x__xxx.sql(注意:這裏的下劃線為兩個_,我也是掉坑了才知道),這樣可以對應SQL更新的版本號。啟動了SpringBoot項目后,就會自動幫你執行SQL文件,可以看到數據庫版本控製表中生成的數據:

clean操作

Flyway的clean操作:徹底清除已配置的架構,它將有效地為您提供一個全新的起點。所有對象(表,視圖,過程等)都將被刪除。

spring:
  flyway:
    clean-on-validation-error: true
    clean-disabled: false

clean-on-validation-error:發生驗證的錯誤時是否執行clean操作(如SQL執行失敗),默認false,生產中必須使用false。
clean-disabled:是否禁用clean操作,默認false,生產中必須使用true

如果我們設置 clean-on-validation-error = true,clean-disabled = false。
當我們的SQL文件執行失敗,在數據庫版本控製表flyway_schema_history會添加一條失敗的記錄,success字段為0,此時並不會執行clean操作。
當把SQL文件修改正確並執行完后,此時flyway_schema_history會把失敗記錄的success字段由0改為1。並且會執行clean操作!!!!!整個數據庫的表裡面的數據都被清空了!(除非你在SQL文件中添加了insert操作)
其實在開發環境我也是不建議使用clean,畢竟填數據也是要時間的。。。

總結

團隊開發當中的必備工具啊!不過生產環境當中記得把clean-disabled改為true

個人博客網址: https://colablog.cn/

如果我的文章幫助到您,可以關注我的微信公眾號,第一時間分享文章給您

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

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

台中搬鋼琴,台中金庫搬運,中部廢棄物處理,南投縣搬家公司,好幫手搬家,西屯區搬家

掄牆鞭死5歲童 養母求處囚終身_網頁設計公司

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

台中景泰電動車行只是一個單純的理由,將來台灣的環境,出門可以自由放心的深呼吸,讓空氣回歸自然的乾淨,減少污染,留給我們下一代有好品質無空污的優質環境

新聞出處: 蘋果日報   記者:孫友廉、黃哲民

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

以設計的實用美學觀點,規劃出舒適、美觀的視覺畫面,有效提昇使用者的心理期待,營造出輕鬆、愉悅的網站瀏覽體驗。



毆打虐待養子致死的樊女,遭求處無期徒刑。資料照片

新北市樊姓女子因曾凌虐年幼養子,今 年5月,遭法院判刑確定,不料,今年9月,她竟再持水管鞭打5歲養子,更腳踹、手掐養子下體,還抓養子頭去撞牆,致養子傷重死亡。板橋地檢署痛斥樊女手段 殘忍,虐待成性,昨依殺人罪起訴,求處無期徒刑,也請法院繼續羈押獲准。

曾遭判刑仍未悔悟

33 歲的樊女與夫因無法生育,陸續領養1子1女,前年7月起,樊女便常以年僅3歲的養子隨地便溺、不受管教等理由,多次毆打養子,造成他身體、生殖器等多處受 傷;8月10日,更打傷養子頭部,造成長約11公分的撕裂傷,今年5月才遭台灣高等法院依傷害罪判刑4月,得易科罰金12萬元,緩刑5年,緩刑期間交付保 護管束確定。

不料樊女仍未悔悟,今年9月14日,在觀護人探視輔導3天後,竟再持水管鞭打養子,還手捏下體,腳踹胸腹,將養子推倒在地,再抓養子 頭去撞牆;樊女見養子沒反應也未送醫,直到丈夫下班發現,連忙開車載養子、樊女,前去警局報案,樊夫到警局便大喊:「誰會CPR?趕快救救我兒子!」但養 子已氣絕身亡。

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

網站的第一印象網頁設計,決定了客戶是否繼續瀏覽的意願。台北網動廣告製作的RWD網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上它。

俄童生吞42個磁鐵 嚇壞母親_如何寫文案

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

什麼是銷售文案服務?A就是幫你撰寫適合的廣告文案。當您需要販售商品、宣傳活動、建立個人品牌,撰寫廣告文案都是必須的工作。

新聞出處: 蘋果日報  

俄羅斯一名1歲又4個月大的男童,在上周二被母親發現生吞42個磁鐵,緊急送醫後,醫師從男童體內取出磁鐵,目前男童恢復狀況良好。

據了解,日前男童的母親發現,貼在冰箱上的磁鐵不翼而飛,

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

擁有後台管理系統的網站,將擁有強大的資料管理與更新功能,幫助您隨時新增網站的內容並節省網站開發的成本。

懷疑是兒子為了好玩,將磁鐵拿走。這名母親的猜測無誤,磁鐵確實被男童拿走,但母親之後驚覺男童竟把磁鐵吃下肚,將男童送醫。醫師表示,他們從男童肚裡取出42個磁鐵。


俄國1歲4個月大男童生吞42個磁鐵,嚇壞母親。翻自網路

醫師也說,這或許是他執業以來遇到的「紀錄」,也呼籲家長注意將小東西放在兒童拿不到的地方。

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

銷售文案是什麼?A文案是廣告用的文字。舉凡任何宣傳、行銷、販賣商品時所用到的文字都是文案。在網路時代,文案成為行銷中最重要的宣傳方式,好的文案可節省大量宣傳資源,達成行銷目的。

3歲男童掉入15米深井底 鑽繩套成功自救_網頁設計公司

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

當全世界的人們隨著網路時代而改變向上時您還停留在『網站美醜不重要』的舊有思維嗎?機會是留給努力改變現況的人們,別再浪費一分一秒可以接觸商機的寶貴時間!

新聞出處:北京新浪網    





放大圖
看更多圖片

  本報訊(記者 陳海峰 通訊員 馬世華 文圖) 本報商丘訊 柘城縣梁庄鄉一名3歲男孩在捉蝴蝶時,不慎掉入15米深的機井中。由於井口直徑僅40厘米,救援人員根本無法下井。消防官兵衹好將救援繩子打結,慢慢放入井內,現場指導落井孩子自己操作,半個小時後,孩子被救上來。經醫生檢查,小孩衹受了些擦傷,無生命危險。

  3歲娃掉入15米深機井里

  3月11日下午,提起兒子掉入井里的那一幕,柘城縣梁庄鄉的劉先生仍然心有余悸。

  據他介紹,3月8日下午,兒子和鄰居的一個同齡孩子出去玩耍,誰知,一會兒兩人便不見了蹤影。正在家人尋找時,鄰居的孩子跑回來說他兒子在捉蝴蝶時,掉進了麥地的井里。

  “我一路找一路喊我兒子名字,聽到他的哭聲,立即趕過去,看到兒子正在井下,水淹到孩子胸口處。”劉先生說,他趕緊撥打了119。

  接到求助電話後,柘城縣消防官兵迅速趕赴現場。

  消防員在現場看到,該機井直徑約40厘米,深約15米,水面距離地面約14米。借著燈光觀察,可見男孩上半身卡在井下水面之上,情況萬分危急。

  消防員指導協助

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

透過資料庫的網站架設建置,建立公司的形象或購物系統,並提供最人性化的使用介面,讓使用者能即時接收到相關的資訊

  孩子自救成功

  消防官兵迅速利用壓縮氣瓶向井底輸送新鮮空氣,並對落井小孩持續喊話:“小朋友,不要怕,叔叔馬上救妳上來。”

  由於井口太窄,救援人員無法下井。於是,救援人員制訂了三個救援方案:一是利用井下救援鉤進行救援﹔二是利用結繩法打套進行救援﹔三是利用挖掘機挖土救援。

  由於孩子被卡在井壁內,救援器材無法展開,第一個救援方案未能成功﹔此時,救援人員調來了一台大型挖掘機,第三個方案和第二個方案同時進行。

  救援人員將繩索打個套,慢慢放入井內,接近落井小孩,同時向其喊話:“小朋友,不要害怕,叔叔馬上就救妳上來,妳配合一下,把妳的雙手合在一塊,伸入繩圈,然後抓住繩圈上面的繩結。小朋友,不要害怕,慢慢來,妳馬上就能上來了。”

  聽到消防人員的喊話後,小孩將手套入繩套中,救援人員慢慢地收緊繩子。但剛向上提升約兩米,小孩的頭部被井壁突出部分卡住,無法繼續上升。哇哇的哭聲又從井底傳出。

  “小朋友,不要怕,妳馬上就能出來了,請按照叔叔說的做,把妳的頭慢慢地向前趴,向妳手臂的方向……”消防隊員小心翼翼地拉著繩子,耐心地向孩子喊話。

  聽到喊話,小孩的情緒好轉,並按照消防隊員的方法將頭慢慢靠近自己的手臂,經過一番努力,落井小孩終於通過了那段狹窄的井壁,慢慢地被拉了上來。

  劉先生夫婦看到孩子被救了上來,一把抱住孩子,哭了起來。經醫生檢查,孩子的臉部和右腳部有些擦傷,生命體征完好。

(原標題:真能!3歲娃15米深井底鑽繩套自救)

詳全文 3歲男童掉入15米深井底 鑽繩套成功自救-兩岸新聞-新浪新聞中心 http://news.sina.com.tw/article/20130312/9135110.html

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

RWD(響應式網頁設計)是透過瀏覽器的解析度來判斷要給使用者看到的樣貌

泳池變態男猥褻小六童 還說:你可以摸我_網頁設計

※台北網頁設計公司這麼多該如何選擇?

網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品

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

擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢

台中出現泳池變態男,竟然在公共浴室洗澡時,伸手撫摸旁邊小六男童的下體,甚至還開口跟他說「你也可以摸我的」,男童嚇得大聲叫阿公,男子這才趕緊收拾東西離開,看到男童追了出來,他還警告男童不准跟著他。事後男童身心受傷,跟媽媽哭訴後,家人趕緊帶著他報警,並且調閱監視器,揪出這名泳池色狼。

游泳池浴室,卡其色上衣、綠色短褲男子匆忙跑了出來,快步離開,後面1名男童顧不得頭髮還濕濕的,也跟著衝出來找人,原來這名男子,竟然在游泳池浴室伸手猥褻他!

受害男童母親說:「電話中他就開始哭了,整個崩潰大哭,然後就跟我講說,他摸我的小鳥,然後我把他手撥開。」

男童身心靈受傷,事後打電話給媽媽時崩潰大哭,家人這才知道,他在游泳池遭到猥褻。8日傍晚,這名小六男童跟阿公一起到豐原這間游泳池游泳,結束後在大眾澡堂淋浴時,1名男子突然伸手抓他下體,還告訴他說「你也可以摸我的啊」,男童嚇得大叫阿公求救,男子才嚇得匆忙離開,看到男童跑出浴室,還轉頭警告他不准跟上來。

事後家人帶著男童報警,調閱監視器,男童一眼就認出猥褻男子。警方依照車牌,將他約談到案到案,男子坦承有對男童伸手,被依妨害性自主罪名,函送法辦。

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

窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。

游泳池誤倒不明液體冒白煙 19名幼童急送醫_貨運

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

中和景新國小委外由游泳池晚間發生誤混液體,造成多名幼童不適,環保署人員趕抵檢查現地。(吳家詮翻攝)

新北景新國小外包游泳池,晚間發生誤倒入不明液體,早成多名在場幼童身體不適。(圖摘自Google Map)

新北市中和區景新國小旁一處私人游泳池,晚間現場疑似救生員誤將不明液體倒入泳池產生白煙,造成現場場19名小朋友噁心嘔吐,送新北雙和醫院急救。

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

 

消防局初步了解,現場為伊藤萬游泳晚上6時50分至8時為學校的游泳課程,因工作人員誤將強酸(氯)及強鹼(消毒水)加在一起,故產生化學作用冒煙,引起上課學生身體不適,小朋友分屬不同學校參加游泳課程,目前送醫計有18名,有1名為家長自行送往醫院,消防局救護車載運10女8男(18名),均送往雙和醫院。

 

雙和醫院稍晚表示,另有5名泳池的教練也因身體不適,陸續到院檢查治療。

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

家長疏忽?6歲童飯店獨棟villa泳池溺水 送醫救回_網頁設計公司

※南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

台東縣池上鄉一家五星級渡假村今天傍晚驚傳6歲男童險溺斃別墅型飯店水池,消防人員趕抵,男童已無生命跡象,經送往關山慈濟醫院急救,才恢復心跳和呼吸,住院觀察中。

救護人員緊急將溺水男童送往關山慈濟醫院,經搶救恢復生命跡象。(記者陳賢義翻攝)

※網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

男童溺水水池位於飯店獨棟villa外。(記者陳賢義翻攝)

這起溺水意外發生在今天傍晚5點26分左右,台東縣消防局勤指中心獲報,池上鄉一家五星級渡假村,有個6歲小朋友在飯店房間水池溺水,溺者已救出水池,立即出動池上消防分隊及通報關山高救隊馳援,抵達現場發現是飯店獨棟villa,男童已無生命跡象,施予救護處置,旋即送往關山慈濟急救。

消防單位說,事發當時,男童家長也在附近,可能是疏於注意,才會導致意外發生。警方則說,男童經搶救,恢復心跳和呼吸,但仍須住院觀察,家長是否涉及兒少法或相關刑責,須再調查釐清。

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

誇張!女童泳池溺水瀕死 媽媽低頭玩手機渾不知_租車

※超省錢租車方案

商務出差、學生出遊、旅遊渡假、臨時用車!GO 神州租賃有限公司!合法經營、合法連鎖、合法租賃小客車!

中國河南洛陽近日發生一起離譜案件,一名女童在一處游泳池內游泳,卻發生溺水意外。但誇張的是,她的母親在泳池邊只顧著玩手機,完全不知道自己的孩子已經溺水,隨後有另外一名女泳客發現異狀,立刻救起女童,但女童被救起時,一度失去意識和呼吸。

據中國《看看新聞》報導,事發在本月14日下午,這名女童到泳池玩耍,卻發生溺水意外,但她的媽媽只在泳池邊不斷低頭玩手機,完全不知道自己的女兒出事了。隨後另一名女泳客、高中老師陶曉峰發現了異狀,感覺水底下有人,她立刻將孩子救起,並馬上進行心肺復甦術。

陶曉峰本身也有救生員資格,

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

有別於一般網頁架設公司,除了模組化的架站軟體,我們的營業主軸還包含:資料庫程式開發、網站建置、網頁設計、電子商務專案開發、系統整合、APP設計建置、專業網路行銷。

她立刻為孩子進行急救,但女童一度失去意識和呼吸。但令人驚訝的是,女童的母親只顧著低頭玩手機,完全不知道自己的女兒身陷危險,甚至瀕臨死亡邊緣。等到女童的母親回過神時,才發現女童沒有了意識,在現場大哭。陶曉峰也說,現場由於游泳的人太多,再加上水也不太清澈,「當時感覺水下是一個小孩」。出於本能意識,陶曉峰立刻潛水並將溺水女童拉出水面。

就在陶曉峰急救的同時,消防隊及救難隊也獲報趕抵現場,並將女童送醫急救。經治療好,女童已無大礙,目前正持續接受治療當中。

誇張!女童泳池溺水瀕死,媽媽低頭玩手機渾不知。翻自畫面
女童被救起時一度失去意識和呼吸。翻自畫面
經治療好,女童已無大礙,目前正持續接受治療當中。翻自畫面

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

日本、大陸,發現這些先進的國家已經早就讓電動車優先上路,而且先進國家空氣品質相當好,電動車節能減碳可以減少空污