“口袋小食”web商城后臺(tái)開(kāi)發(fā)問(wèn)題與解決方案記錄

知識(shí)點(diǎn)1:thymeleaf傳來(lái)的都是String類(lèi)型偶房,轉(zhuǎn)為int類(lèi)型的java語(yǔ)法如下

int user_id = Integer.parseInt(request.getParameter("user_id"));

知識(shí)點(diǎn)2:如果前端的<input> 標(biāo)簽用了diasbled ,則該輸入框的內(nèi)容不僅前端無(wú)法修改眉厨,提交表單時(shí)也無(wú)法傳值到 controller

如果只是想在前端對(duì)輸入框input 禁用修改庇勃,但要保持將值傳到后臺(tái)的能力,則 可以使用 readonly 屬性

參考鏈接:

css屬性readonly與disabled的區(qū)別

知識(shí)點(diǎn)3:主外鍵表關(guān)聯(lián)時(shí)刪除項(xiàng)時(shí)需要的注意事項(xiàng)

需要先刪除子表(即帶外鍵的表)披摄,再刪除父表(即其主鍵是其它表外鍵的表)

拓展鏈接:

MySQL主鍵馆铁、外鍵以及子表的刪除跑揉、更新約束

知識(shí)點(diǎn)4:多表聯(lián)查的語(yǔ)句示例

SELECT fc.first_category_id, sc.second_category_id, fc.first_category_name, sc.second_category_name FROM demo.tb_first_category fc LEFT JOIN demo.tb_second_category sc ON fc.first_category_id = sc.second_category_id;

參考鏈接:

圖解MySQL 內(nèi)連接、外連接叼架、左連接畔裕、右連接衣撬、全連接

知識(shí)點(diǎn)5:修改列名稱(chēng)的mysql語(yǔ)句示例

alter table tb_first_category modify name_before_modified name_after_modified unsigned NOT NULL after first_category_id;

參考鏈接

MYSQL數(shù)據(jù)庫(kù)(九)- 修改數(shù)據(jù)表名稱(chēng)乖订、列名稱(chēng)

問(wèn)題6:頁(yè)面切換時(shí)如何傳參

問(wèn)題描述

在一個(gè)index.html 里扮饶,用 thymeleafth:replace 引入了5個(gè)功能模塊的頁(yè)面,切換功能的邏輯是乍构,選中哪個(gè)功能則顯示哪個(gè)功能的頁(yè)面甜无,將其 display 屬性設(shè)為block, 其它功能模塊的屬性則設(shè)為 none

javascript 代碼實(shí)現(xiàn)如下:

function changePage(id){//用于實(shí)現(xiàn)頁(yè)面切換
    var parent = document.getElementById("fragParent");
    var allFragment=parent.getElementsByClassName("fragment");
    console.log(allFragment);
    console.log(allFragment.length);
    for (var i=0;i < allFragment.length;i++){

        if(parseInt(id)==parseInt(i)) {
            allFragment[i].style.display = "block";
        }
        else{
            allFragment[i].style.display = "none";
        }
    }
}

現(xiàn)在的問(wèn)題是,在這樣的切換頁(yè)面思路下哥遮,如何實(shí)現(xiàn)各子頁(yè)面切換時(shí)的數(shù)據(jù)傳遞岂丘。

錯(cuò)誤的思路

一開(kāi)始的思路是寫(xiě)不同的路由,點(diǎn)擊鏈接跳轉(zhuǎn)不同的路由再跳回主頁(yè)眠饮,結(jié)果這樣的邏輯出錯(cuò)了奥帘,因?yàn)槊看翁囟枷喈?dāng)于一次刷新,之前的display 狀態(tài)也就失效了

正確的思路

因?yàn)?個(gè)子頁(yè)面都是在父頁(yè)面里的仪召,只不過(guò)用js 控制了其display 屬性寨蹋,所以應(yīng)該在 index.html 加載的時(shí)候就 將各子頁(yè)面需要變量在index 跳轉(zhuǎn)的controller層將之全部傳到index 頁(yè)面。

知識(shí)點(diǎn)7:帶條件的多表聯(lián)查更新語(yǔ)句示例

UPDATE demo.tb_first_category fc INNER JOIN tb_second_category sc ON fc.first_category_id = sc.first_category_id SET fc.first_category_name="測(cè)試一級(jí)目錄",sc.second_category_name="測(cè)試二級(jí)目錄" WHERE sc.second_category_id=10

參考鏈接:

mysql 多表 update sql語(yǔ)句總結(jié)

知識(shí)點(diǎn)8:多表關(guān)聯(lián)刪除

