後端框架學習筆記

1.運行過程html

WishList(Domain)-->WishListMapper(DAO)-->WishListService(Service)-->WishListController(Controller)
以上是從原型定義到mybatis的Mapper文件定義,再到提供服務,而後提供接口和結果的過程。前端

2.@Param參數java

在定義mybatis的mapper文件或者定義基於註解的sql語句時候,使用@Param註解,以下:mysql

@Select("SELECT id, user_id, item_id, add_price, add_time, created, updated FROM" +"user_collection_info WHERE user_id= #{userId} AND item_id= #{itemId, jdbcType=BIGINT}")
List<WishList> getWishListItemByItemId(@Param("userId") long userId, @Param("itemId") long itemId);

@Param後的字段和#{}之中的內容對應,select選擇的是數據庫之中的字段,後面的#{itemId}能夠自由命名,只要在@Param之中對應起來就行。linux

3.IDEA的幾個縮寫git

psvm=補全main函數
fori =for循環
sout =System.out.println();程序員

4.接口,參數,請求等之間的關係web

接口的請求:接口分爲通常接口和分佈式接口(如Dubbo接口),通常的隨便調用,Dubbo接口主要是爲了在分佈式環境下提供服務,能夠在不一樣的機器之間調用(RPC);返回的數據格式:調用了接口以後,返回的數據通常是json格式的,可是其中的具體內容,還須要和前端商討,返回的數據究竟是什麼格式;參數的傳遞:在Http的Get請求下,所須要的數據能夠經過URL上經過http://localhost:8080/wishlist/getMarkList?userId=2&pageSize=10&pageStart=0 ?參數1=值1&參數2=值2&...這種方式爲參數賦值,咱們能夠經過url給controller中調用的方法的參數賦值,此時controller方法參數的名字和url之中的參數的名字要相同,不然取不到值。而對於Http的Post請求,咱們是無法看到對應的頁面的,傳遞參數的方式是同樣的,須要藉助工具實現,如postman來發送post請求。一個「悖論」是,咱們須要的參數經過url傳遞,可是應該也有其餘方式傳遞,好比我提交了註冊按鈕,而後,通常而言不會跳轉到一個新的頁面,應該是直接取到後臺返回的結果,而後在本頁刷新便可,也就是說,url在取得參數數據以後這種狀況是Post請求的狀況,而Get請求是相對應起來的),這種狀況是針對於Post請求的,能夠把Post請求理解爲在後端進行,不須要對應的頁面便可。字段的對應關係:還有在contorller, service, mapper, url和數據庫之中字段的對應關係,mappr和數據庫對應,url和controller對應,其餘地方沒有明確的要求,定義統一和方便本身查找便可,對於時間的處理,通常不寫在函數的參數請求之中,而直接在SQL中操做ajax

5.微服務redis

不能我去查找別人的,我沒有權限的數據庫字段,不是個人模塊,對我而言,我是看不到的,我須要的數據我沒法直接獲取的時候,我須要調用別人提供給個人接口,通常而言,我只須要在這些數據之中找到我要的部分,而後將其組裝,就能夠了。簡言之:不是個人,我沒法直接操做底層(數據庫),只能經過調用別人的提供的接口,來獲取我須要的內容

6.幾個常見的術語

關鍵詞 名稱 術語
api接口 Service接口 service
Model 接口 model
實現類 Mapper 接口 dao
Model POJO類 domain/model
Service/Serviceimpl Service實現類 service
Controller 調用類 controller

7.異常處理和日誌

異常處理通常在service層處理,須要處理的時候處理,返回相應的result(通常是Json格式),日誌的話通常是使用logback,常量常數的話通常不是直接使用1,0這種表示,而是將其定義爲常量,這樣更有含義,明確。

8.數據來源

我本身管理的數據庫表,只有一部分我須要的數據,可是其餘的部分在別人的數據庫表之中,我怎麼拿到所有我想要的數據呢?通常的思路是這樣的:在分佈式的系統和微服務的架構下我沒法直接操道別人的數據庫,沒法直接經過操道別人數據庫的方式來得到數據,因此只能經過別人提供的服務接口來得到數據,而後經過和我本身的一部分數據,經過必定的條件查詢,拼裝組合出我想要的數據。通常而言,在mybatis之中,須要定義好一個組裝成的數據的Model,而後直接將數據填充到Model的對象之中去。

9.IDEA調試快捷鍵

模式 做用
F7 Debug 進入斷點方法之中
F8 Debug 不進入斷點,越過斷點直接給出結果
F9 Debug 恢復程序運行
Alt + F8 Debug 彈出可輸入表達式的計算框
Ctrl + F8 Debug / Common 設置/清除斷點
Shift + F7 Debug 智能步入,會讓你選擇一個進入的方法
Shift + F8 Debug 跳出,恢復程序運行,=F9
Ctrl + Shift + F8 Debug 設置斷點的進入條件
Alt + Shift + F7 Debug 進入嵌套的方法之中

10.IDEA的Debug使用

① 以下圖 Gif 所示,查看所選對象的方法經常使用有三種方式:

  • 選中對象後,使用快捷鍵 Alt + F8
  • 選中對象後,拖動對象到 Watches
  • 選中對象後,鼠標懸停在對象上 2 秒左右。
  • 想看對象的具體內容,選中之中,使用Ctrl + F1,查看對象具體內容。

img1

img6

② 以下圖 Gif 所示,在彈出表達式輸入框中 IntelliJ IDEA 也是能幫咱們智能提示。
img2

③ 以下圖 Gif 所示,當咱們須要過掉後面的全部斷點的時候,咱們不須要去掉這些斷點,只須要點擊左下角那個小圓點,點擊小圓點以後,全部斷點變成灰色,而後咱們再在按快捷鍵 F9 便可過掉當前和後面全部的斷點。
img3

