96SEO 2026-02-20 04:06 21
2.参数#xff1a;根据需求考虑#xff0c;我们这个接口功能完成需要哪些信息。

3.返回结果#xff1a;考虑我们能为对方提供什么。
站在对方角度考虑。
用户登录添加图书显示图书列表更新图书删除图书批量删除图书强制登录引入统一功能
jdbc:mysql://127.0.0.1:3306/book_test?characterEncodingutf8useSSLfalseusername:
com.mysql.cj.jdbc.Drivermybatis:configuration:log-impl:
org.apache.ibatis.logging.stdout.StdOutImpl
MyBatis?志map-underscore-to-camel-case:
xml的?件路径在resources/mapper创建所有表的xml?件#
classpath对应resources这个目录接下来说明在mapper这个文件夹下面以Mapper.xml结束的都可以被加载#
spring-book.log我们新建一个book_test数据库。
com.qiyangyang.springbook.demos.model;import
com.qiyangyang.springbook.demos.model;
application/x-www-form-urlencoded;
从数据库查询用户名和密码如果可以查到并且密码一致就认为登录成功。
com.qiyangyang.springbook.demos.controller;import
com.qiyangyang.springbook.demos.model.UserInfo;
com.qiyangyang.springbook.demos.service.UserService;
org.springframework.beans.factory.annotation.Autowired;
org.springframework.util.StringUtils;
org.springframework.web.bind.annotation.RequestMapping;
org.springframework.web.bind.annotation.RestController;
javax.servlet.http.HttpSession;Slf4j
userService;RequestMapping(/login)public
校验参数*/if(!StringUtils.hasLength(userName)
!StringUtils.hasLength(password)){return
false;}//判断用户输入的密码和用户输入的密码是否一致//我们需要查询数据库得到数据库的密码UserInfo
userService.queryByName(userName);if(userInfo
false;}if(password.equals(userInfo.getPassword())){//将密码置为空不置为空也可以因为Session是在服务器上的数据客户端也看不到//session也是占内存的因此不需要的不存。
/***
存Session*///由于密码信息是没用的用不到。
我们设置成空。
不设置成空也行因为存在服务器。
客户端是看不到的userInfo.setPassword();session.setAttribute(user_session,userInfo);return
com.qiyangyang.springbook.demos.controller;import
com.qiyangyang.springbook.demos.model.UserInfo;
com.qiyangyang.springbook.demos.service.UserService;
org.springframework.beans.factory.annotation.Autowired;
org.springframework.util.StringUtils;
org.springframework.web.bind.annotation.RequestMapping;
org.springframework.web.bind.annotation.RestController;
javax.servlet.http.HttpSession;Slf4j
userService;RequestMapping(/login)public
校验参数*/if(!StringUtils.hasLength(userName)
!StringUtils.hasLength(password)){return
false;}//判断用户输入的密码和用户输入的密码是否一致//我们需要查询数据库得到数据库的密码UserInfo
userService.queryByName(userName);if(userInfo
false;}if(password.equals(userInfo.getPassword())){//将密码置为空不置为空也可以因为Session是在服务器上的数据客户端也看不到//session也是占内存的因此不需要的不存。
/***
存Session*///由于密码信息是没用的用不到。
我们设置成空。
不设置成空也行因为存在服务器。
客户端是看不到的userInfo.setPassword();session.setAttribute(user_session,userInfo);return
存的是根据SessionId获取的Session对象每一个sessionId对应一个session对象。
*
会根据客户端等等判断是新用户还是老用户。
服务器里面存了很多session。
*
发送给客户端。
**/**/问题1每次我们存的Session都一样。
后面用户。
存的Session会覆盖前面用户的Session吗
存的是根据SessionId获取的Session对象每一个sessionId对应一个session对象。
会根据客户端等等判断是新用户还是老用户。
服务器里面存了很多session。
什么时候才去做多线程呢比如程序里面用到了线程池。
才考虑多线程。
每个用户进来login函数。
信息存放在栈里面栈是线程私有的。
堆是线程公有的。
这些成员变量存储在栈里面因此每个用户的信息之间没有关系。
分别对应不同的对象。
在我们需要进行优化的时候考虑多线程。
比如要查询两次数据。
第一次得到了密码可以因为业务需要还要查询一次。
这时候串行查询觉得太慢了。
这时候考虑多线程。
就可以进行并行查询。
加了多线程我们就要考虑线程安全的情况。
代码里用到多线程才考虑多线程。
校验密码我们推荐在业务逻辑层来写由于这里比较简单。
我们就写在Controller中
com.qiyangyang.springbook.demos.service;import
com.qiyangyang.springbook.demos.mapper.UserInfoMapper;
com.qiyangyang.springbook.demos.model.UserInfo;
org.springframework.beans.factory.annotation.Autowired;
org.springframework.stereotype.Service;Service
userInfoMapper.queryByName(userName);}
com.qiyangyang.springbook.demos.mapper;import
com.qiyangyang.springbook.demos.model.UserInfo;
org.apache.ibatis.annotations.Mapper;
org.apache.ibatis.annotations.Select;Mapper
使用Postman校验。
多次实验发现校验成功。
然后我们再去写前端的代码。
srcjs/jquery.min.js/scriptscriptfunction
{$.ajax({type:post,url:/user/login,data:{userName:$(#userName).val(),password:$(#password).val()},success:function
{if(resulttrue){//验证成功location.href
{alert(登录失败用户名不存在或密码错误);}}});}/script3.4.2完整前端登录代码
initial-scale1.0titleDocument/titlelink
onclicklogin()登录/button/div/div/divscript
srcjs/jquery.min.js/scriptscriptfunction
{$.ajax({type:post,url:/user/login,data:{userName:$(#userName).val(),password:$(#password).val()},success:function
{if(resulttrue){//验证成功location.href
{alert(登录失败用户名不存在或密码错误);}}});}/script
输入错误用户名和密码。
登录失败。
弹框显示用户名不存在或密码错误。
application/x-www-form-urlencoded;
bookName图书1author作者1count23price36publish出版社1status1
form表单的形式来提交数据。
服务器返回处理结果。
返回“”表示图书添加成功。
否则返回失败信息。
bookService;RequestMapping(/addBook)public
bookInfo){log.info(添加图书bookInfo:{},bookInfo);/***
参数校验*/if(!StringUtils.hasLength(bookInfo.getBookName())||
!StringUtils.hasLength(bookInfo.getAuthor())||
!StringUtils.hasLength(bookInfo.getPublish())||
bookInfo.getPrice()null){return
出现错误比如参数错误。
添加过程出现异常因为MySQL会出现一些异常*
{bookService.insertBook(bookInfo);}catch
bookInfoMapper.insertBook(bookInfo);}
book_info(book_name,author,count,price,publish)
(#{bookName},#{author},#{count},#{price},#{publish}))Integer
在前端显示页面并没有什么作用。
主要是搭配后端来进行前后端交互。
整个表单内容需要提交的话我们可以借助form标签来提交整个表单
//序列化//这个函数会把整个表单的所有的input框…等等输入的项目都会提交
forbookName图书名称:/labelinputtypetextclassform-controlplaceholder请输入图书名称idbookNamenamebookName//divform
value2不可借阅/option/select/divdiv
onclickjavascript:history.back()返回/button/div/formajax部分
srcjs/jquery.min.js/scriptscriptfunction
{$.ajax({type:post,url:/book/addBook,
//整个表单内容需要提交的话我们可以借助form标签来提交整个表单搭配后端做一些交互来使用的。
data:
//这个函数会把整个表单的所有的input框..等等输入的项目都会提交success:function
成功添加图书){alert(添加成功);location.href
{alert(result);}}});}/script4.4.2完整前端添加图书代码
10pxsvgxmlnshttp://www.w3.org/2000/svgwidth40fill#17a2b8classbi
3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492V2.687zM8
4.287.94c-1.514.153-3.042.672-3.994
0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809
1.783z//svgspan添加图书/span/h2/divform
forbookName图书名称:/labelinputtypetextclassform-controlplaceholder请输入图书名称idbookNamenamebookName//divdiv
forbookAuthor图书作者/labelinputtypetextclassform-controlplaceholder请输入图书作者idbookAuthornameauthor//divdiv
forbookStock图书库存/labelinputtypetextclassform-controlplaceholder请输入图书库存idbookStocknamecount//divdiv
forbookPrice图书定价/labelinputtypenumberclassform-controlplaceholder请输入价格idbookPricenameprice//divdiv
forbookPublisher出版社/labelinputtypetextidbookPublisherclassform-controlplaceholder请输入图书出版社namepublish//divdiv
value2不可借阅/option/select/divdiv
onclickadd()确定/buttonbuttontypebuttonclassbtn
btn-lgonclickjavascript:history.back()返回/button/div/form/divscript
srcjs/jquery.min.js/scriptscriptfunction
/book/addBook,//整个表单内容需要提交的话我们可以借助form标签来提交整个表单搭配后端做一些交互来使用的。
data:
//序列化//这个函数会把整个表单的所有的input框..等等输入的项目都会提交success:
{alert(result);}},});}/script/body
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback