知识点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
里,用 thymeleaf
的th: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=1
的 table1
表的行,以及满足 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.css
和kinadd.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
多条件搜索
直接用AND
或 OR
连接即可,复合运算有歧义时用括号括起来
参考链接
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
最终正确代码:
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.html
的javascript
函数,查看源码往下拉确实看不到,把该js
函数定义放在body
里也不行,由于将代码跑起来后再浏览器查看的源码是全部的源码,包括th:include
的页面也一并显示,很长,于是想到了是引用的页面引起的问题
在index
中用 thymeleaf
引用了其它几个界面,本来都没什么问题,但是在我修改了其引用的其中一个页面foodlist.html
后,原先在index
定义的