三脚架案例

一、项目概述

核心业务

  1. 用户登录操作
  2. 后台首页展现、展现左侧菜单列表
  3. 完成用户模块的crud–增删改查
  4. 完成商品分类模块的crud
  5. 完成商品模块的crud
  6. 完成商品关联入库、关联查询
  7. 完成商品图片文件上传
  8. 完成图片的回显 nginx反向代理
  9. 完成项目服务器部署 准备3台tomcat服务器 实现负载均衡、搭建tomcat集群
  10. 实现项目linux 真实环境部署

二 、 各表说明

1.user表说明

在这里插入图片描述

2. item_cat商品分类表

菜单
在这里插入图片描述

3. 商品表对应的详情表item_desc

在这里插入图片描述

4. item

在这里插入图片描述

4. 权限表rights

在这里插入图片描述

三、后端项目搭建

个别项目创建后,不能识别为maven

在pom里添加maven依赖

1. 创建一个新的项目 jt

2. 编辑pom文件

3. 复制目录

4.修改后端服务器的端口号

server:
  port: 8091

5. 流程

controller 要加两个注解

  • @CrossOrigin //跨越那个服务器,就在谁的头上加注解
  • @RestController
    //将该类交给Spring容器管理
@RestController
@CrossOrigin
public class UserController {
    @Autowired
    private UserService userService;
    //1.测试后端
    @GetMapping("findall")
    public List<User> findall(){
        return userService.findAll();
    }
}

service 接口

public interface UserService {
    List<User> findAll();
}

实现类 接口实现类
要加注解

  • @Service //将该类交给Spring容器管理
@Service
public class UserServiceImplt implements UserService{
    @Autowired
    private UserMapper userMapper;
    @Override
    public List<User> findAll() {
        return userMapper.findAll();
    }
}

mapper接口

  • 在mapper头顶加@Mapper注解
  • 或者在启动类上加@Mapperscan
@Mapper
public interface UserMapper {
    List<User> findAll();
}

后端项目环境的测试

  1. 目录在这里插入图片描述
  2. 后补

什么是VUE

components组件页面

完成用户登录

用户登录的流程

  1. 用户输入用户名和密码
  2. 通过vue中的axios发起post请求和参数
  3. 在UserController中接受用户的请求和参数
  4. 现将密码进行加密处理 根据参数查询数据
    4.1 查询成功有数据 输入正确 有且只有一个数据
    4.2.查询失败 没有数据 输入有误
    5.登陆成功 则返回token秘钥(传token是为了安全性 )利用SysResult对象返回

首页跳转说明

在这里插入图片描述
在这里插入图片描述

1. 用户动态登录

目录结构:
在这里插入图片描述
controller

在这里插入图片描述
service
在这里插入图片描述
在这里插入图片描述

mapper
在这里插入图片描述

补充:idea如何解决代理对象飘红

在这里插入图片描述

拓展知识:cookie和session

cookie

“小型类型文件”,为了辨别用户身份,是通过session加密跟踪用户信息,即暂时或永久储存在计算机(本地终端)

  1. 是一个小型文本文件,存储在本地终端上
  2. 可以存储用户信息
  3. 数据类型key-value
  4. 数据一般采用加密的方式保存
  5. 数据可以“永久”保存
session

session加密跟踪用户信息,会话期间有效

session和cookie选择

特点:

  1. 临时用session 永久用cookie
  2. 对于安全性较高的数据,选用session
  3. seesion和cookie信息的查看,如图:在这里插入图片描述

2. 实现系统页面的跳转

在这里插入图片描述
跳转到系统主页–组件是 home
步骤:

  1. 导入组件
  2. 添加跳转路径
  3. 如图:在这里插入图片描述
    引入:
    在这里插入图片描述

业务需求

说明:用户在未登录的情况下,可直接访问其他页面,没有安全性
所以需要添加校验规则
校验的规则:

1.访问没有token信息,则用户没有登录,则需要跳转登录页面
2.
问题:如何实现每一次的请求都要校验
答:路由导航拦截器

路由导航拦截器

在这里插入图片描述

后端业务方法编辑

  1. 业务接口
    1.2 如图:
  2. 权限列表查询的sql(关联查询)
    2.1 如图: 在这里插入图片描述
    但是我们映射的sql语句是不能出现重名的id,需要更改:
    在这里插入图片描述
    也可以选择封装时更改 resultMap
    在这里插入图片描述
    写了箭头函数,写this,代表当前的function函数

业务需求 – 子级路由跳转

实现子集
点击请求后,要求跳转的页面组件 在 home组件空白位置展现—即该组件为home组件的子级
在这里插入图片描述