下面的語(yǔ)句實(shí)現(xiàn)的功能是刪除id=1table1 表的行扔茅,以及滿(mǎn)足 a.id = b.id 條件的 table2 的對(duì)應(yīng)行

DELETE a,b FROM table1 a INNER JOIN  table2 b ON a.id = b.aid WHERE a.id=1

問(wèn)題9:類(lèi)型管理 功能中已旧,點(diǎn)擊特定行的刪除 按鈕,結(jié)果表單提交了錯(cuò)誤的 數(shù)據(jù)行 到后臺(tái)召娜,每次提交的都是列表中第一行

問(wèn)題描述

預(yù)期結(jié)果:

在前端 html 頁(yè)面有一個(gè)數(shù)據(jù)列表运褪,點(diǎn)擊要?jiǎng)h除的數(shù)據(jù)行對(duì)應(yīng)的刪除按鈕,該行對(duì)應(yīng)的表單被提交到后臺(tái)玖瘸,經(jīng)過(guò)后臺(tái)處理后刪除數(shù)據(jù)庫(kù)中對(duì)應(yīng)的信息

實(shí)際結(jié)果:

在前端的列表中秸讹,不管點(diǎn)擊數(shù)據(jù)列表哪一行,表單提交到后臺(tái)controller 層的都是第一行雅倒。

后來(lái)覺(jué)得應(yīng)該是提交時(shí)提交了全部行璃诀,但是變量只能接收第一個(gè)值,所以不管點(diǎn)哪一行后臺(tái)得到的都是第一行的數(shù)據(jù)屯断。

解決方案

之前是將<form> 標(biāo)簽寫(xiě)在了列表標(biāo)簽<ul> 外面文虏,導(dǎo)致相當(dāng)于整個(gè)數(shù)據(jù)列表都是一個(gè)表單里的內(nèi)容了,所以不管點(diǎn)擊哪行的按鈕提交的都是包含了整個(gè)列表內(nèi)容的表單殖演,只要把 <form> 標(biāo)簽放在 <ul> 里氧秘,只包圍每一行數(shù)據(jù)的 li 標(biāo)簽即可

<ul class="list_b" th:each="c : ${categorylist}">
   <form method="post" action="/categoryOperation">
       <li><input name="second_category_id" th:value="${c.second_category_id}"></li>
        <li><input name="first_category_name" th:value="${c.first_category_name}"</li>
       <li><input name="second_category_name" th:value="${c.second_category_name}"</li>
    </form>
</ul>

問(wèn)題10:實(shí)現(xiàn)提交表單時(shí)利用 confirm() 函數(shù)跳出二次確認(rèn)表單,點(diǎn)擊 確認(rèn) 則提交趴久,點(diǎn)擊 取消 則不提交

直接用 onclick="confirm('確定刪除丸相?');" 是不行的,雖然在彈窗中點(diǎn)擊 確定 確實(shí)會(huì)返回 true, 點(diǎn)擊 取消 會(huì)返回 false 彼棍,但是返回false 時(shí)依然會(huì)提交表單灭忠,正確的寫(xiě)法應(yīng)該如下:即應(yīng)該在 confirm() 返回 false 時(shí)執(zhí)行return false膳算; 語(yǔ)句:

onclick="if(!confirm('are you ok?')){return false;}"

問(wèn)題11:路由的路徑問(wèn)題

問(wèn)題描述

情況:html 頁(yè)面文件kindadd,html 和其對(duì)應(yīng)的 css 文件 main.css 的目錄結(jié)構(gòu)如下(除了main.csskinadd.html 之外其它都是目錄):

templates
--css
----main.css
--EndPages
----kindadd.html

spring boot 中的 application.properties 文件配置的路徑如下:

