“口袋小食”web商城后台开发问题与解决方案记录

知识点1:thymeleaf传来的都是String类型,转为int类型的java语法如下

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

知识点2:如果前端的 标签用了diasbled ,则该输入框的内容不仅前端无法修改,提交表单时也无法传值到 controller

如果只是想在前端对输入框input 禁用修改,但要保持将值传到后台的能力,则 可以使用 readonly 属性

参考链接:

css属性readonly与disabled的区别

知识点3:主外键表关联时删除项时需要的注意事项

需要先删除子表(即带外键的表),再删除父表(即其主键是其它表外键的表)

拓展链接:

MySQL主键、外键以及子表的删除、更新约束

知识点4:多表联查的语句示例

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 内连接、外连接、左连接、右连接、全连接

知识点5:修改列名称的mysql语句示例

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

参考链接

MYSQL数据库(九)- 修改数据表名称、列名称

问题6:页面切换时如何传参

问题描述

在一个index.html 里,用 thymeleafth:replace 引入了5个功能模块的页面,切换功能的逻辑是,选中哪个功能则显示哪个功能的页面,将其 display 属性设为block, 其它功能模块的属性则设为 none

javascript 代码实现如下:

function changePage(id){//用于实现页面切换
    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";
        }
    }
}

现在的问题是,在这样的切换页面思路下,如何实现各子页面切换时的数据传递。

错误的思路

一开始的思路是写不同的路由,点击链接跳转不同的路由再跳回主页,结果这样的逻辑出错了,因为每次跳回都相当于一次刷新,之前的display 状态也就失效了

正确的思路

因为6个子页面都是在父页面里的,只不过用js 控制了其display 属性,所以应该在 index.html 加载的时候就 将各子页面需要变量在index 跳转的controller层将之全部传到index 页面。

知识点7:带条件的多表联查更新语句示例

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="测试一级目录",sc.second_category_name="测试二级目录" WHERE sc.second_category_id=10

参考链接:

mysql 多表 update sql语句总结

知识点8:多表关联删除

下面的语句实现的功能是删除id=1table1 表的行,以及满足 a.id = b.id 条件的 table2 的对应行

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

问题9:类型管理 功能中,点击特定行的删除 按钮,结果表单提交了错误的 数据行 到后台,每次提交的都是列表中第一行

问题描述

预期结果:

在前端 html 页面有一个数据列表,点击要删除的数据行对应的删除按钮,该行对应的表单被提交到后台,经过后台处理后删除数据库中对应的信息

实际结果:

在前端的列表中,不管点击数据列表哪一行,表单提交到后台controller 层的都是第一行。

后来觉得应该是提交时提交了全部行,但是变量只能接收第一个值,所以不管点哪一行后台得到的都是第一行的数据。

解决方案

之前是将