④ 以下圖 Gif 所示,咱們能夠給斷點設置進入的條件,由於變量 temp3 不等於 200 因此該斷點沒有被進入直接跳過。
img4

⑤ 如 下圖Gif 演示,有時候當咱們步入方法體以後,還想回退到方法體外,斷點進入 addNum 方法後,點擊 Drop Frame 按鈕以後,斷點從新回到方法體以外。
img5

11.mybatis 到底要不要寫一對多、一對一關聯?

  • 方法1
    • Dao 層有一對多、一對一關聯
    • Service 層寫業務邏輯
  • 方法2
    • Dao 層不寫一對多、一對一關聯,只提供基本的增刪查改
    • Service 層完成關聯查詢等以及寫業務邏輯

方法1在效率上貌似有優點,但寫 resultMap 和語句真是不開心
方法2對程序員比較友好,但效率不如方法一,並且 service 層會比較臃腫

12.日誌的配置,以及其含義

1.Log4j的配置, 2.log4j的使用--IDEA建立maven項目

13.gitflow簡單的操做

gitflow簡單的操做

14.Spring MVC之中出現:No mapping found for HTTP request with URI

A:關於No mapping found for HTTP request with URI..., DID NOT FIND HANDLER METHOD FOR SPRINGMVC資源文件掃描不到---關於SPRING的那些坑