#默認(rèn)css調(diào)用路徑是static(在resources目錄之后),現(xiàn)在改變其路徑為templates
spring.resources.static-locations=classpath:/templates/
  • 如果在kindAdd.html 中引入樣式表的路徑寫(xiě)為css/main.css :

    kindAdd.html 提交的表單的action 屬性設(shè)為 /categoryAdd 弛作,控制層的路由也設(shè)為 /categoryAdd

    控制層函數(shù)處理完return的html頁(yè)面路徑 為 EndPages/kindAdd

    期望結(jié)果是:正確跳轉(zhuǎn)到 .../EndPages/kindAdd.html

    實(shí)際結(jié)果是:實(shí)際結(jié)果是跳轉(zhuǎn)到.../categoryAdd (注意沒(méi)有html尾綴涕蜂,相當(dāng)于是路由的路徑,這是瀏覽器上顯示的地址映琳,不知道算不算是實(shí)際跳轉(zhuǎn)的地址)机隙,于是加載的css路徑就變?yōu)?code>.../css/main.css, 而正確路徑是.../EndPages/css/main.css,所以無(wú)法正確加載

  • 如果在kindadd.html 中引入樣式表的路徑寫(xiě)為EndPages/css/main.css :

    那么在從別的頁(yè)面(前往該頁(yè)面的路由為/EndPages,其html路徑為/EndPages/index.html) 點(diǎn)擊鏈接跳轉(zhuǎn)到EndPages/kindAdd.html 的時(shí)候萨西,跳轉(zhuǎn)完畢后加載的css路徑為.../EndPages/EndPages/css/main.css ,導(dǎo)致在這一步的css樣式無(wú)法被正確加載

解決方案

最終我的解決方案是在 kindadd.html 里引用 main.css 的路徑寫(xiě)為 css/main.css ,這樣就不會(huì)在從index.html 跳轉(zhuǎn)過(guò)來(lái)的時(shí)候css加載路徑多一個(gè)EndPages ,同時(shí)為了讓在 kindAdd提交表單后的跳轉(zhuǎn)能正確加載出css,將其表單提交的action 屬性和對(duì)應(yīng)的路由設(shè)置為EndPages/categoryAdd

//todo: 了解spring boot頁(yè)面和控制層鏈接跳轉(zhuǎn)的邏輯以及css樣式文件引用的相對(duì)邏輯

?

知識(shí)點(diǎn)12: mysql 查詢(xún) SELECT 多條件搜索

直接用ANDOR 連接即可,復(fù)合運(yùn)算有歧義時(shí)用括號(hào)括起來(lái)

參考鏈接

MySQL搜索: WHERE 多條件

知識(shí)點(diǎn)13:帶條件的多表聯(lián)查

(下面這段代碼還是有問(wèn)題有鹿,詳見(jiàn)問(wèn)題14)

SELECT fc.first_category_id, sc.second_category_id, fc.first_category_name, sc.second_category_name FROM demo.tb_first_category fc LEFT JOIN demo.tb_second_category sc ON fc.first_category_id = sc.second_category_id WHERE first_category_name REGEXP "哈哈" OR second_category_name REGEXP "哈哈" limit 9;

注意用LEFT JOIN 左連接,當(dāng)右表沒(méi)有與左表匹配的記錄的時(shí)候也能輸出右表

圖解 mysql 左連接谎脯,右連接葱跋,內(nèi)連接,全外連接

(問(wèn)題其實(shí)是變量寫(xiě)錯(cuò)的問(wèn)題源梭,ON 的條件應(yīng)該是 fc.first_category_id = sc.first_category_id ,最終正確代碼如問(wèn)題15所敘述娱俺。

問(wèn)題14:對(duì)多表聯(lián)查時(shí)出現(xiàn)的問(wèn)題的解決思路

本來(lái)是帶條件的聯(lián)合搜索,排查思路如下:

  • 以為是關(guān)聯(lián)表插入時(shí)出現(xiàn)問(wèn)題咸产,結(jié)果去數(shù)據(jù)庫(kù)發(fā)現(xiàn)插入時(shí)是沒(méi)問(wèn)題的
  • 后來(lái)發(fā)現(xiàn)搜索時(shí)只能搜索出主表或子表的結(jié)果矢否,想到了應(yīng)該用LEFT JOIN 而不是 INNER JOIN 連接,結(jié)果還是出現(xiàn)以下關(guān)聯(lián)不起來(lái)的問(wèn)題
  • 以為是搜索條件設(shè)置不對(duì)脑溢,上網(wǎng)搜了一下將WHERE 改為AND ,把后面OR 連接的條件用括號(hào)括起來(lái)結(jié)果問(wèn)題更大僵朗,會(huì)搜出很多無(wú)關(guān)的結(jié)果
  • 最后把WHERE 后面的條件全去了發(fā)現(xiàn)還是無(wú)法將兩個(gè)表關(guān)聯(lián)輸出,終于發(fā)現(xiàn)是ON 后面的條件寫(xiě)錯(cuò)了屑彻,應(yīng)該是fc.first_category_id=sc.first_category_id ...

啟示:這段代碼是從上面的多表聯(lián)查的代碼里拷下來(lái)然后添加條件修改的验庙,出現(xiàn)問(wèn)題時(shí)一直以為是后面添加條件導(dǎo)致的問(wèn)題,其實(shí)在上面多表聯(lián)查時(shí)就有這個(gè)問(wèn)題了社牲,然而當(dāng)時(shí)沒(méi)有仔細(xì)檢查結(jié)果粪薛,看到輸出了就以為是對(duì)的了,導(dǎo)致后面debug更難發(fā)現(xiàn)問(wèn)題

結(jié)果first_category_id

image

最終正確代碼:

SELECT fc.first_category_id, sc.second_category_id, fc.first_category_name, sc.second_category_name FROM demo.tb_first_category fc LEFT JOIN demo.tb_second_category sc ON fc.first_category_id = sc.first_category_id WHERE first_category_name REGEXP #{arg0} OR second_category_name REGEXP #{arg0};

知識(shí)點(diǎn)15: 數(shù)據(jù)庫(kù)查詢(xún)語(yǔ)句的返回類(lèi)型設(shè)置為String時(shí)搏恤, 只能接受一個(gè)返回值

因?yàn)閿?shù)據(jù)庫(kù)里同一個(gè)name 有多條數(shù)據(jù)违寿,如果用名字搜索的話(huà)會(huì)返回多個(gè)Id