路由语法说明
组成路由的三个部分:

  1. <router-link to="/shopping">商场</router-link> 路由 跳转的关键字
  2. <router-view></router-view> 路由的填充位,跳转的页面 --> 展现的位置
  3. const routes = [ {path: '/', redirect: '/login'},// redirect:再直接询问 {path: '/login', component: Login}, {path:'/home',component:Home} ]路由的跳转规则

父子组件跳转
第一步:在home里有个占位符 router-view

在这里插入图片描述
代码:

在home组件中
<!-- 定义主页面结构-->
      <el-main>
        <!-- 定义路由展现页面-->
        <router-view></router-view>
      </el-main>

第二步:实现父子组件的映射
思路:从home组件跳转到home下的子组件user页面下,代码展现–使用children关键字,前提是,在home里有个占位符 router-view

在index 路由组件中
{path:'/home',component:Home,children:[
      {path: '/', component: }
  ]}

实现跳转user的总结
在这里插入图片描述
在这里插入图片描述

跳转页面,同时获取用户数据 – 实现方法: 生命周期函数
1.

//利用钩子函数实现数据查询
    mounted(){
      this.getUserList()
    }

2.获取的js

 async getUserList(){
        //动态获取数据 get请求 携带多个数据 封装成对象 用params
        const {data: result} = await this.$http.get('/user/list',{
           params: this.queryInfo
        })
        // 访问失败
        if(result.status !== 200) return this.$message.error("用户列表查询失败")
        // rows 后讲  多层封装
        this.userList = result.data.rows
        // total 后讲
        this.total = result.data.total
        console.log("总记录数:"+this.total)
      }

封装的对象queryInfo

queryInfo: {    //封装的对象
          query: '',         //查询:请输入内容
          pageNum: 1,          //初始化页
          pageSize: 20     //定义每页几行
        }

业务:分页查询数据
前端使用的对象封装,后端数据库 也应该用PageResult对象封装

这里是引用
在这里插入图片描述

前后端数据关联:在后端服务器需要额外的查询总数以及分页的总数
请求类型为get 一共传了三个参数 --> 返回结果有五个 --> 把剩余的两个附带上 --> 业务
数据封装:如图
在这里插入图片描述
后端编辑
controller
在这里插入图片描述

sql查询
分页sql语法:
select * from user limit 起始位置,查询条数 (含头不包尾)
第一页:
select * from user limit 0,10
第二页:
select * from user limit 10,10
第n页:
select * from user limit (页数-1)*条数,条数
(分数据库 limit不是通用的 sql标准 是通过row 行的方式来查询)

需求: 如果query有参数,则添加like关键字 --> 如何实现??动态sql

<where>
     <if test="query != null and query != ''">username like "%"#{query}"%" </if>
</where>

扩展:将多值封装成单值 @Param

总结:

controller
在这里插入图片描述
实现类
在这里插入图片描述
mapper接口
在这里插入图片描述
xml
在这里插入图片描述

2. 业务: 用户新增

知识点一:非空校验
知识点二:双向数据绑定

2.1 前端js说明

  1. 点击事件<el-button type="primary" @click="addUserBtn">确 定</el-button>
  2. 函数说明 校验
//校验用户数据  valid表示校验是否通过
      addUserBtn(){
        this.$refs.addUserRef.validate(async valid => {
          //如果校验失败 则停止数据
          if(!valid) return
          //console.log(this.addUserModel)
          const {data: result} = await this.$http.post('/user/addUser',this.addUserModel)
          if(result.status !== 200) return this.$message.error("用户新增失败")
          this.$message.success("用户新增成功")
          //关闭对话框
          this.dialogVisible = false
          //重新获取用户列表
          this.getUserList()

        })
      }

2.2 后端编辑

  1. 密码加密处理
  2. 设定默认状态
  3. 设定默认时间
  4. sql语句 insert into value

controller
在这里插入图片描述
实现类
在这里插入图片描述

mapper.xml
在这里插入图片描述

3. 业务:更新数据回显

3.1 js解析

点击修改按钮时,触发作用域插槽(获取当前行的所有数据)–>根据id更新数据 --> 为了获取id 所以使用作用域插槽获取当前行的全部数据
需要注意的是sql语句 只需要写三个值,username phone email
仔细看前端页面

  1. 路径是resultful形式 所以putmapping注意
  2. 传参是单值 写@path…
  3. 只有一个参数的时候,sql会自动按照下表,所以#{写什么都行}

3.2 后端编辑

3.2.1 业务:更新数据回显

在这里插入图片描述
xml
在这里插入图片描述

3.2.2 业务:实现更新数据回显

3.2.2.1 页面js分析

摁钮
在这里插入图片描述
摁钮触发的方法 : 校验 和 根据接口文档封装数据
URL:/user/updateUser
参数类型 是user的js对象 – 属性有三个 id phone email --> 后端用json串接

在这里插入图片描述

3.2.2.2 编辑后端
  1. 查看用户接口文档在这里插入图片描述

  2. 编辑controller

  3. 实现类:修改更新时间 updated

  4. 编辑xml文件 update user set phone = #{phone} ,email = #{email},updated = #{updated} where id = #{id}

4. 业务:删除用户数据

4.1 js页面解析

  1. 点击删除按钮 会弹出消息确认框
  2. 触发方法 – > scope.row作用域插槽
  3. 确认就是confirm 取消就是cancel

4.2 后端编辑

4.2.1 查看接口文档

在这里插入图片描述

4.2.1 编辑后端
  1. url:/user/{id}
  2. 参数id
  3. 接口文件:接受单个参数id需要添加@PathVariable 接口方法注意不要重名 deleteByUserId()
  4. sql : delete from user where id = #{id}

5. 业务:用户状态修改

5.1 前端说明

说明:用户可以修改状态 请求路径是:在这里插入图片描述
更新操作一定要写条件
在js中无法直接识别布尔型数据 所以用一个开关
在这里插入图片描述

 <el-table-column prop="status" label="状态">
             <template slot-scope="scope">
                <el-switch v-model="scope.row.status" @change="updateStatus(scope.row)"
                  active-color="#13ce66" inactive-color="#ff4949">
                </el-switch>
             </template>

拓展:vue.js作用域插槽

一般在表格数据中,信息不全,如果需要获取全部数据,则需要使用 vue.js作用域插槽

作用域插槽 基本语法:

 <template slot-scope="scope">
	{{scope.row}}
 </template>

其中{{scope.row}} 代表当前行的全部信息

5.2 后端编辑

controller–更新操作不用返回值,看路径是resultful形式,

在这里插入图片描述
实现类
在这里插入图片描述

5. 业务:异常处理

5.1 spring异常

全局异常的处理机制 – 只拦截controller层抛出的异常 语法规则

  • 1.标识该类是异常处理机制
  • @RestControllerAdvice 返回对象是json串
  • advice:通知 AOP技术 面向切面编程 的技术 用来解决特定问题
  • 返回值几乎统一
  • 说明:需要定义一个方法
  • 要求:返回的是统一的业务数据 SysResult
  • 拦截:指定遇到某种异常实现AOP处理
  • 2.在方法上添加注解 @ExceptionHandler()

参考:

//全局异常的处理机制 -- 只拦截controller层抛出的异常
/*语法规则
* 1.标识该类是异常处理机制
* @RestControllerAdvice  返回对象是json串
* advice:通知 AOP技术 面向切面编程 的技术 用来解决特定问题
* 返回值几乎统一
* 说明:需要定义一个方法
*   要求:返回的是统一的业务数据 SysResult
*   拦截:指定遇到某种异常实现AOP处理
* 2.在方法上添加注解 @ExceptionHandler()
* */
@RestControllerAdvice
public class SystemExe {
    //用来拦截指定的异常 当我们遇到运行异常时,报这个异常
    @ExceptionHandler({RuntimeException.class})
    public Object fail(Exception e){//异常类型较多 数量多 用大类Object接
        e.printStackTrace();
        //返回返回失败
        return  SysResult.fail();
//        return  SysResult.fail1();
//        return  SysResult.fail2();
    }
}

5.2 spring中事务机制

5.2.1 特征
  1. 原子性 事务同时成功同时失败 不能分割
  2. 隔离性 多个事务相互隔离 独立 互不干扰
  3. 一致性 保证数据的一直(脏读/幻读/不可重复度)
  4. 持久性 一旦事务提交 就应该持久化保存
5.2.2 spring中默认事务策略
5.2.3 spring添加事务

在实现类上添加注解@Transactional

/* @Transactional 开启spring事务管理机制
    *   默认值rollbackFor = RuntimeException.class
    *   如果想要他拦截其他异常 需要添加属性 noRollbackFor = RuntimeException.class
    * 在写CRUD业务层(除查询)时,写这个注解 */
    @Transactional
    @Override
    public void deleteUserById(Integer id) {
       userMapper.deleteUserById(id);
    }

6. 补充知识

7. 业务:商品分类展现

7.2.2 优化手段
思路:获取所有的数据库记录,之后按照父子级关系进行封装
结构:Map<k,v>

Map<parentId,当前父级的自己信息> — 只有自己的信息 – 当前查询的信息

封装数据规则:

定义一个结果集是 Map<Integer,List>的方法 实现类中

  1. 创建一个map集合 Map<Integer,List>
    2.1 获取数组中的所有数据,itemCatMapper.selectList(null); 没有查询条件,可以为null

遍历所有的数据,如果存在,追加数据,不存在,则以自己的id创建一个数组,以自己为第一个元素

2.2 遍历数据 for (类型 遍历的每一个元素的名字 :被遍历的对象)
2.3 拿到parentid ----> itemcat.getparentid()
2.4 判断是否存在 if(map.containskey(parentid)){key存在,追加
}else{key不存在,定义list集合,把自己当作第一个元素,存入集合}
2.5 定义list集合 list childrenlist = new … 然后再把自己当作第一个元素存入集合,childrenlist.add() map.put(parentid,childrenlist)
2.6 key存在,追加 map.get(parentid).add(itemcat)追加自己的id和元素
2.7 以后拿子集,写map的k就可以取到了
2.8 最后返回map集合
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值