學習筆記隨記-2019-01-01--01
目錄:
1.學到的知識
1.1 Mybatis中 的動態SQL模糊查詢
模糊查詢的多種寫法:
(1)直接拼接%%
如 ‘%’#{name}’%’ 或 “%”#{name}"%",單引號或雙引號都可以。
結合專案中,寫法如下:
<where>
u.`status`=1
<if test="name != null And name != '%%'">
AND u.`name` LIKE ('%${name}%')
</if>
<if test="roleName != null And name != '%%'">
AND r.role_name LIKE ('%${roleName}%')
</if>
</where>
注意:此處不能寫成 “%#{name}%” ,#{name}就成了字串的一部分,會發生這樣一個異常: The error occurred while setting parameters,應該寫成:
"%"#{name}"%",即#{name}是一個整體,前後加上%
(2)使用concat函式
使用concat(str1,str2)函式將兩個引數連線
<where> u.`status`=1 <if test="name != null" > AND u.`name` LIKE CONCAT('%',#{name},'%') </if> <if test="roleName != null"> AND r.role_name LIKE CONCAT('%',#{roleName},'%') </if> </where>
(3)使用 bind 標籤
對字串進行繫結,然後對繫結後的字串使用 like 關鍵字進行模糊查詢
<where>
u.`status`=1
<if test="name != null" >
<bind name="name" value="'%'+name+'%'"/>
AND name LIKE #{name}
</if>
</where>
Mysql中查詢相關知識拓展:
一般模糊語句如下:
SELECT 欄位 FROM 表 WHERE 某欄位 Like 條件
其中提供了四種匹配模式:
- 1.%:表示任意0個或多個字元。可匹配任意型別和長度的字元;
- _: 表示任意單個字元。匹配單個任意字元,它常用來限定表示式的字元長度語句;
- 3.[ ]:表示括號內所列字元中的一個(類似正則表示式)。指定一個字元、字串或範圍,要求所匹配物件為它們中的任一個;
- 4.[^ ] :表示不在括號所列之內的單個字元。其取值和 [] 相同,但它要求所匹配物件為指定字元以外的任一個字元。
- 注意:
- 查詢內容包含萬用字元時,由於萬用字元的緣故,導致我們查詢特殊字元“%”、“_”、“[”的語句不能正常實現,而把特殊字元用“[ ]”括起便可正常查詢。
疑問1. ${} 與 #{}之間的區別
- 1.#{} 將傳入的資料當做一個字串,會自動對穿入的資料加一個雙引號。
- 2.${} 將穿入的資料直接顯示生成在SQL語句中。
- 3.#{}是預編譯處理,${}是字串替換。
- 4.Mybatis在處理#{}時,會將sql中的#{}替換為?號,呼叫PreparedStatement的set方法來賦值;
綜上,#{} 能防止SQL注入,${}無法防止注入。
拓展:所謂的SQL注入,也就是通過吧SQL命令插入WEB表單提交或者屬於域名或頁面請求的查詢字串,最終達到欺騙伺服器執行惡意的SQL命令。具體來說,它是利用現有應用程式,將(惡意的)SQL命令注入到後臺資料庫引擎執行的能力。比如:影視網站洩露VIP會員密碼大多就是通過WEB表單遞交查詢字元暴出的。這裡先不深入細說。
對於模糊查詢,高效率寫法:
- 1.LOCATE
語法:LOCATE(‘substr’,str,pos)
說明:
若pos不存在,返回substr在str中第一次出現的位置,如果substr在str中不存在,返回值為 0 。
若pos存在,返回substr在str第pos個位置後第一次出現的位置,如果substr在str中不存在,返回值為0。
模糊查詢,SQL寫法:
SELECT `column` FROM `table` WHERE LOCATE('keyword', `field`)>0;
demo:
SELECT
*
FROM
`user`
WHERE
LOCATE( 'a', `name` ) > 0
結果如下:
- 2.POSITION
語法:POSITION(‘substr’ INfield
)
position可以看做是locate的別名,功能跟locate一樣
模糊查詢,SQL寫法:
SELECT `column` FROM `table` WHERE POSITION('keyword' IN `filed`);
demo:
SELECT
*
FROM
`user`
WHERE
POSITION( 'a' IN `name` )
結果如下:
- 3.INSTR
語法:INSTR(str
,‘substr’)
說明:功能跟instr一樣
模糊查詢,SQL寫法:
SELECT `column` FROM `table` WHERE INSTR(`field`, 'keyword' )>0;
demo:
SELECT
-
FROM
`user`
WHERE
INSTR ( `name`, 'a' )> 0
結果如下:
- 4.FIND_IN_SET
語法:FIND_IN_SET(str1,str2)
說明:返回str2中str1所在的位置索引,其中str2必須以","分割開。
模糊查詢,SQL寫法:
SELECT `column` FROM `table` WHERE FIND_IN_SET('keyword', `filed`);
demo:
SELECT
*
FROM
`user`
WHERE
FIND_IN_SET('admin', `name` )
結果如下:
1.2.微服務在伺服器執行自動關閉
基於SpringSecurity + Spring OAuth2 + JWT許可權認證的微服務,考慮本地記憶體不夠,想著先將註冊中心 Eurake 和 授權認證中心 UAA-server先放到伺服器上執行,本地單獨執行 資源中心,遠端呼叫授權中心,緩解本地筆記本記憶體不夠的問題。
2.1.1.本地微服務打成JAR
將 將註冊中心 Eurak-server 和 授權認證中心 UAA-server 打成可執行Jar包。
在這裡,在伺服器上執行遇到兩個問題,記錄一下問題和解決辦法。
- (1)使用 java -jar uaa-service-0.0.1-SNAPSHOT.jar & 執行,會將列印資訊顯示在控制檯。
解決辦法: 將列印的資訊轉移到一個檔案,使用命令如下:
java -jar uaa-service-0.0.1-SNAPSHOT.jar >uaa.txt &
- (2)使用 java -jar uaa-service-0.0.1-SNAPSHOT.jar >uaa.txt &,會讓微服務自動關閉。
檢視日誌,發現關閉點資訊如下:
授權中心 uaa-server 日記記錄:
2018-12-27 23:03:50.445 [32mINFO [0;39m [34m20823[0;39m — [Thread-9 ] [36mo.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext [0;39m : Closing org.springframework.boot.web.ser[email protected]704d6e83: startup date [Thu Dec 27 22:09:24 CST 2018]; parent: org.spring[email protected]3ecf72fd
2018-12-27 23:03:50.447 [32mINFO [0;39m [34m20823[0;39m — [Thread-9 ] [36mo.s.c.n.e.serviceregistry.EurekaServiceRegistry [0;39m : Unregistering application uaa-service with eureka with status DOWN
註冊中心,關閉資訊如下:
2018-12-27 23:03:50.465 INFO 20036 — [nio-8761-exec-6] c.n.e.registry.AbstractInstanceRegistry : Registered instance UAA-SERVICE/izwz9ivjuzijxaguw5ni8kz:uaa-service:7777 with status DOWN (replication=false)
2018-12-27 23:03:50.487 INFO 20036 — [ Thread-15] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.ser[email protected]60c6f5b: startup date [Thu Dec 27 22:08:45 CST 2018]; parent: org.spring[email protected]66048bfd
2018-12-27 23:03:50.488 INFO 20036 — [ Thread-15] o.s.c.n.e.s.EurekaServiceRegistry : Unregistering application unknown with eureka with status DOWN
找到相關資料,原因是 可執行jar啟動方式的問題:
https://stackoverflow.com/questions/35882496/why-does-my-spring-boot-app-shutdown-by-itself
1.2.2 nohup 和 & 的區別
我們知道,當用戶登出(logout)或者網路斷開時,終端會收到 HUP(hangup)訊號從而關閉其所有子程序。因此,我們的解決辦法就有兩種途徑:要麼讓程序忽略 HUP 訊號,要麼讓程序執行在新的會話裡從而成為不屬於此終端的子程序。
所以這就是前面jar在伺服器上執行,只要終端一關閉就會關掉應用程式的問題。
再對下面兩個命令學習下:
- (1)nohup是永久執行
執行 nohup --help
Run COMMAND, ignoring hangup signals. 可以看到是“執行命令,忽略掛起訊號”,然後會發現,nohup執行命令可以使命令永久的執行下去,和使用者終端沒有關係,例如我們斷開SSH連線都不會影響他的執行。 - (2)&是指在後臺執行
&是指在後臺執行,但當用戶推出(掛起)的時候,命令自動也跟著退出。
所以這也就是 退出終端之後,服務會自動關閉的問題。 - 綜上,永久的在後臺執行的命令為: nohup COMMAN
使用命令如下:
java -jar eureka-server-0.0.1-SNAPSHOT.jar >nohup command > eureka.txt 2>&1 & - 解析: 2>&1
command >out.file 2>&1 &
command>out.file是將command的輸出重定向到out.file檔案,即輸出內容不列印到螢幕上,而是輸出到out.file檔案中。
2>&1 是將標準出錯重定向到標準輸出,這裡的標準輸出已經重定向到了out.file檔案,即將標準出錯也輸出到out.file檔案中。最後一個&, 是讓該命令在後臺執行。
試想2>1代表什麼,2與>結合代表錯誤重定向,而1則代表錯誤重定向到一個檔案1,而不代表標準輸出;換成2>&1,&與1結合就代表標準輸出了,就變成錯誤重定向到標準輸出.
1.2.3 disown
場景:
我們已經知道,如果事先在命令前加上 nohup 或者 setsid 就可以避免 HUP 訊號的影響。但是如果我們未加任何處理就已經提交了命令,該如何補救才能讓它避免 HUP 訊號的影響呢?
解決方法:
這時想加 nohup 或者 setsid 已經為時已晚,只能通過作業排程和 disown 來解決這個問題了。讓我們來看一下 disown 的幫助資訊:
disown [-ar] [-h] [jobspec …]
靈活運用 CTRL-z
在我們的日常工作中,我們可以用 CTRL-z 來將當前程序掛起到後臺暫停執行,執行一些別的操作,然後再用 fg 來將掛起的程序重新放回前臺(也可用 bg 來將掛起的程序放在後臺)繼續執行。這樣我們就可以在一個終端內靈活切換執行多個任務,這一點在除錯程式碼時尤為有用。因為將程式碼編輯器掛起到後臺再重新放回時,游標定位仍然停留在上次掛起時的位置,避免了重新定位的麻煩。
用disown -h jobspec來使某個作業忽略HUP訊號。
用disown -ah 來使所有的作業都忽略HUP訊號。
用disown -rh 來使正在執行的作業忽略HUP訊號。
需要注意的是,當使用過 disown 之後,會將把目標作業從作業列表中移除,我們將不能再使用jobs來檢視它,但是依然能夠用ps -ef查詢到它。
但是還有一個問題,這種方法的操作物件是作業,如果我們在執行命令時在結尾加了"&"來使它成為一個作業並在後臺執行,那麼就萬事大吉了,我們可以通過jobs命令來得到所有作業的列表。但是如果並沒有把當前命令作為作業來執行,如何才能得到它的作業號呢?答案就是用 CTRL-z(按住Ctrl鍵的同時按住z鍵)了!
CTRL-z 的用途就是將當前程序掛起(Suspend),然後我們就可以用jobs命令來查詢它的作業號,再用bg jobspec來將它放入後臺並繼續執行。需要注意的是,如果掛起會影響當前程序的執行結果,請慎用此方法。
學習連結:
https://www.ibm.com/developerworks/cn/linux/l-cn-nohup/index.html