标签写在了列表标签
    外面,导致相当于整个数据列表都是一个表单里的内容了,所以不管点击哪行的按钮提交的都是包含了整个列表内容的表单,只要把 标签放在
      里,只包围每一行数据的 li 标签即可

      问题10:实现提交表单时利用 confirm() 函数跳出二次确认表单,点击 确认 则提交,点击 取消 则不提交

      直接用 onclick="confirm('确定删除?');" 是不行的,虽然在弹窗中点击 确定 确实会返回 true, 点击 取消 会返回 false ,但是返回false 时依然会提交表单,正确的写法应该如下:即应该在 confirm() 返回 false 时执行return false; 语句:

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

      问题11:路由的路径问题

      问题描述

      情况:html 页面文件kindadd,html 和其对应的 css 文件 main.css 的目录结构如下(除了main.csskinadd.html 之外其它都是目录):

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

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

      #默认css调用路径是static(在resources目录之后),现在改变其路径为templates
      spring.resources.static-locations=classpath:/templates/
      
      • 如果在kindAdd.html 中引入样式表的路径写为css/main.css :

        kindAdd.html 提交的表单的action 属性设为 /categoryAdd ,控制层的路由也设为 /categoryAdd

        控制层函数处理完return的html页面路径 为 EndPages/kindAdd

        期望结果是:正确跳转到 .../EndPages/kindAdd.html

        实际结果是:实际结果是跳转到.../categoryAdd (注意没有html尾缀,相当于是路由的路径,这是浏览器上显示的地址,不知道算不算是实际跳转的地址),于是加载的css路径就变为.../css/main.css, 而正确路径是.../EndPages/css/main.css,所以无法正确加载

      • 如果在kindadd.html 中引入样式表的路径写为EndPages/css/main.css :

        那么在从别的页面(前往该页面的路由为/EndPages,其html路径为/EndPages/index.html) 点击链接跳转到EndPages/kindAdd.html 的时候,跳转完毕后加载的css路径为.../EndPages/EndPages/css/main.css ,导致在这一步的css样式无法被正确加载

      解决方案

      最终我的解决方案是在 kindadd.html 里引用 main.css 的路径写为 css/main.css ,这样就不会在从index.html 跳转过来的时候css加载路径多一个EndPages ,同时为了让在 kindAdd提交表单后的跳转能正确加载出css,将其表单提交的action 属性和对应的路由设置为EndPages/categoryAdd

      //todo: 了解spring boot页面和控制层链接跳转的逻辑以及css样式文件引用的相对逻辑

      知识点12: mysql 查询 SELECT 多条件搜索

      直接用ANDOR 连接即可,复合运算有歧义时用括号括起来

      参考链接

      MySQL搜索: WHERE 多条件

      知识点13:带条件的多表联查

      (下面这段代码还是有问题,详见问题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 左连接,当右表没有与左表匹配的记录的时候也能输出右表

      图解 mysql 左连接,右连接,内连接,全外连接

      (问题其实是变量写错的问题,ON 的条件应该是 fc.first_category_id = sc.first_category_id ,最终正确代码如问题15所叙述。

      问题14:对多表联查时出现的问题的解决思路

      本来是带条件的联合搜索,排查思路如下:

      • 以为是关联表插入时出现问题,结果去数据库发现插入时是没问题的
      • 后来发现搜索时只能搜索出主表或子表的结果,想到了应该用LEFT JOIN 而不是 INNER JOIN 连接,结果还是出现以下关联不起来的问题
      • 以为是搜索条件设置不对,上网搜了一下将WHERE 改为AND ,把后面OR 连接的条件用括号括起来结果问题更大,会搜出很多无关的结果
      • 最后把WHERE 后面的条件全去了发现还是无法将两个表关联输出,终于发现是ON 后面的条件写错了,应该是fc.first_category_id=sc.first_category_id ...

      启示:这段代码是从上面的多表联查的代码里拷下来然后添加条件修改的,出现问题时一直以为是后面添加条件导致的问题,其实在上面多表联查时就有这个问题了,然而当时没有仔细检查结果,看到输出了就以为是对的了,导致后面debug更难发现问题

      结果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};
      

      知识点15: 数据库查询语句的返回类型设置为String时, 只能接受一个返回值

      因为数据库里同一个name 有多条数据,如果用名字搜索的话会返回多个Id

      数据库里有多个重复值

      返回的错误结果的截图:

      返回的结果值过多

      问题16 :一个报错奇怪的问题: 实际上html中thymeleaf 的语法写错了引起的(也可能是html标签没关闭导致的)

      排查思路

      在这之前已经将controller 层新增的代码全给注释掉了,也检查了index 主页的路由发现也没问题

      在浏览器的控制台查看错误说找不到一个定义在index.htmljavascript函数,查看源码往下拉确实看不到,把该js 函数定义放在body 里也不行,由于将代码跑起来后再浏览器查看的源码是全部的源码,包括th:include 的页面也一并显示,很长,于是想到了是引用的页面引起的问题

      index 中用 thymeleaf引用了其它几个界面,本来都没什么问题,但是在我修改了其引用的其中一个页面foodlist.html 后,原先在index 定义的 之外 之内的js 代码就识别不了了,说找不到在那定义的函数,如果把foodlist.html 文件 里的代码全注释了就没这么问题,注释其它引用的页面就不行

      最后通过全部注释,逐段取消注释的方式找到了问题所在,其实应该能想到的,主要修改的就是这一段和另一段,要出现问题最有可能在这两段。想到的是 goodlist 的问题,去后台 debug 发现果然没有取到goodlist ,返回的全为null

      这告诉我们一步一debug很重要!

      最后发现的问题是entity 层写的对象的一个变量名称跟数据库的变量名不一样(之前已经试过mysql语句了,所以只能是在之后的封装出现问题了)

      **后来发现如果html 页面的语法有问题,比如说某个标签少了一半符号( 如 ) 也会报错 **

      
      ...
      
      ...

      知识点17:在提交按钮里写js代码会使表单的 required 属性失效

      我在

你可能感兴趣的:(“口袋小食”web商城后台开发问题与解决方案记录)