數(shù)據(jù)庫(kù)里有多個(gè)重復(fù)值

返回的錯(cuò)誤結(jié)果的截圖:

返回的結(jié)果值過(guò)多

問(wèn)題16 :一個(gè)報(bào)錯(cuò)奇怪的問(wèn)題: 實(shí)際上html中thymeleaf 的語(yǔ)法寫(xiě)錯(cuò)了引起的(也可能是html標(biāo)簽沒(méi)關(guān)閉導(dǎo)致的)

排查思路

在這之前已經(jīng)將controller 層新增的代碼全給注釋掉了,也檢查了index 主頁(yè)的路由發(fā)現(xiàn)也沒(méi)問(wèn)題

在瀏覽器的控制臺(tái)查看錯(cuò)誤說(shuō)找不到一個(gè)定義在index.htmljavascript函數(shù)熟空,查看源碼往下拉確實(shí)看不到藤巢,把該js 函數(shù)定義放在body 里也不行,由于將代碼跑起來(lái)后再瀏覽器查看的源碼是全部的源碼息罗,包括th:include 的頁(yè)面也一并顯示掂咒,很長(zhǎng),于是想到了是引用的頁(yè)面引起的問(wèn)題

index 中用 thymeleaf引用了其它幾個(gè)界面,本來(lái)都沒(méi)什么問(wèn)題绍刮,但是在我修改了其引用的其中一個(gè)頁(yè)面foodlist.html 后温圆,原先在index 定義的</body> 之外</html> 之內(nèi)的js 代碼就識(shí)別不了了,說(shuō)找不到在那定義的函數(shù)孩革,如果把foodlist.html 文件 <body> 里的代碼全注釋了就沒(méi)這么問(wèn)題岁歉,注釋其它引用的頁(yè)面就不行

最后通過(guò)全部注釋?zhuān)鸲稳∠⑨尩姆绞秸业搅藛?wèn)題所在,其實(shí)應(yīng)該能想到的嫉戚,主要修改的就是這一段和另一段刨裆,要出現(xiàn)問(wèn)題最有可能在這兩段澈圈。想到的是 goodlist 的問(wèn)題彬檀,去后臺(tái) debug 發(fā)現(xiàn)果然沒(méi)有取到goodlist ,返回的全為null

這告訴我們一步一debug很重要!

最后發(fā)現(xiàn)的問(wèn)題是entity 層寫(xiě)的對(duì)象的一個(gè)變量名稱(chēng)跟數(shù)據(jù)庫(kù)的變量名不一樣(之前已經(jīng)試過(guò)mysql語(yǔ)句了瞬女,所以只能是在之后的封裝出現(xiàn)問(wèn)題了)

**后來(lái)發(fā)現(xiàn)如果html 頁(yè)面的語(yǔ)法有問(wèn)題窍帝,比如說(shuō)某個(gè)標(biāo)簽少了一半符號(hào)( 如<li ) 也會(huì)報(bào)錯(cuò) **


...
<div class="list_b_c">
    <ul class="list_b" th:each="g : ${goodslist}">
        <form method="post" action="/brandOperation">
            <li class="b20"><input name="commodity_id" th:value="${g.commodity_id}" style="border: none;text-align: center;" readonly="true"></li>
            <li class="b20"><input name="cname" th:value="${g.cname}" style="border: none;text-align: center;" readonly="true"></li>
            <li class="b20"><input name="name" th:value="${g.name}" style="border: none;text-align: center;" readonly="true"></li>
            <li class="b20"><input name="sc_name" th:value="${g.second_category_name}" style="border: none;text-align: center;" readonly="true"></li>

            <input type="submit" name="submitInput" value="編輯" class="inputbutton">
            <input type="submit" name="submitInput"  value="刪除" class="inputbutton"  onclick="if(!confirm('are you ok?')){return false;}">

        </form>
    </ul>