15.springmvc能夠對前臺返回json數據,也能夠從前臺獲取JSON格式的數據, 固然,JSON格式只是最經常使用的一種格式,還有不少其餘的格式,後臺給前端返回json數據相對簡單,而前臺給後臺發送JSON格式數據的時候,就須要注意,咱們要使用AJAX來幫助(jquey的ajax)便可.此時,必定要搞清楚方向的問題,是前端發送json數據到後臺,因此這個發送時從前端發給後臺,就是從前端瀏覽器之中發起請求,在web服務器如tomcat運行的時候,後臺會接收到這個請求,得到參數,而後纔去相應的措施.
1.springmvc 接收json對象的兩種方式, 2.Java運用JSON實現後臺與前端分工合做(代碼實例), 3. SpringMVC——對Ajax的處理(包含 JSON 類型), 4.SpringMVC @RequestBody 處理ajax請求, 5. ajax請求,fastjson報出錯誤:syntax error, expect {, actual error, pos 0, 6.springmvc與fastjson的整合,註解@RequestBody的使用

16.表單form簡介

基本語法

<FORM ACTION="URL" METHOD="GET|POST" ENCTYPE="MIME" TARGET="...">
... ... 
</FORM>

基本功能
表單在網頁中主要負責的是數據採集功能,一個表單基本由三部分組成

  • 表單標籤:這裏麪包含了處理表單數據所用 CGI (Common Gateway Interface,通用網關接口)程序的 URL (Uniform Resource Location,統一資源定位符)以及數據提交到服務器的方法.
  • 表單域:包含了文本框、密碼框、隱藏域、多行文本框、複選框、單選框、下拉選擇框和文件上傳框等。
  • 表單按鈕:包括提交按鈕、復位按鈕和通常按鈕;用於將數據傳送到服務器上的CGI腳本或者取消輸入,還能夠用表單按鈕來控制其餘定義了處理腳本的處理工做.

兩個參數

17.前端和後端的感悟

A:form之中的action,對應的不是一個獲取到的地址, 而是將數據傳送, 而後讓其處理問題的地址, 即push! form之中的表單信息提交給Spring MVC之中RequestMapping之中的url進行處理,是的! 可是,爲何此處沒有得到那邊傳過來的數據呢??? 其實,意思就是,應該是後端的數據綁定到了前端, 仍是說前端的數據傳遞到了後端?---> 我想,確定是前端的數據,傳到了後端,而傳值得方式,是經過前端和後端都有,可是在後端定義的數據模型,id,來完成的. 就是說,在後端定義了一個模型, key在後端定義好了, 可是value須要前端傳過來, 給後端, 通過後端處理, 而後顯示出來.

18.關於form標籤的path和commandName

form標籤之中的path,commandName(modelAttribute)的來源,path就是我須要的一個值的對應的Domain(Model,POJO)類之中的相應的字段,commandName(modelAttribute)就是在Controller之中定義的Model(ModelMap, ModelAndView)對應的Model的key。此處須要理清楚數據綁定的對象,數據綁定的方向。

19.Spring MVC先後端數據交互

A:1.Spring MVC先後端數據交互總結, 2.Spring MVC 後端獲取前端提交的json格式字符串並直接轉換成control方法對應的參數對象, 3.Spring MVC 傳值方式總結, 4.SpringMVC前端傳值到Controller與Controller中傳值到View解析, 5.Spring 向頁面傳值以及接受頁面傳過來的參數的方式

20.JSP頁面使用a href來跳轉到另外一個jsp頁面

A:Spring MVC貌似不支持從一個jsp頁面經過<a href="sss.jsp">的方式跳轉,都要經過controller的方式訪問頁面

21.視圖配置的時候,能夠設置多個文件夾嗎?能夠配置多種視圖後綴嗎?

A: ViewResolver能夠設置多個,不一樣的ViewResolver類型,須要設置不一樣的ViewResolver,好比jspViewResolver,htmlViewResolver等。至於某一種視圖的多個文件夾,能夠在/WEB-INF/views/之中設置,能夠設置到不一樣級別的文件夾之中,可是這樣不靈活,通常都是返回的時候,返回其父級別的文件夾名,好比以前的爲/WEB-INF/views/,返回的時候使用的是return "login",好比修改成/WEB-INF/views/user以後,那就須要使用user/login來返回,寫全就是:return "user/login",若是要訪問其餘的,新的網頁,則可使用「user/XXX」,那麼就是同一視圖的多個文件夾的訪問方式,而不一樣的ViewResolver,通常時將其頁面放在不一樣的頁面之下。1. springmvc如何設置多視圖器,springmvc 多個 ViewResolver, 2.SpringMVC同時支持多視圖(JSP,Velocity,Freemarker等)的一種思路實現

22.Spring MVC之中form標籤,jstl標籤,sf標籤,el表達式,各自使用在什麼地方而且有什麼區別?

A:JSTL的全名爲:Java Server Pages Standard Tag Library。JSP標準標籤庫,由四個定製標記庫(core、format、xml 和sql)和一對通用標記庫驗證器(ScriptFreeTLV 和 PermittedTaglibsTLV)組成。它實現了迭代和條件判斷、數據管理格式化、XML操做以及數據庫訪問的功能。有了jstl標籤庫和el表達式,咱們的 jsp中不須要<%%>的java代碼,提升了程序的可讀性和可維護性

EL(Expression Language)表達式:目的是爲了使JSP寫起來更加簡單。語法結構:${expression}; 對象:pageScope、requestScope、sessionScope、applicationScope(訪問順序:page—request—session——application)

form標籤是SpringMVC的核心標籤,以下的表達式中,tablib是咱們給此標籤庫設置的名字,能夠爲任意不重複的名字,固然決定此標籤庫的仍是URI,URI惟一決定此標籤庫,因此以下的標籤庫能夠叫sf,也能夠叫form

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

除了Spring標籤,JSTL標籤,還有Strutsde 標籤等等。而EL表達式只是爲了方便使用而存在的

區別尚未寫

23.Spring MVC的模板技術有哪些?

A:模板技術有JSP, Velocity, freemarker和Thymeleaf模板,JSP開發對於MVC是破壞的,然後面三種是MVC模式的,不會在視圖之中直接寫java代碼,而jsp會寫java代碼,而後編譯成servlet,佔用JVM的堆大小,會有GC的產生。Velocity, freemarker和Thymeleaf支持MVC開發模式,先後端分離,之間的差異不是很是大,Spring官方推薦的是Thymeleaf模板淺談jsp、freemarker、velocity區別

24.Spring MVC後端傳給前端值,怎麼傳,有哪些方法?

A:

25.Spring MVC前端傳給後端值,怎麼傳,有哪些方法?

A:

26.spring的jsp類庫有哪些?<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>的含義和說明

A:taglib之中的prefix是一個必要的參數,這個是本身定義的,能夠是任何和已有的標籤縮寫不重複的標籤前綴,可是重點在於後面的URI,這是惟必定位一個標籤庫的方式。 Spring的標籤,有form部分和其餘部分,這個form是爲了數據綁定而設置的,Spring的標籤,主要是使用form,其餘的標籤在tags下面,用的不是不少

27.spring的jsp類庫有哪些?

A:Spring提供了兩個JSP標籤庫,用來幫助定義SpringMVC Web的視圖。其中一個標籤庫會用來渲染HTML表單標籤,是from標籤,這些標籤能夠綁定model中的某個屬性。另一個標籤庫包含了一些工具類標籤,咱們隨時均可以很是便利地使用它們。在這兩個標籤庫匯中,表單綁定的標籤庫更加有用。咱們更多使用的是表單標籤,表單標籤所在的位置爲:
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>,而工具類標籤爲
<%@taglib uri="http://www.springframework.org/tags" prefix="sf"%>。1.SpringMVC入門之七:使用JSP做爲視圖, 2.Spring MVC 頁面渲染( render view ), 3.SpringMVC入門之五:渲染Web視圖概述

28: spring form之中的標籤,能夠卸載spring:form以外嗎?也就是說,能在form以外單獨應用嗎?

A: 是不能的,spring jsp的表單form標籤之中的子元素,如<form:input>,<form:checkouboxs>等,都是須要在form標籤之下才能起做用的,因此spring jsp的表單form標籤之中的子元素必需要包含在form打的標籤之中,在標籤以外就會報錯

29.Spring MVC的默認視圖解析器是什麼?

A:當視圖爲jsp的時候,默認的視圖解析器爲InternalResourceViewResolver,默認的viewClass爲JstlView,通常的配置爲:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView />
</bean>

30.爲何經過mybatis執行sql語句,一開始能夠成功,可是後續執行返回結果爲0?

A:這主要是由於數據過小,而查詢的時候沒法直接顯示出來數據的緣由,好比,刪除的時候使用id和item_id,在一開始的時候都是1,2,3這種數據,可是購物車id主鍵和商品的id的增加是不一樣步的,因此就會產生數據不一樣步的緣由,此時的表現是,sql語句能夠執行,可是返回受影響的行數結果爲0。這類問題大可能是因爲粗枝大葉,把字段搞錯了!解決這些問題的方法以下:

  • 查看sql日誌
    • 調到debug狀態img
    • 查看參數img
  • sql參數檢查
    img
  • Rap2接口聲明查看
  • mybatis語法測試

31.IDEA忽然標紅,怎麼處理?

A:通常是因爲緩存致使的,表現爲各個類都沒法識別,可是仍然能夠運行,此時只須要清理緩存便可。img

32.mybatis之中動態SQL的做用?
A:當咱們使用mybatis對一張表進行的CRUD操做,若是業務簡單,那麼SQL語句都比較簡單,若是有比較複雜的業務,咱們須要寫複雜的SQL語句,每每須要拼接,而拼接 SQL,稍微不注意,因爲引號,空格等缺失可能都會致使錯誤。
那麼怎麼去解決這個問題呢?就須要使用mybatis的動態SQL,經過if, choose, when, otherwise, trim, where, set, foreach等標籤,可組合成很是靈活的SQL語句,從而在提升 SQL 語句的準確性的同時,也大大提升了開發人員的效率

33.@Results,@Result的做用是什麼?
A:@Results, 對應<resultMap>表示的是結果映射的列表,包含了一個特別結果列如何被映射到屬性或字段的詳情。屬性爲value,@Result是@Results註解的結果數組之中的一條結果,@Results註解產生一個對應的結果數組。

34.嵌入在mybatis動態SQL語句之中的<script>,<CDATA>等標籤的做用?
A:用script標籤包圍,而後像xml語法同樣書寫,很明顯,在java中寫xml可讀性和維護性太差,尤爲當SQL很長時,這樣寫是很痛苦的。 <script>,<CDATA>這些標籤是xml之中的標籤,咱們通常寫sql的時候不用這麼寫,須要注意標點,鏈接符等便可。寫簡單的SQL,結果拼接,而不是拼接SQL

@Select("<script>" +
            "SELECT id,sn,user_id,wechat_id,alipay_id,item_id,item_value,mobile," +
            "oilcard_num,oilcard_name,recharge_value,bean_award_value,payment_value,status," +
            "payment_time,order_time,created,updated " +
            " FROM oilcard_recharge_record "+
            "<where>" +
            "<if test=\"status !=null \"> and status = #{status}</if>" +
            "<if test=\"createdStart !=null \"> and created <![CDATA[ > ]]> #{createdStart}</if>" +
            "<if test=\"createdEnd !=null \"> and created <![CDATA[ < ]]> #{createdEnd}</if>" +
            "</where>" +
            "order by order_time desc " +
            "</script>")
    List<OilCardRechargeRecord> listByStatus(@Param("status") Integer status,
                                             @Param("createdStart") Long createdStart,
                                             @Param("createdEnd") Long createdEnd);

sql中有一些特殊的字符的話,在解析xml文件的時候會被轉義,<CDATA>能避免被轉義mybatis 詳解(五)------動態SQLXML CDATA,"![CDATA[","<script>"這些字符在動態sql的語句之中的做用是:防止sql裏面出現諸如"<"、"&"這種XML非法字符的狀況 MyBatis動態SQL實現ORDER BY和LIMIT的控制?

注意

有時候,只使用單純的sql語句,在使用動態語句的時候,就會出現沒法正確解析SQL的狀況,好比說,使用<if>語句的時候,在"<if test=\"topic.status != null\" >status = #{topic.status},</if>"這種狀況的時候就會出現問題,因此最外層須要使用<script>包起來。另外status = #{topic.status}這句,不能將#和{}分開,好比status = # {topic.status},這種就會出現錯誤。當if的條件只有一句的時候,後面不能加","。好比有

sql lite // 只有一個參數的時候,不能加逗號","---><if test=\"status !=null\"> status = #{status},</if> @Select("<script>" + "SELECT " + "id, topic_name, topic_introduce " + "FROM article_topic" + "<where>" + "<if test=\"status !=null\"> status = #{status}</if>" + "</where>" + "</script>") List<ArticleTopic> getTopicNumber(@Param("status") int status);

在插入語句之中,也可使用動態條件,以下:

sql lite // 須要添加<script>,不然沒法正確解析<if...>的內容,在insert的時候也可使用<if...> @Insert("<script>" + "INSERT INTO " + "article_topic (id, topic_name, topic_introduce, sort," + "<if test=\"topicImg !=null \"> topic_img,</if> " + "<if test=\"topicThumbnail !=null \"> topic_thumbnail,</if> " + "status, created, updated)" + "VALUES" + "(#{id}, #{topicName}, #{topicIntroduce}, #{sort}, " + "<if test=\"topicImg !=null \"> #{topicImg},</if> " + "<if test=\"topicThumbnail !=null \"> #{topicThumbnail},</if> " + "#{status}, #{created}, #{updated})" + "</script>") @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") long addTopic(ArticleTopic topic);

通常狀況下,更新,插入的時候,須要使用到對象,在此時,咱們的字段就須要帶對象的名稱,可是在佔位符之中,不須要設置對象名,以下:

@Update("<script>"
            + "UPDATE article_topic"
            + "<set>"
            + "<if test=\"topic.status !=null\"> status = #{topic.status},</if>"
            + "<if test=\"topic.updated !=null\"> updated = #{topic.updated},</if>"
            + "</set>"
            + "<where>"
            + "id = #{id}"
            + "</where>"
            + "</script>")
    long stickyTopic(@Param("topic") ArticleTopic topic, @Param("id") long id);

35.註解,providersql,mapper.xml等方式的異同?
A:註解,providersql,mapper.xml三種方式都是要產生對應的查詢結果,註解方式更加集中,把DAO方法,SQL語句,集中在了一個Java接口之中,方便,可是每次有改動,必需要完整的改動這個接口文件。
providersql和mapper.xml方式比較類似,providersql方式,將sql語句與DAO方法的接口文件分離,使用反射,提供了sql語句的調用,DAO方法和SQL語句是分離的。
mapper.xml方式一樣是分離的,可是在mapper.xml之中,咱們能夠定義各類resultMap,能夠重複利用,利用效率比較高,可是寫起來比較麻煩。

36:動態sql標籤
A:MyBatis的動態SQL是基於OGNL表達式的,它能夠幫助咱們方便的在SQL語句中實現某些邏輯。MyBatis中用於實現動態SQL的元素主要有:if, where, set, choose(when,otherwise), trim, foreach. 咱們在通常是在可能產生不肯定條件的地方使用動態SQL的標籤,如在where, update的set之中使用動態標籤。

if是一個基本的標籤,

<if test="條件"> id=#{id} </if>

也能夠if+where組合,

<where>
    <if test="條件1"> id=#{id} </if> 
    <if test="條件2"> name=#{name}</if>
</where>

update的<set> 標籤,

<set>
    <if test="條件1">  id=#{id} </if> 
    <if test="條件2">  name=#{name}</if>
</set>

有時候,咱們不想用到全部的查詢條件,只想選擇其中的一個,查詢條件有一個知足便可,使用 <choose> 標籤能夠解決此類問題,相似於Java的switch語句

<where> 
    <choose> 
        <when test="條件1">  id=#{id}  </when> 
        <when test="條件2">  name=#{name}  </when> 
        <otherwise> and age=#{sex}  </otherwise>
    </choose> 
</where>

trim標記是一個格式化的標記,能夠完成set或者是where標記的功能,在sql其中,添加了一些如分隔符,前綴後綴等的信息。能夠對應更多的狀況,而foreach更多的是sql之中的in狀況,例如id in(id的一個查詢獲得的結果集合)

<select id="selectUserByListId" parameterType="com.ys.vo.UserVo" resultType="com.ys.po.User">
    select * from user
    <where>
        <!--
            collection:指定輸入對象中的集合屬性
            item:每次遍歷生成的對象
            open:開始遍歷時的拼接字符串
            close:結束時拼接的字符串
            separator:遍歷對象之間須要拼接的字符串
            select * from user where 1=1 and (id=1 or id=2 or id=3)
          -->
        <foreach collection="ids" item="id" open="and (" close=")" separator="or">
            id=#{id}
        </foreach>
    </where>
</select>

37:Mybatis的Insert Update和Select Delete語句的注意點

A:當咱們使用SQL進行insert和update的時候,在Mybatis之中,使用的是對象,而非一個一個的單獨的參數,在Mapper之中,對應的參數爲id和對應的對象,而delete和select的時候大多數使用的是id或者其餘合適的條件。Mybatis純註解方式

@Insert("<script>"
        + "INSERT INTO "
        + "article_topic (id, topic_name, topic_introduce, sort,"
        + "<if test=\"topicImg !=null \"> topic_img,</if> "
        + "<if test=\"topicThumbnail !=null \"> topic_thumbnail,</if> "
        + "status,  created,  updated)"
        + "VALUES"
        + "(#{id}, #{topicName}, #{topicIntroduce}, #{sort}, "
        + "<if test=\"topicImg !=null \"> #{topicImg},</if> "
        + "<if test=\"topicThumbnail !=null \"> #{topicThumbnail},</if> "
        + "#{status}, #{created}, #{updated})"
        + "</script>")
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
long addTopic(ArticleTopic topic);

上面是Insert語句的狀況,在addTopic方法之中,參數是ArticleTopic的對象topic,Update的狀況和Insert相同,另外當咱們使用SqlProvider的時候,Insert和Update的參數都寫在對應的Values和Set的String參數之中,參數和佔位符相對應。以下的示例,分別對應爲Mapper文件和SqlProvider文件

@InsertProvider(type = ArticleCommentReviewSqlProvider.class, method = "reviewComment")
long reviewComment(@Param("commentReview") ArticleCommentReview commentReview, @Param("id") long id);

@UpdateProvider(type = ArticleCommentReviewSqlProvider.class, method = "reviewCommentAgain")
long reviewCommentAgain(@Param("commentReview") ArticleCommentReview commentReview, @Param("id") long id);
public String reviewComment(@Param("commentReview") ArticleCommentReview commentReview, @Param("id") long id) {
    //insert時,cloumn和對應的參數都寫在sql.VALUES()之中,參數和佔位符一一對應
    SQL sql = new SQL();
    sql.INSERT_INTO("article_comment_review");
    sql.VALUES(
            "comment_id, article_id, reviewer_id, review_detail, review_time,"
                    + " review_result, created, updated",
            "#{commentId}, #{articleId}, #{reviewerId}, #{reviewDetail},#{reviewTime}, "
                   + "#{reviewResult}, #{created}, #{updated}");
    return sql.toString();
}

public String reviewCommentAgain(@Param("commentReview") ArticleCommentReview commentReview, @Param("id") long id) {
    //update時,column和對應的參數都寫在sql.SET之中,參數和佔位符一一對應
    SQL sql = new SQL();
    sql.UPDATE("article_comment_review");
    sql.SET("review_detail, review_result", "#{reviewDetail}, #{reviewResult}");
    sql.WHERE("id= #{id}");
    return sql.toString();
}

以上這是在Mapper(DAO層)之中的定義,而在Service層和Controller層,咱們仍是須要整個完整的參數

38:SQL分頁的問題
A:SQL的分頁,咱們可使用limit關鍵字或者limit&offset兩個關鍵字組合來完成分頁的實現,可是使用這兩個關鍵字的時候是有區別的。示例以下:

1️⃣:僅使用limit關鍵字,limit N只返回符合條件的前N條

###### sql的數據計算是從0開始的,第1條的下標爲0) #####
SELECT * FROM article_topic LIMIT 10; # 符合條件的前10條
SELECT * FROM article_topic WHERE id<100 LIMIT 10; # 符合條件的前10條,這句和上面一句的含義相同

2️⃣:使用limit關鍵字,limit M , N跳過M條,返回N條,從第M條開始讀取

SELECT * FROM article_topic LIMIT 2,1; # 跳過2條取出1條數據,LIMIT後面是從第2條開始讀,讀取1條信息,即讀取第2條數據,也就是第三條
SELECT * FROM article_topic LIMIT 8,5; # 跳過8條,取出5條,從第8條開始讀取
SELECT * FROM article_topic WHERE id<100 LIMIT 8,5;

3️⃣:使用limit&offset關鍵字,limit M offset N跳過N條,返回M條,從第N條開始計算

SELECT * FROM article_topic LIMIT 2 OFFSET 1; # 返回2條數據,從第1條開始計算,LIMIT後面跟的是2條數據,OFFSET後面是從第1條開始讀取,即讀取第2,3條
SELECT * FROM article_topic LIMIT 10 OFFSET 5; # 返回10條數據,從第5條開始計算

其中第2️⃣種和第3️⃣種之間的關係是相反的,最好統一使用第三種: limit M offset N, 返回M條(跳過N條),從第N條開始計算。sql 中 limit 與 limit,offset連用的區別, SQL 語句的LIMIT的用法

39:sql語句定義和查詢時候的一些問題

A:1️⃣:全部的字段最好不要設置成NULL,能夠設置爲NOT NULL,爲其設置一個默認值,經過DEFAULT xxx
2️⃣:將字段定義爲BIGINT,INT等數字的時候,若是其大於0,那麼能夠加一個UNSIGNED來修飾,這樣就不會有小於0的狀況,表示無符號,只有咱們認爲的大於0的狀況存在,沒有負數的存在了
3️⃣:給字段和表添加註釋是一個好習慣COMMENT '建立時間',
4️⃣:在建立數據庫的語句以前,最好加上DROP TABLE IF EXISTS xxx表;
5️⃣:在建立SQL的語句之中,所使用的引號都是單引號---'',而不是雙引號
6️⃣:爲了區別SQL語句和咱們建立或者查詢的字段,能夠把SQL保留字,所有大寫,自定義的代表,數據等小寫
一個建立表的例子

# article_info
DROP TABLE IF EXISTS article_info;
CREATE TABLE article_info (
  id  BIGINT(20) UNSIGNED NOT NULL  AUTO_INCREMENT  COMMENT '主鍵',
  topic_id  BIGINT(20) UNSIGNED NOT NULL  COMMENT '專題id',
  user_id  BIGINT(20) UNSIGNED NOT NULL  COMMENT '編輯人id',
  title  VARCHAR(64)  NOT NULL  COMMENT '標題',
  introduce_detail VARCHAR(64)  NOT NULL  DEFAULT ''  COMMENT '推薦詞',
  author  VARCHAR(64)  NOT NULL  COMMENT '做者',
  content  TEXT  NOT NULL  COMMENT '文章內容',
  main_img  VARCHAR(300)  NOT NULL  DEFAULT '' COMMENT '主圖 url',
  thumbnail_img  VARCHAR(300)  NOT NULL  DEFAULT '' COMMENT '縮略圖url',
  status  TINYINT(4)  NOT NULL  DEFAULT 0 COMMENT '狀態(待審覈,經過,不經過,發表,下架)',
  release_time  BIGINT(11)  UNSIGNED NOT NULL  DEFAULT 0 COMMENT '發表時間',
  off_time   BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0  COMMENT '下架時間',
  sort  int UNSIGNED NOT NULL  DEFAULT 0 COMMENT '排序',
  created  BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0  COMMENT '建立時間',
  updated  BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0  COMMENT '更新時間',
  PRIMARY KEY (id),
  INDEX idx_article_info_topic_id  (topic_id),
  INDEX idx_article_info_user_id  (user_id)
)DEFAULT CHARSET = utf8  COMMENT = '文章表';


# article_collect
DROP TABLE IF EXISTS article_collect;
CREATE TABLE article_collect (
  id  BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT  COMMENT ' 主鍵',
  user_id  BIGINT(20) UNSIGNED NOT NULL  COMMENT '用戶id',
  article_id BIGINT(20) UNSIGNED NOT NULL  COMMENT '文章id',
  created  BIGINT(20) UNSIGNED NOT NULL DEFAULT 0  COMMENT '建立時間',
  updated  BIGINT(20) UNSIGNED NOT NULL DEFAULT 0  COMMENT '更新時間',
  PRIMARY KEY (id),
  INDEX idx_article_collect_user_id(user_id),
  INDEX idx_article_collect_article_id(article_id),
  UNIQUE idx_union_unique(user_id,article_id)
)DEFAULT CHARSET = utf8  COMMENT = '文章收藏表';


# article_thumb
DROP TABLE IF EXISTS article_thumb;
CREATE TABLE article_thumb(
  id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  user_id BIGINT(20) UNSIGNED NOT NULL COMMENT '用戶id',
  article_id BIGINT(20) UNSIGNED NOT NULL COMMENT '文章id',
  created BIGINT(11) UNSIGNED DEFAULT 0 COMMENT '建立時間',
  updated BIGINT(11) UNSIGNED DEFAULT 0 COMMENT '更新時間',
  PRIMARY KEY (id),
  INDEX  idx_article_thumb_user_id(user_id),
  INDEX  idx_article_thumb_article_id(article_id)
) DEFAULT CHARSET =utf8 COMMENT = '文章點贊表';


# article_area
DROP TABLE  IF EXISTS article_area;
CREATE TABLE article_area (
  id BIGINT(20) UNSIGNED NOT NULL  AUTO_INCREMENT COMMENT '主鍵',
  area_id BIGINT(20)  UNSIGNED NOT NULL  COMMENT '地區id',
  article_id BIGINT(20) UNSIGNED NOT NULL  COMMENT '文章id',
  created BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0 COMMENT '建立時間',
  updated BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0 COMMENT '更新時間',
  PRIMARY KEY (id),
  INDEX  idx_article_area_article_id(article_id),
  INDEX  idx_article_area_area_id(area_id)
)DEFAULT CHARSET =utf8 COMMENT ='文章地區表';


# article_review
DROP TABLE IF EXISTS article_review;
CREATE TABLE article_review(
  id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  article_id BIGINT(20) UNSIGNED  NOT NULL COMMENT '文章id',
  reviewer_id BIGINT(20) UNSIGNED NOT NULL COMMENT '審覈人id',
  review_detail VARCHAR(200) NOT NULL  DEFAULT '' COMMENT '審覈說明',
  review_time BIGINT(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '審覈時間',
  review_result TINYINT(4) UNSIGNED NOT NULL  COMMENT '審覈結果',
  created BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0 COMMENT '建立時間',
  updated BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0 COMMENT '更新時間',
  PRIMARY KEY (id),
  INDEX  idx_article_area_article_id(article_id)
)DEFAULT  CHARSET =utf8 COMMENT ='文章審覈表';


# article_topic
DROP  TABLE IF EXISTS article_topic;
CREATE  TABLE  article_topic(
  id BIGINT(20) UNSIGNED NOT NULL  AUTO_INCREMENT COMMENT '主鍵',
  topic_name VARCHAR(50) NOT NULL  COMMENT '專題名',
  topic_introduce VARCHAR(200) NOT NULL  DEFAULT '' COMMENT '專題簡介',
  sort int UNSIGNED NOT NULL DEFAULT 0  COMMENT '專題排序',
  topic_img VARCHAR(300) NOT NULL  DEFAULT '' COMMENT '專題主圖片',
  topic_thumbnail VARCHAR(300) NOT NULL  DEFAULT '' COMMENT '專題縮略圖',
  status TINYINT(4) NOT NULL COMMENT '專題狀態',
  created BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0 COMMENT '建立時間',
  updated BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0 COMMENT '更新時間',
  PRIMARY KEY (id)
)DEFAULT  CHARSET =utf8 COMMENT ='文章主題表';


# article_comment
DROP TABLE  IF EXISTS article_comment;
CREATE TABLE article_comment(
  id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  article_id BIGINT(20) UNSIGNED NOT NULL  COMMENT '文章id',
  user_id BIGINT(20) UNSIGNED NOT NULL  COMMENT '用戶id',
  comment_content VARCHAR(140) NOT NULL COMMENT '評論內容',
  sort int NOT NULL DEFAULT 0  COMMENT '排序',
  status TINYINT(4) NOT NULL COMMENT '狀態(提交,審覈經過,不經過',
  created BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0 COMMENT '建立時間',
  updated BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0 COMMENT '更新時間',
  PRIMARY KEY (id),
  INDEX  idx_article_comment_article_id(article_id),
  INDEX  idx_article_comment_user_id(user_id)
)DEFAULT  CHARSET =utf8 COMMENT ='文章評論表';


# article_comment_thumb
DROP TABLE IF EXISTS article_comment_thumb;
CREATE  TABLE article_comment_thumb(
  id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  comment_id BIGINT(20)  UNSIGNED NOT NULL COMMENT '評論id',
  user_id BIGINT(20) UNSIGNED NOT NULL COMMENT '用戶id',
  created BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0 COMMENT '建立時間',
  updated BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0 COMMENT '更新時間',
  PRIMARY KEY (id),
  INDEX idx_article_comment_thumb_user_id(user_id),
  INDEX idx_article_comment_thumb_comment_id(comment_id)
)DEFAULT  CHARSET =utf8 COMMENT ='文章評論點贊表';


# article_comment_review
DROP TABLE IF EXISTS article_comment_review;
CREATE TABLE article_comment_review(
  id BIGINT(20) UNSIGNED NOT NULL  AUTO_INCREMENT COMMENT '主鍵',
  comment_id BIGINT(20) UNSIGNED NOT NULL  COMMENT '評論id',
  article_id BIGINT(20) UNSIGNED NOT NULL  COMMENT '文章id',
  reviewer_id BIGINT(20) UNSIGNED NOT NULL COMMENT  '審覈人id',
  review_detail VARCHAR(200) NOT NULL  DEFAULT ''  COMMENT '審覈說明',
  review_time BIGINT(11) NOT NULL  DEFAULT 0 COMMENT '審覈時間',
  review_result TINYINT(4) NOT NULL COMMENT '審覈結果',
  created BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0 COMMENT '建立時間',
  updated BIGINT(11) UNSIGNED NOT NULL  DEFAULT 0 COMMENT '更新時間',
  PRIMARY KEY (id),
  INDEX idx_article_comment_review_reviewer_id(reviewer_id)
)DEFAULT  CHARSET =utf8 COMMENT ='文章評論審覈表';

39:MySQL字段的疑惑

A:mysql之中的bigint長度爲8個字節int爲4個字節,tinyint爲1個字節,不一樣類型的int決定了存儲的佔用的字節數量,而常用的tinyint(M):M默認爲4,SMALLINT(M):M默認爲6,MEDIUMINT(M):M默認爲9,INT(M):M默認爲11,BIGINT(M):M默認爲20。M表示最大顯示寬度,建表若設置了zerofill(0填充),會在數字前面補充0

他山之石:

不是咱們有這種限制,全部的建表都要加上這個限制 這個含義和入參檢查是同樣的,不是能夠保存多大的值就保存多大的值,要從邏輯入手,性別就1位,身份證就17位,手機號就11位

40:MVC模式在何處進行數據校驗

A:通常java web的項目分爲domain, dao, service, controller等層,數據的校驗和參數傳遞集中在controller和service兩個地方,具備較大的可選性,有兩種方式,1️⃣一種是在service之中獲取基本數據,取得須要的基本數據,在controller層之中進行數據合法性的校驗,而後在此處,將全部的數據統一處理,打包成須要的格式,傳送給前端;2️⃣第二種是在service層之中將全部的數據都驗證,整合,將其傳送給controller層,controller只是作一個url轉發的層。這兩種方式在實際上都是能夠的,可是因爲第2️⃣種方式要講數據多傳送一次,而在service層之中整個合法性校驗,數據的整合,而後又傳送給controller層,這樣操做比較浪費,因此第1️⃣種方式好,service層提供基本的數據,在controller層之中校驗,組裝數據,轉發請求等

41:Java EE須要掌握的技術

  • [ ] Spring(core/ mvc/boot)
  • [ ] mybatis(hibernate)
  • [ ] nosql(redis/mongodb)
  • [ ] RabbitMQ
  • [ ] RPC(Dubbo)
  • [ ] Zookeeper
  • [ ] 配置工具(maven/Apollo)
  • [ ] linux(命令行操做)

42:intellij idea 運行 tomcat,沒法進入斷點的問題解決方法

A:這是由於JMX port被佔用而出現的問題,解決方法,1️⃣:重啓機器,2️⃣:使用netstat -aon|findstr 1099找出來1099端口占用的進程,而後經過taskkill -f -pid 3756殺掉進程,從新運行,便可。其實和沒法啓動tomcat服務器的緣由是同樣的。啓動tomcat時jmx port被佔用intellij idea 運行 tomcat,沒法進入斷點的問題解決方法
img

43:RPC與RMI的介紹

A:RPC(Remote Procedure Call Protocol)遠程過程調用協議,經過網絡從遠程計算機上請求調用某種服務。RMI是遠程方法調用(Remote Method Invocation)。可以讓在客戶端Java虛擬機上的對象像調用本地對象同樣調用服務端java 虛擬機中的對象上的方法。 RMI中是經過在客戶端的Stub對象做爲遠程接口進行遠程方法的調用每一個遠程方法都具備方法簽名。若是一個方法在服務器上執行,可是沒有相匹配的簽名被添加到這個遠程接口(stub)上,那麼這個新方法就不能被RMI客戶方所調用RPC中是經過網絡服務協議向遠程主機發送請求,請求包含了一個參數集和一個文本值,一般造成「classname.methodname(參數集)」的形式。RPC遠程主機就去搜索與之相匹配的類和方法,找到後就執行方法並把結果編碼,經過網絡協議發回。 RMI只用於Java;RPC是網絡服務協議,與操做系統和語言無關

44:Spring配置多個數據源,如何使用?

A:Spring配置多個數據源的時候,啓用他須要使用包掃描,意思就是在特定的包下面使用某一個特定的數據源,在這個包下的操做,就是用這些對應的數據源。注意:須要單獨把相關的dao建立一個包,放在原先的dao下面會被覆蓋,從而致使沒法取到數據源的鏈接。另外,須要在工程的配置文件之中添加上多個數據源的鏈接基本信息,方可操做。

@Configuration
@ConfigurationProperties(prefix = "redpacket.datasource")
@MapperScan(basePackages = "com.yjf.redpacketdao", sqlSessionFactoryRef = "redpacketSession")
@EnableTransactionManagement
public class RedPacketDataConfiguration {

    //單獨把相關的dao建立一個包,放在原先的dao下面會被覆蓋,原先的包爲com.yjf.dao
    private static final String DATA_SOURCE = "redpacket_ds";

    @Value("${redpacket.datasource.mapUnderscoreToCamelCase}")
    private Boolean mapUnderscoreToCamelCase;

    @Bean("redpacketSession")
    public SqlSessionFactory getSqlSessionFactory(@Qualifier(DATA_SOURCE) DataSource ds) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(ds);
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(mapUnderscoreToCamelCase);
        bean.setConfiguration(configuration);
        return bean.getObject();
    }

    @Bean(name = DATA_SOURCE)
    @ConfigurationProperties(prefix = "redpacket.datasource")
    public DataSource dataSourceRedpacket() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    public DataSourceTransactionManager redPacketTransactionManager(@Qualifier(DATA_SOURCE) DataSource ds) {
        return new DataSourceTransactionManager(ds);
    }
}

45:把sql的嵌套查詢拆開,應該怎麼作?

A:在開發之中,SQL層(Mapper層的查詢),可能常常會遇到多個sql嵌套查詢的狀況,這樣的時候,很容易出現Mapper層的耦合,處理這些耦合,就須要把複雜嵌套的sql語句拆分紅單獨的簡單的sql,而後在service層之中處理等否,關聯等關係,這樣能夠有效減小SQL語句的耦合,讓複雜的SQL變得清晰簡單。

46:寫Mybatis的Mapper文件時候,sql的注意問題?

A:有時候,寫Mapper文件的時候,有時候會有把sql語句都寫在一塊兒,在寫<script>包裹起來的語句,在每一行的sql語句後面,最好後面留一個空格,防止SQL語句拼接連在一塊兒,出現問題

@Select("<script>"
            + "SELECT "
           + "id, create_date, ali_user_id, balance, identity_number, is_enabled, is_locked, mobile, name, "
            + "phone, wx_open_id, member_rank, sinopec_station, real_name, area, "
            + "FROM  member "
            + "WHERE is_enabled = 1 and is_locked = 0 "
            + "</script>")
    List<Member> getMemberList();

    @Select("<script>"
            + "SELECT "
            + "id, create_date, ali_user_id, balance, identity_number, is_enabled, is_locked, mobile, name, "
            + "phone, wx_open_id, member_rank, sinopec_station, real_name, area, "
            + "FROM  member "
            + "WHERE id= #{id}"
            + "</script>")
    Member getUserById(@Param("id") Long id);

47:須要的數據是從多個表之中獲取,該如何處理?

A:首先咱們經過查詢語句,將須要的信息,提取出來,此時咱們獲得了多種信息,而後接下來,咱們能夠建立一個新的domain,裏面的字段恰好是所需信息的所有字段,而後使用Mapper查詢出來咱們要的信息後,在Service層將信息組合,整合出來咱們想要的信息,好比,Student表和Book表,student(id, name, age, gender, grade, class, school),book(id, book_name, book_price, book_author, book_detail, book_time, book_type)。若是咱們想知道學生喜歡的書籍的類型和出版時間,那麼能夠新建新的domain,student_book(id, name, age, gender, book_name, book_detail, book_time, book_type),將其組合成一個新的domain, 這樣處理將會方便不少。

ref:

1.IDEA 圖標介紹。 緩存和索引介紹、清理方法和Debug使用, 2.使用 mybatis 到底要不要寫一對多、一對一關聯, 3.Log4j的配置, 4.log4j的使用--IDEA建立maven項目, 5.mybatis 詳解(五)------動態SQL, 6.MyBatis——動態SQL講解, 7.MyBatis註解Annotation介紹及Demo, 8.spring boot(8)-mybatis三種動態sql, 9.mybatis @Select註解中如何拼寫動態sql, 10.MySQL bigint(20)是什麼意思?, 11.詳解mysql int類型的長度值問題, 12.Java RMI與RPC的區別, 13.Mybatis純註解方式, 14.sql 中 limit 與 limit,offset連用的區別, 15.SQL 語句的LIMIT的用法

相關文章
相關標籤/搜索