</div>
...

知識(shí)點(diǎn)17:在提交按鈕里寫(xiě)js代碼會(huì)使表單的 required 屬性失效

我在<button> 里添加的 js 代碼是

onclick="alert('保存成功!');"

知識(shí)點(diǎn)18:mysql GROUP_CONCAT列表操作

將訂單order_id 與其對(duì)應(yīng)的多個(gè)商品idcommodity_id逗號(hào)連接的字符串 的形式返回

SELECT    o.order_id, 
          o.state,
          od.quantity
          GROUP_CONCAT(od.commodity_id ORDER BY od.commodity_id) AS commoditys
FROM      tb_order o
LEFT JOIN tb_orders_detail od ON o.order_id = od.order_id
GROUP BY  o.order_id;

問(wèn)題19:一個(gè)神奇的問(wèn)題,因?yàn)樽詣?dòng)補(bǔ)全了相似的變量名導(dǎo)致一直發(fā)現(xiàn)不了問(wèn)題

這件事告訴我們自動(dòng)補(bǔ)全既能減少因?yàn)樽兞棵l(fā)的bug,也可能導(dǎo)致變量命名引發(fā)的bug诽偷,因?yàn)闀?huì)自動(dòng)補(bǔ)全相似的變量命名反而更難發(fā)現(xiàn)問(wèn)題

寫(xiě)著寫(xiě)著突然dao層掃描不到了坤学,整個(gè) service 層的函數(shù)調(diào)用的dao層層對(duì)象都出現(xiàn)了紅線(xiàn),于是我就想著肯定是引用或者IDEA本身的問(wèn)題报慕,重啟深浮,查bug都不行,還把dao層對(duì)象刪了重新聲明眠冈,問(wèn)題就在這里飞苇,本來(lái)應(yīng)該是重啟IDEA就解決的,結(jié)果因?yàn)槲抑匦侣暶鱠ao層對(duì)象的時(shí)候IDEA自動(dòng)補(bǔ)全了一個(gè)跟后面用的變量名很像但不是的變量蜗顽,導(dǎo)致問(wèn)題轉(zhuǎn)移了而且因?yàn)橹岸寄苓\(yùn)行我也不會(huì)考慮是變量命名的問(wèn)題布卡,找了一個(gè)小時(shí)找不到來(lái)去吃飯睡了一覺(jué),回到教室再看出現(xiàn)問(wèn)題的地方發(fā)現(xiàn)提醒的問(wèn)題不是說(shuō)原來(lái)的類(lèi)找不到了而是說(shuō)聲明的這個(gè)變量沒(méi)有使用雇盖,然后就發(fā)現(xiàn)我新聲明的變量跟下面使用的不對(duì)應(yīng)....掀凳子.jpg

問(wèn)題20:搞混了插入語(yǔ)句和更新語(yǔ)句忿等,插入語(yǔ)句不能帶條件

如果要更新應(yīng)該用update ,可以帶條件來(lái)更新指定數(shù)據(jù)行崔挖,如果要插入的話(huà)是插入新數(shù)據(jù)贸街,不能帶條件

知識(shí)點(diǎn)21:更新數(shù)據(jù)庫(kù)上某字段的數(shù)值: 在原基礎(chǔ)上增加

update demo.tb_flavor_commodity SET stock=stock+10 WHERE flavor_commodity_id=1;

問(wèn)題22:又一個(gè)神奇的問(wèn)題,因?yàn)樵?code>dao 層的數(shù)據(jù)庫(kù)語(yǔ)句中的mysql 語(yǔ)句寫(xiě)少了個(gè)花括號(hào)狸相,結(jié)果報(bào)路徑錯(cuò)誤...

之前也試過(guò)mysql 語(yǔ)句寫(xiě)錯(cuò)了薛匪,都是能成功運(yùn)行的,只有在訪(fǎng)問(wèn)特定頁(yè)面需要調(diào)用該函數(shù)時(shí)才會(huì)報(bào)錯(cuò)提示mysql 語(yǔ)句錯(cuò)了卷哩,結(jié)果這次直接整個(gè)項(xiàng)目都運(yùn)行不了蛋辈,還報(bào)了一大版的錯(cuò)誤看上去就像是找不到dao 層一樣

最后實(shí)在沒(méi)法了仔細(xì)地看報(bào)錯(cuò)發(fā)現(xiàn)這個(gè)報(bào)錯(cuò)真有特點(diǎn),不是把錯(cuò)誤根源放在前面,而是放在最后面...大概意思是A錯(cuò)了因?yàn)锽錯(cuò)了冷溶,B錯(cuò)了因?yàn)镃錯(cuò)了....最后應(yīng)該是F錯(cuò)了...渐白,而且是一長(zhǎng)句,不拖到最后面根本看不出什么問(wèn)題

mysql 被錯(cuò)誤地寫(xiě)成了如下

...value(#{arg0}),#{arg1,#{arg2}

改正改過(guò)后應(yīng)該是

...value(#{arg0},#{arg1},#{arg2})

報(bào)錯(cuò)信息如下:

2019-07-08 16:44:07.404  WARN 14480 --- [  restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'endPagesController': Unsatisfied dependency expressed through field 'endpagesservice'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'endPagesServiceImpl': Unsatisfied dependency expressed through field 'endpagesdao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'endPagesDao' defined in file [D:\Git\codehub_download\ShopProject\target\classes\com\example\demo\dao\EndPagesDao.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: org.apache.ibatis.builder.BuilderException: Could not find value method on SQL annotation.  Cause: org.apache.ibatis.builder.BuilderException: Parsing error was found in mapping #{arg1,#{arg2}.  Check syntax #{property|(expression), var1=value1, var2=value2, ...}

知識(shí)22:mysql 給表取了別名之后逞频,就不能用原來(lái)的名字了

原來(lái)的代碼

SELECT tb_order.order_id, tb_order.state,tb_order_detail.detail_id,tb_order_detail.quantityGROUP_CONCAT(tb_commodity.cname) FROM tb_order o LEFT JOIN tb_order_detail od ON o.order_id = od.order_id LEFT JOIN tb_commodity c ON od.commodity_id=c.commodity_id GROUP BY o.order_id;

這段 mysql 語(yǔ)句有三個(gè)問(wèn)題:

  1. tb_order_detail.quantityGROUP_CONCAT 之間應(yīng)該有逗號(hào)隔開(kāi)
  2. GROUP_CONCAT(tb_commodity.cname)FROM 之間應(yīng)該有 cname ,并且該cname 之前不能有表名纯衍,即不能是tb_commodity.cnamecname ,而GROUP_CONCAT() 括號(hào)里的表名可以帶也可以不帶
  3. 后面 LEFT JOIN 后給三個(gè)表起了別名,所以前面 SELECT 的變量的表名也應(yīng)該用別名苗胀,用原名會(huì)報(bào)錯(cuò)

之前我覺(jué)得在變量名前加上表名更嚴(yán)謹(jǐn)避免多個(gè)表中有重名變量襟诸,但是現(xiàn)在發(fā)現(xiàn)有時(shí)候?qū)懕砻粌H是多次一舉的行為,還可能因此引發(fā)錯(cuò)誤基协,比如上面的第2點(diǎn)歌亲,cname就不能帶表名,帶了就報(bào)錯(cuò)

后來(lái)發(fā)現(xiàn)GROUP_CONCAT(c.name) 相當(dāng)于SELECT 出來(lái)的變量名澜驮,所以和前一個(gè)變量應(yīng)該用逗號(hào)隔開(kāi)陷揪。這個(gè) cname 是新變量名,表示GROUP_CONCAT(c.cname) 連接成字符串后的新名稱(chēng)杂穷, 所以不能加表名.前綴

后來(lái)的代碼

SELECT o.order_id,o.state,od.detail_id,od.quantity, GROUP_CONCAT(c.cname) cname FROM tb_order o LEFT JOIN tb_orders_detail od ON o.order_id = od.order_id LEFT JOIN tb_commodity c ON od.commodity_id=c.commodity_id GROUP BY o.order_id

將od.quantity 也聚合起來(lái)悍缠,并且將兩個(gè)聚合名設(shè)為 quantity_group, cname_group :

SELECT o.order_id,o.state,od.detail_id,GROUP_CONCAT(od.quantity) quantity_group, GROUP_CONCAT(c.cname) cname_group FROM tb_order o LEFT JOIN tb_orders_detail od ON o.order_id = od.order_id LEFT JOIN tb_commodity c ON od.commodity_id=c.commodity_id GROUP BY o.order_id

參考鏈接:

MySQL連表操作LEFT JOIN和GROUP_CONCAT函數(shù)分組使用

知識(shí)點(diǎn)23:java的嵌套列表與嵌套數(shù)組

一開(kāi)始時(shí)我是用嵌套列表的,后來(lái)遇到錯(cuò)誤沒(méi)想到是聲明長(zhǎng)度的問(wèn)題就換了二維數(shù)組了耐量,后來(lái)發(fā)現(xiàn)如果只聲明了一維的大小沒(méi)有聲明二維的話(huà)飞蚓,雖然編輯器不會(huì)報(bào)錯(cuò),但是運(yùn)行項(xiàng)目時(shí)會(huì)報(bào)錯(cuò)

如下所示廊蜒,這樣會(huì)出錯(cuò):

//orderlist.size()是一個(gè)列表的長(zhǎng)度趴拧,sgroup.length是一個(gè)數(shù)組的長(zhǎng)度
String[][] arr =new String[orderlist.size()][];
for (int j=0;j<sgroup.length;j++){
    arr[i][j]=sgroup[j];//這條語(yǔ)句會(huì)引發(fā)錯(cuò)誤,因?yàn)閍rr[i][j]的第二維長(zhǎng)度沒(méi)有聲明劲藐,相當(dāng)于第二維長(zhǎng)度為0
}

可以聲明時(shí)只初始化行數(shù)八堡,之后再初始化列數(shù)

參考鏈接

java 數(shù)組 聲明時(shí)只初始化行數(shù),之后再初始化列數(shù)的嵌套數(shù)組

知識(shí)點(diǎn)24:thymeleaf 應(yīng)該不可以迭代兩個(gè)對(duì)象(列表/數(shù)組等)

thymeleaf 是可以嵌套迭代的聘芜,但是不可以并列迭代兩個(gè)對(duì)象兄渺,如下所示:在同一個(gè)<ul> 列表中,只迭代orderlist 列表變量或只迭代二維數(shù)組 all_commodity (嵌套迭代了) 都是可以的汰现,但是這兩個(gè)變量放同一個(gè)<ul> 列表里迭代就會(huì)報(bào)錯(cuò)挂谍。

<ul class="list_b"  th:each="o:${orderlist}"  th:each="one_order:${all_commodity}">
    
    <li style="width:17%"><input name="cname" th:value="${o.cname_group}" style="width:100%;border: none;text-align: center;" readonly="true"></li>
    
    <select class="form-control" name="name"  style="width:100px;margin-left: 210px;">
        <option th:each="oo:${one_order}" th:value="${oo}" th:text="${oo}">初始值</option>
    </select>
    
</ul>

知識(shí)點(diǎn)25:英文搜索的技巧:在了解thymeleaf 是否可以迭代兩個(gè)兌現(xiàn)更多過(guò)程中,我在搜了幾次前面的結(jié)果都不是我想要的瞎饲,然后我用英文搜口叙,結(jié)果一搜就出來(lái)了

我的中文搜索關(guān)鍵詞 themeleaf th:each 在同一區(qū)域同時(shí)迭代兩個(gè)對(duì)象

我的英文搜索關(guān)鍵詞thymeleaf th:each iterate two object in one area

第一個(gè)搜索結(jié)果的鏈接如下:

Thymeleaf th:each two iterate two listings - Stack Overflow

里面的答案說(shuō)了thymeleaf 無(wú)法這樣做,變通的方法是把它們放到一個(gè)map (中文搜索結(jié)果中我看到有提到map,也想到可能要把這個(gè) listarr 組一個(gè) map)了嗅战,另外一個(gè)方法就是創(chuàng)建一個(gè)對(duì)象妄田,這個(gè)對(duì)象包含了要迭代的這個(gè)listarr(這個(gè)方法其實(shí)之前我也想到了俺亮,就是覺(jué)得麻煩)

Unfortunately you cannot do it that way.

Two options that I can think of right now:

  1. If the lists are of equal size and indexes correspond to same object, put them in a Map and iterate the map. That way you will get the room and roomType
  2. (Preferred) Create a object and save the room and roomType in it, then add it to single List and iterate the list.

I prefer the second method because you can guarantee what you are actually passing into the list and onto the view layer for processing.

知識(shí)點(diǎn)26:java里的變量聲明問(wèn)題:變量重新賦值后再添加到列表,添加到列表時(shí)沒(méi)有更新變量

其實(shí)變量的聲明和初始化在循環(huán)外的時(shí)候疟呐,每次打印 order_all_in_one.orderOne 也是不一樣的脚曾,即每次循環(huán)的order_all_in_one 都是得到了更新的,但是添加到order_all_in_one_list 后启具,之后再用循環(huán)輸出order_all_in_one_list 的元素又都是一樣的...非常奇怪本讥,把order_all_in_one 的聲明和初始化放在循環(huán)里就沒(méi)這個(gè)問(wèn)題。

后來(lái)發(fā)現(xiàn)變量(可能只是針對(duì)對(duì)象變量)聲明可以在循環(huán)外只聲明一次鲁冯,但是初始化要在循環(huán)內(nèi)拷沸,即每次賦值后,下一次重新賦值前需要重新初始化

List<OrderAllInOneEntity_yrh> order_all_in_one_list=new ArrayList<>();
OrderAllInOneEntity_yrh order_all_in_one;/*只需聲明一次*/
for(int i=0;i<orderlist.size();i++){
    order_all_in_one=new OrderAllInOneEntity_yrh();/*該對(duì)象變量每次重新賦值前都要重新初始化*/
    order_all_in_one.orderOne=orderlist.get(i);//一個(gè)訂單聚合類(lèi)對(duì)象
    //System.out.println("look here!=================");
    //System.out.println(order_all_in_one.orderOne);
    String one_order_cname=orderlist.get(i).cname_group;//一個(gè)訂單的全部商品:用逗號(hào)連接的字符串
    String[] sgroup=one_order_cname.split(",");//每個(gè)訂單的商品切割后存到一個(gè)臨時(shí)數(shù)組中
    order_all_in_one.cnameOneLineArr=sgroup;//一個(gè)訂單的全部商品:一維數(shù)組

    order_all_in_one_list.add(order_all_in_one);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末薯演,一起剝皮案震驚了整個(gè)濱河市撞芍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涣仿,老刑警劉巖勤庐,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異好港,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)米罚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)钧汹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人录择,你說(shuō)我怎么就攤上這事拔莱。” “怎么了隘竭?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵塘秦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我动看,道長(zhǎng)尊剔,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任菱皆,我火速辦了婚禮须误,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘仇轻。我一直安慰自己京痢,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布篷店。 她就那樣靜靜地躺著祭椰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上方淤,一...
    開(kāi)封第一講書(shū)人閱讀 51,198評(píng)論 1 299
  • 那天侣监,我揣著相機(jī)與錄音,去河邊找鬼臣淤。 笑死橄霉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的邑蒋。 我是一名探鬼主播姓蜂,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼医吊!你這毒婦竟也來(lái)了钱慢?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤卿堂,失蹤者是張志新(化名)和其女友劉穎束莫,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體草描,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡览绿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了穗慕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饿敲。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖逛绵,靈堂內(nèi)的尸體忽然破棺而出怀各,到底是詐尸還是另有隱情,我是刑警寧澤术浪,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布瓢对,位于F島的核電站,受9級(jí)特大地震影響胰苏,放射性物質(zhì)發(fā)生泄漏硕蛹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一碟联、第九天 我趴在偏房一處隱蔽的房頂上張望妓美。 院中可真熱鬧,春花似錦鲤孵、人聲如沸壶栋。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)贵试。三九已至琉兜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間毙玻,已是汗流浹背豌蟋。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桑滩,地道東北人梧疲。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像运准,于是被迫代替她去往敵國(guó)和親幌氮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 概要 64學(xué)時(shí) 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,182評(píng)論 0 3
  • 問(wèn)答題47 /72 常見(jiàn)瀏覽器兼容性問(wèn)題與解決方案胁澳? 參考答案 (1)瀏覽器兼容問(wèn)題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,748評(píng)論 1 92
  • HTML 5 HTML5概述 因特網(wǎng)上的信息是以網(wǎng)頁(yè)的形式展示給用戶(hù)的该互,因此網(wǎng)頁(yè)是網(wǎng)絡(luò)信息傳遞的載體。網(wǎng)頁(yè)文件是用...
    阿啊阿吖丁閱讀 3,887評(píng)論 0 0
  • 今天是柳君書(shū)房陪伴你的第21天。 ▼ 今日話(huà)題 ~ “工作即表演” 01 這個(gè)時(shí)代胰丁,“玩怂骈伲”變的越來(lái)越重要。 “快...
    楊柳君2017閱讀 341評(píng)論 0 0
  • 一隘马、初來(lái)乍到 新一輪的寒流慢慢到來(lái)太防,聽(tīng)著窗外嘩啦啦的雨聲,心中思緒萬(wàn)千酸员,不知不覺(jué)地已獨(dú)自一人在他鄉(xiāng)...
    熊貓君me閱讀 271評(píng)論 2 2