SSM整合-前后端分离(实现增删改查)

news2024/12/28 21:05:09

实现增删改查

  • 实现功能03-添加家居信息
    • 需求分析/图解
    • 思路分析
    • 代码实现
    • 注意事项和细节
  • 实现功能04-显示家居信息
    • 需求分析/图解
    • 思路分析
    • 代码实现
  • 实现功能05-修改家居信息
    • 需求分析/图解
    • 思路分析
    • 代码实现
    • 注意事项和细节
  • 实现功能06-删除家居信息
    • 需求分析/图解
    • 思路分析
    • 代码实现
    • 课后作业
  • 实现功能07-分页显示列表
    • 需求分析/图解
    • 思路分析
    • 代码实现
    • 完成测试
  • 实现功能08-带条件查询分页显示列表
    • 需求分析/图解
    • 思路分析
    • 代码实现
  • 实现功能09-添加家居表单前端校验
    • 需求分析/图解
    • 思路分析
    • 代码实现
  • 实现功能10-添加家居表单后端校验
    • 需求分析/图解
    • 思路分析
    • 代码实现

上一讲, 我们学习的是 SSM项目-前后端分离(搭建Vue前端工程)

现在打开furn-ssm项目 和 ssm_vue项目

在这里插入图片描述

实现功能03-添加家居信息

需求分析/图解

在这里插入图片描述

在这里插入图片描述

思路分析

1.完成后台代码从 dao -> service -> controller, 并对每层代码进行测试, 到controller这一层, 使用Postman 发送http post请求完成测试.

2.完成前端代码, 使用axios发送ajax(json数据)给后台, 实现添加家居信息

代码实现

回忆JavaWeb版本家居购项目
在这里插入图片描述

1创建src/main/java/com/zzw/furn/service/FurnService.java

public interface FurnService {
    //添加
    public void save(Furn furn);
}

2.创建src/main/java/com/zzw/furn/service/impl/FurnServiceImpl.java

@Service
public class FurnServiceImpl implements FurnService {

    //注入/装配FurnMapper接口对象[代理对象]
    @Resource
    private FurnMapper furnMapper;

    @Override
    public void save(Furn furn) {
        //解读
        //1.使用insertSelective
        //2.因为我们furn表的id是自增的, 就使用insertSelective
        furnMapper.insertSelective(furn);
    }
}

3.测试 src/test/java/com/zzw/furn/service/FurnServiceTest.java
动态代理jdk的Proxy和Spring的CGlib, getBean方法何时会返回代理对象

public class FurnServiceTest {

    //属性
    private ApplicationContext ioc;
    //从spring容器中,获取的是FurnService接口对象/代理对象
    private FurnService furnService;

    /**
     * 解读
     * 1. 编写方法完成初始化
     * 2. 当方法标注 @Before, 表示在执行你的目标测试方法前, 会先执行该方法
     */
    @Before
    public void init() {
        ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        //说明
        //1.通过FurnService.class类型获取 FurnService接口代理对象
        furnService = ioc.getBean(FurnService.class);
        System.out.println("furnService=" + furnService.getClass());
    }

    @Test
    public void save() {
        Furn furn =
                new Furn(null, "你好", "你好", new BigDecimal(100), 123, 2, "image");
        furnService.save(furn);
        System.out.println("添加成功");
    }
}

4.修改Furn.java, 当创建Furn对象 imgPathnull时, imgPath给默认值

//当创建Furn对象 imgPath 为 null时, imgPath 给默认值
private String imgPath = "assets/images/product-image/1.jpg";

public Furn(Integer id, String name, String maker, BigDecimal price, Integer sales, Integer stock, String imgPath) {
    this.id = id;
    this.name = name;
    this.maker = maker;
    this.price = price;
    this.sales = sales;
    this.stock = stock;
    //解读
    //如果imgPath不为null, 而且是有数据, 就设置给this.imgPath; 否则就使用默认值
    //imgPath != null && !imgPath.equals("") => 使用一个工具类方法完成 => org.springframework.util
    //public static boolean hasText(@Nullable String str) {
    //    return str != null && !str.isEmpty() && containsText(str);
    //}
    //StringUtils.hasText(imgPath) 就是要求imgPath 不是null, 而且不是"", 而且不是"    "
    if (StringUtils.hasText(imgPath)) {
        this.imgPath = imgPath;
    } else {
        this.imgPath = "assets/images/product-image/1.jpg";
    }
}

5.创建src/main/java/com/zzw/furn/bean/Msg.java, 用来返回json数据的通用类.

/**
 * Msg: 后端程序返回给前端的json数据的Msg对象=>本质就是数据规则
 */
@Getter
@Setter
public class Msg {

    //状态码 200-成功 400-失败
    private int code;
    //信息-返回数据的说明
    private String msg;
    //返回给客户端/浏览器的数据-Map集合
    private Map<String, Object> extend = new HashMap<>();

    //编写几个常用的方法-封装好msg
    //返回success对应的msg
    public static Msg success() {
        Msg msg = new Msg();
        msg.setCode(200);
        msg.setMsg("success");
        return msg;
    }

    //返回fail对应的msg
    public static Msg fail() {
        Msg msg = new Msg();
        msg.setCode(400);
        msg.setMsg("fail");
        return msg;
    }

    //给返回的msg设置数据
    public Msg add(String key, Object value) {
        extend.put(key, value);
        return this;
    }
}

6.创建com/zzw/furn/controller/FurnController.java,处理添加请求.

@Controller
public class FurnController {

    //注入配置FurnService
    @Resource
    private FurnService furnService;

    /**
     * 1.响应客户端的添加请求
     * 2.@RequestBody:
     * 使用SpringMVC的 @RequestBody 将客户端提交的json数据, 封装成JavaBean对象
     * 3.@ResponseBody:
     * 我们往往需要服务器返回的数据格式是按照json来返回的(底层是按照http协议进行协商)
     *
     * @param furn
     * @return
     */
    @PostMapping("/save")
    @ResponseBody
    public Msg save(@RequestBody Furn furn) {
        furnService.save(furn);
        //没有抛出异常, 就返回成功信息
        Msg success = Msg.success();
        return success;
    }
}

7.使用Postman来完成Controller层测试, 通过Postman添加Furn数据

1)使用Postman进行测试. Postman如何发送json数据

{
    "name":"海澜之家衣柜",
    "maker":"小米之家",
    "price":13.3,
    "sales":300,
    "stock":1000
}

2)使用Postman测试时, 因为我们前台发送的是json数据, 被服务器接收到后, 转成javabean数据, 因此pom.xml需要引入jackson, 处理json数据, 否则后台会报错.

<!--引入jackson, 处理json数据-->
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.12.4</version>
</dependency>

8.点击添加按钮, 可以出现添加家居的对话框, 修改D:\idea_project\SSM-Vue整合项目\ssm_vue\src\views\HomeView.vue.
说明一下 el-dialog从Dialog对话框获取▶️, 表单代码从Form表单获取▶️, 组合一下即可
js定义对象

<template>
  <div>
    <!--增加按钮和搜索框-->
    <div style="margin: 10px 5px">
      <!--解读
      1.@click="add" 表示点击新增, 就会触发add方法
      -->
      <el-button type="primary" @click="add">新增</el-button>
      <el-button>其它</el-button>
    </div>
    <!--margin: 顶部距离 左侧距离-->
    <div style="margin: 10px 5px">
      <el-input v-model="search" style="width: 20%" placeholder="请输入家居名"/>
      <el-button style="margin: 10px" type="primary">查询</el-button>
    </div>
    <el-table :data="tableData" stripe style="width: 90%">
      <el-table-column sortable prop="date" label="日期"/>
      <el-table-column prop="name" label="名字"/>
      <el-table-column prop="address" label="地址"/>
      <el-table-column fixed="right" label="操作" width="120">
        <template #default>
          <el-button link type="primary">
            编辑
          </el-button>
          <el-button link type="primary">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!--说明家居的弹窗
    说明:
    1.el-dialog v-model="dialogFormVisible" 表示对话框, 和 dialogFormVisible 变量双向绑定, 控制是否显示对话框
    2.el-form :model="form" 表示 表单数据 和 form数据变量 双向绑定
    3.el-input v-model="form.name" 表示表单的input控件, 名字为name, 需要和后台JavaBean属性一致
    4.在前端中, 对象的属性是可以动态生成的. 这个知识点, 我们在讲解前端技术栈讲过.
    -->
    <el-dialog v-model="dialogVisible" title="提示" width="500">
      <el-form :model="form" label-width="120px">
        <el-form-item label="家居名">
          <el-input v-model="form.name" style="width: 80%"/>
        </el-form-item>
        <el-form-item label="厂商">
          <el-input v-model="form.marker" style="width: 80%"/>
        </el-form-item>
        <el-form-item label="价格">
          <el-input v-model="form.price" style="width: 80%"/>
        </el-form-item>
        <el-form-item label="销量">
          <el-input v-model="form.sales" style="width: 80%"/>
        </el-form-item>
        <el-form-item label="库存">
          <el-input v-model="form.stock" style="width: 80%"/>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="save">确 定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script>
// @ is an alias to /src
// 导出组件
export default {
  name: 'HomeView',
  components: {},
  data() {
    return {
      search: '',
      dialogVisible: false,
      form: {},//定义一个空表单
    }
  },
  methods: {
    add() {
      //显示对话框
      this.dialogVisible = true;
      //情况添加表单数据
      this.form = {}
    }
  }
}
</script>

7.完成测试, 点击新增按钮, 看看能否正常的弹出添加家居的对话框(含有表单).在这里插入图片描述

8.项目前端: 安装axios, 用于发送Ajax请求给后台
npm i axios -S

9.创建工具文件 D:\idea_project\SSM-Vue整合项目\ssm_vue\src\utils\request.js

//引入axios包
//重要提示: 如果在启动前端项目时, 提示找不到axios, 把光标放在 import axios from "axios"的'axios', 会有一个修复提示, 导入axios, 导入即可正常使用.
import axios from "axios";
//通过axios创建对象-request对象, 用于发送请求到后端
const request = axios.create({
    timeout: 5000
})

//request拦截器的处理
//1.可以对请求做统一的处理
//2.比如统一地假如token, Content-Type等
request.interceptors.request.use(config => {
    config.headers['Content-Type'] = "application/json;charset=utf-8";
    return config;
}, error => {
    return Promise.reject(error);
})

//导出request对象, 在其它文件引入就可以使用
export default request;

10.修改HomeView.vue, 在methods编写save方法, 并测试, 会出现跨域问题.
发送axios请求

<script>
// @ is an alias to /src
//导入request对象
import request from "@/utils/request";

//导出组件
export default {
  name: 'HomeView',
  components: {},
  methods: {
    save() {//将填写的表单数据,发送给后端
      //解读
      //1.url: http://localhost:8080/ssm/save
      //2.this.form: 携带的数据
      request.post("http://localhost:8080/ssm/save", this.form).then(res => {
        console.log("res=", res);
        console.log("res.data=", res.data);
        this.dialogVisible = false;
      })
    }
  }
}
</script>

在这里插入图片描述

11.修改D:\idea_project\SSM-Vue整合项目\ssm_vue\vue.config.js, 解决跨域问题.
因为修改了配置文件, npm serve 需要重启, 否则不能识别.

module.exports = {
  devServer: {
    port: 10000,                  //前端vue启动端口
    //解读:如果我们请求的地址 /api/save => 代理到 http://localhost:8080/ssm/save
    proxy: {                      //设置代理, 必须填
      '/api': {                   //设置拦截器, 拦截器格式 斜杠+拦截器名字, 名字可以自己定
        target: 'http://localhost:8080/ssm', //代理的目标地址, 就是/api 代理 http://localhost:8080/ssm
        changeOrigin: true,               //是否设置同源, 输入是的, 浏览器就允许跨域
        pathRewrite: {                    //路径重写
          '/api':''                       //选择忽略拦截器里面的单词
        }
      }
    }
  }
}

12.老师提醒, 这里容易出现的问题
1)一定要确定 request.post(“/api/save”) 被代理后的url, 是项目后台服务对应提供的API接口.

2)跨域执行请求时, 如果报错, 浏览器还是提示http://localhost:10000/api/xxx, 所以不要认为是api没有替换你的配置.

注意事项和细节

1.Postman测试时, 要制定Content-Type, 否则会报错在这里插入图片描述

2.如果需要将提交的json数据, 封装到对应的JaveBean, 需要配置@RequestBody, 否则会报错500.在这里插入图片描述

如果需要返回json数据, 需要在方法上, 配置@ResponseBody, 否则会报错404.在这里插入图片描述

实现功能04-显示家居信息

需求分析/图解

在这里插入图片描述

思路分析

1.完成后台代码从dao -> service ->controller, 并对每层代码进行测试.

2.完成前台代码, 使用axios发送http请求, 返回所有家居数据, 将数据绑定显示.

代码实现

1.修改FurnService.javaFurnServiceImpl.java, 增加findAll方法

//查询所有的家居信息
public List<Furn> findAll();
@Override
public List<Furn> findAll() {
    //查看分析FurnMapper.xml文件
    //传入是null, 表示返回所有的家居信息
    return furnMapper.selectByExample(null);
}

2.修改FurnServiceTest.java, 测试find All方法.

@Test
public void findAll() {
    List<Furn> furns = furnService.findAll();
    for (Furn furn : furns) {
        System.out.println("furn--" + furn);
    }
}

3.修改FurnController.java, 处理修改请求, 并使用Postman完成测试.

/**
 * 响应客户的查询请求
 * @param furn
 * @return
 */
@GetMapping("/furns")
@ResponseBody
public Msg listFurns() {
    List<Furn> furns = furnService.findAll();;
    没有抛出异常, 就返回成功信息
    //Msg msg = Msg.success();
    把家居信息, 封装到msg对象
    //return msg.add("furns", furns);
    return Msg.success().add("furns", furns);
}

在这里插入图片描述

4.修改HomeView.vue, 编写list方法. vue生命周期
1)修改 el-table

<el-table :data="tableData" stripe style="width: 90%">
  <el-table-column sortable prop="id" v-model="tableData.id"/>
  <el-table-column prop="name" v-model="tableData.name" label="家居名"/>
  <el-table-column prop="maker" v-model="tableData.maker" label="厂商"/>
  <el-table-column prop="sales" v-model="tableData.sales" label="销量"/>
  <el-table-column prop="price" v-model="tableData.price" label="价格"/>
  <el-table-column prop="stock" v-model="tableData.stock" label="库存"/>
  <el-table-column fixed="right" label="操作" width="120">
    <template #default>
      <el-button link type="primary">
        编辑
      </el-button>
      <el-button link type="primary">删除</el-button>
    </template>
  </el-table-column>
</el-table>

2)修改 tableData: []

data() {
  return {
    search: '',
    dialogVisible: false,
    form: {},//定义一个空表单
    tableData: []
  }
},

3)在created() 调用list() 完成页面数据获取

methods: {
  save() {//将填写的表单数据,发送给后端
    //解读
    //1.url: http://localhost:8080/ssm/save
    //2.this.form: 携带的数据
    request.post("/api/save", this.form).then(res => {
      console.log("res=", res);
      console.log("res.data=", res.data);
      this.dialogVisible = false;
      //调用list方法, 刷新数据
      this.list();
    })
  },
  //编写list方法, 请求返回家居信息
  //list方法应该是自动调用
  list() {
    request.get("/api/furns").then(res => {
      console.log("res.data--", res.data);
      //解读: 为什么是res.data.extend.furns, 可以根据console输出的数据结构来查看
      this.tableData = res.data.extend.furns;
    })
  }
},
created() {//生命周期函数
  this.list();//调用list方法
}

5.完成测试, 看看是否可以显示家居列表信息在这里插入图片描述

6.修改src/utils/request.js, 增加response拦截器, 统一处理响应后结果
字符串转JSON

//可以在调用接口响应后, 统一地处理返回结果
request.interceptors.response.use(response => {
    let res = response.data;
    //如果返回的是文件
    if (response.config.responseType === 'blob') {
        return res;
    }
    //如果是string, 就转成json
    if (typeof res === 'string') {
        //如果res 不为'', 就转换成json对象
        res = res ? JSON.parse(res) : res;
    }
    return res;
}, error => {
    console.log("error=", error);
    return Promise.reject(error);
})

7.修改HomeView.vue, 简化返回处理

list() {
  request.get("/api/furns").then(res => {
    console.log("res--", res);
    //解读: 为什么是res.data.extend.furns, 可以根据console输出的数据结构来查看
    //因为我们对返回response结果进行了统一拦截处理 let res = response.data;
    //, 所以我们这里直接使用 res.extend.furns
    this.tableData = res.extend.furns;
  })
}

8.完成测试在这里插入图片描述

实现功能05-修改家居信息

需求分析/图解

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

思路分析

1.完成后台代码从 dao ->service -> controller, 并对每层代码进行测试

2.完成前台代码, 回显家居信息, 再使用axios发送http请求, 更新数据, 将数据绑定显示.

代码实现

1.修改FurnService.javaFurnServiceImpl.java, 增加update方法

//修改家居
public void update(Furn furn);
@Override
public void update(Furn furn) {
    furnMapper.updateByPrimaryKeySelective(furn);
}

2.修改FurnServiceTest.java, 测试update方法.

@Test
public void update() {
    Furn furn = new Furn();
    furn.setId(18);
    furn.setName("大象家居");
    furn.setMaker("大象传人");
    //因为imgPath属性有一个默认值, 所以如果我们不希望生成的update语句对img_path字段修改, 就显示地设置null
    furn.setImgPath(null);
    furnService.update(furn);
    System.out.println("修改成功");
}

3.修改FurnController.java, 处理修改请求, 并使用Postman完成测试.
rest请求风格

/**
 * 1.响应客户端的修改请求
 * @param furn
 * @return
 */
@PutMapping("/update")
@ResponseBody
public Msg update(@RequestBody Furn furn) {
    furnService.update(furn);
    //没有抛出异常, 就返回成功信息
    Msg success = Msg.success();
    return success;
}

在这里插入图片描述

4.修改HomeView.vue, 编写handleEdit方法, 回显数据 并测试.

<el-table-column fixed="right" label="操作" width="120">
  <!--说明
  1.这里通过 handleEdit(scope.row)
  2.可以将当前行数据传递给 handleEdit
  -->
  <template #default="scope">
    <el-button link type="primary" @click="handleEdit(scope.row)">编辑</el-button>
    <el-button link type="primary">删除</el-button>
  </template>
</el-table-column>
methods: {
  handleEdit(row) {
    //console.log("row--", row);
    //将当前的家居信息绑定到弹出对话框的表单上
    //1. 方式1: 可以通过row.id 到后端-DB去获取对应的家居信息, 返回后将其绑定到this.form[小伙伴自己思考解决]
    //2. 方式2: 把获取的row的数据通过处理, 绑定到this.form 进行显示
    //3. JSON.stringify(row): 将row 转成json字符串
    //4. JSON.parse(JSON.stringify(row)) 将json字符串 转成json对象
    this.form = JSON.parse(JSON.stringify(row));

    //显示对话框
    this.dialogVisible = true;
  }
}

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

5.修改HomeView.vue, 修改save方法, 处理修改请求, 添加 更新成功的消息框, 不需要做额外处理

save() {//将填写的表单数据,发送给后端
  //修改和添加时走的同一个方法
  if (this.form.id) {//表示修改
    request.put("/api/update", this.form).then(res => {
      // console.log("res=", res);
      if (res.code === 200) {//修改成功
        //提示一个成功的消息框
        this.$message({
          message: "修改成功",
          type: "success",
        });
      } else {
        this.$message({
          message: "修改失败",
          type: "error",
        });
      }
      //关闭对话框
      this.dialogVisible = false;
      //调用list方法, 刷新数据
      this.list();
    })
  } else {//表示添加
    //解读
    //1.url: http://localhost:8080/ssm/save
    //2.this.form: 携带的数据
    request.post("/api/save", this.form).then(res => {
      // console.log("res=", res);
      this.dialogVisible = false;
      //调用list方法, 刷新数据
      this.list();
    });
  }
  //这里有一个注意事项...
},

注意事项和细节

1.<template #default="scope">
在这里插入图片描述

2.调用list() 刷新数据需要注意的地方. 这样写是错误的, axios本质是ajax请求, 异步处理机制.

save() {//将填写的表单数据,发送给后端
  //修改和添加时走的同一个方法
  if (this.form.id) {//表示修改
    //本质发出ajax请求-异步处理
    request.put("/api/update", this.form).then(res => {
      // console.log("res=", res);
      if (res.code === 200) {//修改成功
        //提示一个成功的消息框
        this.$message({
          message: "修改成功",
          type: "success",
        });
      } else {
        this.$message({
          message: "修改失败",
          type: "error",
        });
      }
    })
  } else {//表示添加
    //解读
    //1.url: http://localhost:8080/ssm/save
    //2.this.form: 携带的数据
    request.post("/api/save", this.form).then(res => {
      // console.log("res=", res);
    });
  }
  //关闭对话框
  this.dialogVisible = false;
  //调用list方法, 刷新数据
  this.list();
  //这里有一个注意事项...
},

实现功能06-删除家居信息

需求分析/图解

思路分析

在这里插入图片描述

代码实现

1.修改FurnService.javaFurnServiceImpl.java, 增加del方法

//删除家居
public void del(Integer id);
@Override
public void del(Integer id) {
    furnMapper.deleteByPrimaryKey(id);
}

2.修改FurnServiceTest.java, 测试del方法.

@Test
public void del() {
    furnService.del(22);
    System.out.println("删除成功");
}

3.修改FurnController.java, 处理修改请求, 并使用Postman完成测试.
URL占位符

/**
 * 1.响应客户端的删除请求
 * @param furn
 * @return
 */
@DeleteMapping("/del/{id}")
@ResponseBody
public Msg del(@PathVariable("id") Integer id) {
    furnService.del(id);
    //没有抛出异常, 就返回成功信息
    Msg success = Msg.success();
    return success;
}

在这里插入图片描述

4.修改HomeView.vue, 编写handleDel方法, 完成删除 并测试.

<el-table-column fixed="right" label="操作" width="120">
  <!--说明
  1.这里通过 handleEdit(scope.row)
  2.可以将当前行数据传递给 handleEdit
  -->
  <template #default="scope">
    <el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
    <!--说明
    1.如果你点击的是确定, 就会触发handleDel
    2.如果你点击的是取消, 就不会触发handleDel
    -->
    <el-popconfirm title="确定要删除吗?" @confirm="handleDel(scope.row.id)">
      <template #reference>
        <el-button size="small" type="danger">删除</el-button>
      </template>
    </el-popconfirm>
  </template>
</el-table-column><el-table-column fixed="right" label="操作" width="120">
  <!--说明
  1.这里通过 handleEdit(scope.row)
  2.可以将当前行数据传递给 handleEdit
  -->
  <template #default="scope">
    <el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
    <!--说明
    1.如果你点击的是确定, 就会触发handleDel
    2.如果你点击的是取消, 就不会触发handleDel
    -->
    <el-popconfirm title="确定要删除吗?" @confirm="handleDel(scope.row.id)">
      <template #reference>
        <el-button size="small" type="danger">删除</el-button>
      </template>
    </el-popconfirm>
  </template>
</el-table-column>
handleDel(id) {
  console.log("id=", id);
  request.delete('/api/del/' + id).then(res => {
    if (res.code === 200) {//删除成功
      this.$message({
        message: res.msg,
        type: "success",
      });
    } else {//删除失败
      this.$message({
        message: res.msg,
        type: "error",
      });
    }
    //调用list方法, 刷新数据
    this.list();
  })
},

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

课后作业

1.把前面我们实现的 Vue+SSM 各个功能, 自己写一遍.
- 一定要自己写一遍, 否则没有印象, 理解不会深入.
- 如果出现问题, 一定是代码问题, 要静下心来, 认真排查, 要逐步锻炼自己的排错能力.

2.修改家居信息功能, 回显家居表单数据, 改成从后端-DB获取

●代码实现
1.修改FurnService.javaFurnServiceImpl.java, 增加findFurnById方法

//根据id查询家居信息
public Furn findFurnById(Integer id);
@Override
public Furn findFurnById(Integer id) {
    return furnMapper.selectByPrimaryKey(id);
}

2.修改FurnServiceTest.java, 测试findFurnById方法.

@Test
public void findFurnById() {
    Furn furn = furnService.findFurnById(7);
    System.out.println("furn--" + furn);
}

3.修改FurnController.java, 处理修改请求, 并使用Postman完成测试.

/**
 * 1.响应客户端的查询请求
 * @param furn
 * @return
 */
@GetMapping("/findFurnById/{id}")
@ResponseBody
public Msg findFurnById(@PathVariable("id") Integer id) {
    Furn furn = furnService.findFurnById(id);
    //没有抛出异常, 就返回成功信息
    return Msg.success().add("furn", furn);
}

在这里插入图片描述

4.修改HomeView.vue, 编写handleEdit方法, 并测试.

handleEdit(row) {
  // console.log("row--", row);
  //将当前的家居信息绑定到弹出对话框的表单上
  //1. 方式1: 可以通过row.id 到后端-DB去获取对应的家居信息, 返回后将其绑定到this.form[小伙伴自己思考解决]
  request.get('/api/findFurnById/' + row.id).then(res => {
    this.form = res.extend.furn;
  })

  //2. 方式2: 把获取的row的数据通过处理, 绑定到this.form 进行显示
  //3. JSON.stringify(row): 将row 转成json字符串
  //4. JSON.parse(JSON.stringify(row)) 将json字符串 转成json对象
  // this.form = JSON.parse(JSON.stringify(row));

  //显示对话框
  this.dialogVisible = true;
},

在这里插入图片描述

实现功能07-分页显示列表

需求分析/图解

在这里插入图片描述

思路分析

1.后台使用MyBatis PageHelper插件完成分页查询.前端使用分页组件.

2.修改FurnController, 增加处理分页显示代码 API/接口

3.完成前台代码, 加入分页导航, 并将分页请求和后台接口结合.

4.简单回顾JavaWeb原生项目的分页模型. 说明: 有了MyBatis PageHelper和前端的分页组件, 完成分页就非常的方便, 但是底层的分页模型和前面我们的java web原生项目一样.

代码实现

1.修改pom.xml, 加入分页插件

<!--引入mybatis pageHelper分页插件-->
<dependency>
  <groupId>com.github.pagehelper</groupId>
  <artifactId>pagehelper</artifactId>
  <version>5.2.1</version>
</dependency>

2.修改mybatis-config.xml, 配置分页拦截器

<!--说明
1.plugins标签需要放在typeAliases标签后, 是DOCTYPE约束的
2.配置分页拦截器
-->
<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!--解读
        配置分页合理化
        1.如果用户请求的pageNum > pages, 就显示查询最后一页
        2.如果用户请求的pageNum < 0, 就显示查询第一页
        -->
        <property name="reasonable" value="true"/>
    </plugin>
</plugins>

3.修改FurnController.java, 增加分页查询处理

/**
 * 分页请求接口
 *
 * @param pageNum:  要显示第几页, 默认为1
 * @param pageSize: 每页要显示几条记录, 默认为5
 * @return
 */
@RequestMapping("/furnsByPage")
@ResponseBody
public Msg listFurnsByPage(@RequestParam(defaultValue = "1") Integer pageNum,
                           @RequestParam(defaultValue = "5") Integer pageSize) {
    //设置分页参数
    //解读
    //1.调用findAll完成查询, 底层会进行物理分页, 而不是逻辑分页
    //2.会根据分页参数来计算 limit ?, ?, 在发出sql语句时, 会带limit
    //3.我们后面会给大家抓取SQL
    PageHelper.startPage(pageNum, pageSize);

    List<Furn> furns = furnService.findAll();

    //将分页查询的结果, 封装到PageInfo
    //PageInfo 对象包含了分页的各个信息, 比如当前页面pageNum, 共有多少记录
    PageInfo pageInfo = new PageInfo(furns, pageSize);

    //将pageInfo封装到Msg对象, 返回
    return Msg.success().add("pageInfo", pageInfo);
}

4.使用Postman进行测试, 看看分页查询是否OK
在这里插入图片描述

数据包含在了list属性里

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

5.修改HomeView.vue, 完成分页导航显示, 分页请求. 给标签属性绑定值

1)添加分页导航控件

<div style="margin: 10px 0px">
  <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      v-bind:current-page="currentPage"
      v-bind:page-sizes="[5, 10]"
      v-bind:page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      v-bind:total="total">
  </el-pagination>
</div>

2)增加分页初始化数据

data() {
  return {
    //增加分页相应的数据绑定
    currentPage: 1,//当前页
    pageSize: 5,//每页显示记录数
    total: 10,//共有多少记录
  }
}

3)修改list方法, 换成分页请求数据的接口

list() {
  //请求分页的接口
  request.get("/api/furnsByPage", {
    params: {//指定请求携带的参数
      pageNum: this.currentPage,
      pageSize: this.pageSize,
    }
  }).then(res => {//处理返回的分页信息
    this.tableData = res.extend.pageInfo.list;
    this.total = res.extend.pageInfo.total;
  })
},

4)处理当前页变化, 比如点击分页链接, 或者go to 第几页

handleCurrentChange(pageNum) {//处理分页请求
  //当用户点击分页超链接时, 会携带pageNum
  // console.log("pageNum=", pageNum);
  this.currentPage = pageNum;
  //发出请求
  this.list();
},

5)处理每页显示多少条记录变化

handleSizeChange(pageSize) {
  this.pageSize = pageSize;
  //发出请求
  this.list();
},

完成测试

在这里插入图片描述

实现功能08-带条件查询分页显示列表

需求分析/图解

在这里插入图片描述

思路分析

1.完成后台代码从 dao ->service -> controller, 并对每层代码进行测试

2.完成前台代码, 使用axios发送http请求, 完成带条件查询分页显示

代码实现

1.修改FurnService.javaFurnServiceImpl.java, 增加条件查询

//根据家居名查询家居信息
public List<Furn> findByCondition(String name);
@Override
public List<Furn> findByCondition(String name) {
    FurnExample furnExample = new FurnExample();
    //通过criteria 对象可以设置查询条件
    FurnExample.Criteria criteria = furnExample.createCriteria();

    //判断name是否有具体的内容
    if (StringUtils.hasText(name)) {
        criteria.andNameLike("%" + name + "%");
    }
    //说明: 如果没有传值, 即为null, "", "   "时, 依然是查询所有的记录
    return furnMapper.selectByExample(furnExample);
}

2.修改FurnServiceTest.java, 测试findByCondition方法.

@Test
public void findByCondition() {
    List<Furn> furns = furnService.findByCondition("风格");
    for (Furn furn : furns) {
        System.out.println("furn--" + furn);
    }
}

3.修改FurnController.java, 处理带条件分页查询, 并使用Postman完成测试.

/**
 * 根据家居名进行分页查询-带条件
 *
 * @param pageNum
 * @param pageSize
 * @return
 */
@RequestMapping("/furnsByConditionPage")
@ResponseBody
public Msg listFurnsByCondition(@RequestParam(defaultValue = "1") Integer pageNum,
                                @RequestParam(defaultValue = "5") Integer pageSize,
                                @RequestParam(defaultValue = "") String search) {
    //设置分页参数
    //解读
    //1.调用findAll完成查询, 底层会进行物理分页, 而不是逻辑分页
    //2.会根据分页参数来计算 limit ?, ?, 在发出sql语句时, 会带limit
    //3.我们后面会给大家抓取SQL
    PageHelper.startPage(pageNum, pageSize);

    List<Furn> furns = furnService.findByCondition(search);

    //将分页查询的结果, 封装到PageInfo
    //PageInfo 对象包含了分页的各个信息, 比如当前页面pageNum, 共有多少记录
    PageInfo pageInfo = new PageInfo(furns, pageSize);

    //将pageInfo封装到Msg对象, 返回
    return Msg.success().add("pageInfo", pageInfo);
}

在这里插入图片描述

4.修改HomeView.vue

<!--margin: 顶部距离 左侧距离-->
<div style="margin: 10px 5px">
  <el-input v-model="search" style="width: 20%" placeholder="请输入家居名"/>
  <el-button style="margin: 10px" type="primary" @click="list">检索</el-button>
</div>

数据池

data() {
  return {
    search: '',//检索条件, 可以在进行分页时保留上次的检索条件
  }
},

list方法

list() {
  //请求分页的接口-带检索条件
  request.get("/api/furnsByConditionPage", {
    params: {//指定请求携带的参数
      pageNum: this.currentPage,
      pageSize: this.pageSize,
      search: this.search,
    }
  }).then(res => {//处理返回的分页信息
    this.tableData = res.extend.pageInfo.list;
    this.total = res.extend.pageInfo.total;
  })
},

5.测试
在这里插入图片描述

实现功能09-添加家居表单前端校验

需求分析/图解

在这里插入图片描述

在这里插入图片描述

说明: 参考 element-plus 表单验证

思路分析

1.完成前台代码, 使用ElementPlus的表单 rules 验证即可

2.参考element-plus 表单验证文档

代码实现

1.修改HomeView.vue, 增加表单验证处理代码. 验证数字
增加对表单各个字段的校验规则

data() {
  return {
    //定义添加表单校验规则
    rules: {
      name: [
        //这里我们可以写多个针对name属性的校验规则
        {required: true, message: "请输入家居名", trigger: "blur"}
      ],
      maker: [
        //这里我们可以写多个针对maker属性的校验规则
        {required: true, message: "请输入厂商", trigger: "blur"}
      ],
      price: [
        //这里我们可以写多个针对price属性的校验规则
        {required: true, message: "请输入价格", trigger: "blur"},
        //使用正则表达式对输入的数据进行校验
        {pattern: /^([1-9]\d*|0)(\.\d+)?$/, message: "请输入数字", trigger: "blur"}
      ],
      sales: [
        //这里我们可以写多个针对sales属性的校验规则
        {required: true, message: "请输入销量", trigger: "blur"},
        {pattern: /^([1-9]\d*|0)$/, message: "请输入数字", trigger: "blur"}
      ],
      stock: [
        //这里我们可以写多个针对stock属性的校验规则
        {required: true, message: "请输入库存", trigger: "blur"},
        {pattern: /^([1-9]\d*|0)$/, message: "请输入数字", trigger: "blur"}
      ],
    }
  }
},

指定将创建的规则引用到form表单, 注意名称要对应
在这里插入图片描述

2.测试, 就可以看到验证规则生效了. 是光标离开输出框时, 出现检验效果, 因为是trigger: "blur"事件, 但是用户提交还是能成.

3.修改HomeView.vue, 但表单验证不通过时, 不提交表单
修改save方法

save() {//将填写的表单数据,发送给后端
  //修改和添加时走的同一个方法
  if (this.form.id) {//表示修改
    //本质发出ajax请求-异步处理
    //...
  } else {//表示添加
    //表单验证是否通过
    this.$refs['form'].validate(valid => {
      //valid就是表单校验后返回的结果
      if (valid) {//如果校验通过
        //解读
        //1.url: http://localhost:8080/ssm/save
        //2.this.form: 携带的数据
        request.post("/api/save", this.form).then(res => {
          // console.log("res=", res);
          //关闭对话框
          this.dialogVisible = false;
          //调用list方法, 刷新数据
          this.list();
        });
      } else {//校验没有通过
        this.$message({
          type: "error",
          message: "表单校验失败, 不提交"
        })
        return false;//放弃提交
      }
    })
  }
  //这里有一个注意事项...
},

修改add方法

add() {//显示添加对话框-带表单
  //显示对话框
  this.dialogVisible = true;
  //情况添加表单数据
  this.form = {};
  //清空上次校验的信息
  this.$refs['form'].resetFields();
},

在这里插入图片描述

实现功能10-添加家居表单后端校验

需求分析/图解

1.为什么前端校验了, 后端还需要校验? -使用Postman添加数据, 打破前端校验机制
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

2.后端校验-需求分析, 但后端校验没有通过, 会出现灰色框提示, 后台不真正入库数据在这里插入图片描述

思路分析

1.后台 使用JSR303数据校验, 引入hibernate-validator.jar, 学习SpringMVC JSR303校验时遇到过.

2.前端 使用ElementPlus进行数据绑定, 并显示错误信息

代码实现

1.修改pom.xml, 引入hibernate-validator jar文件

<!--JSR303数据校验支持引入hibernate-validator-->
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-validator</artifactId>
  <version>6.1.1.Final</version>
</dependency>

2.修改Furn.java, 使用hibernate-validator

@NotEmpty(message = "请输入家居名")
private String name;

@NotEmpty(message = "请输入厂商")
private String maker;

@NotNull(message = "请输入数字")
@Range(min = 0, message = "价格不能小于0")
private BigDecimal price;

@NotNull(message = "请输入数字")
@Range(min = 0, message = "销量不能小于0")
private Integer sales;

@NotNull(message = "请输入数字")
@Range(min = 0, message = "库存不能小于0")
private Integer stock;

3.修改FurnController.java, 处理带条件分页查询, 并使用Postman完成测试.

@PostMapping("/save")
@ResponseBody
public Msg save(@Validated @RequestBody Furn furn, Errors errors) {
    Map<String, Object> map = new HashMap<>();

    List<FieldError> fieldErrors = errors.getFieldErrors();

    for (FieldError fieldError : fieldErrors) {
        map.put(fieldError.getField(), fieldError.getDefaultMessage());
    }

    if (map.isEmpty()) {//说明后端校验通过, 因为没有发现校验错误
        furnService.save(furn);
        //没有抛出异常, 就返回成功信息
        Msg success = Msg.success();
        return success;
    } else {
        //校验失败, 就把错误信息封装到Msg对象, 并返回
        return Msg.fail().add("errors", map);
    }
}

在这里插入图片描述在这里插入图片描述在这里插入图片描述
4.修改HomeView.vue, 显示服务器校验返回的提示信息
在数据池, 增加显示错误信息的变量

data() {
  return {
    //存放后端校验的错误信息
    serverValidErrors: {},
  }
},

修改save方法, 显示错误提示

if (valid) {//如果校验通过
  //解读
  //1.url: http://localhost:8080/ssm/save
  //2.this.form: 携带的数据
  request.post("/api/save", this.form).then(res => {
    console.log("res=", res);
    if (res.code === 200) {//添加成功
      //关闭对话框
      this.dialogVisible = false;
      //调用list方法, 刷新数据
      this.list();
    } else {//后端校验失败
      //取出校验失败的信息, 赋给serverValidErrors
        this.serverValidErrors.name = res.extend.errors.name;
        this.serverValidErrors.maker = res.extend.errors.maker;
        this.serverValidErrors.price = res.extend.errors.price;
        this.serverValidErrors.sales = res.extend.errors.sales;
        this.serverValidErrors.stock = res.extend.errors.stock;
    }
  });
}

修改对话框, 显示后台返回的校验错误信息

<el-form ref="form" :model="form" :rules="rules" label-width="120px" style="width: 80%">
  <el-form-item label="家居名" prop="name">
    <el-input v-model="form.name" style="width: 50%"/>
    {{serverValidErrors.name}}
  </el-form-item>
  <el-form-item label="厂商" prop="maker">
    <el-input v-model="form.maker" style="width: 50%"/>
    {{serverValidErrors.maker}}
  </el-form-item>
  <el-form-item label="价格" prop="price">
    <el-input v-model="form.price" style="width: 50%"/>
    {{serverValidErrors.price}}
  </el-form-item>
  <el-form-item label="销量" prop="sales">
    <el-input v-model="form.sales" style="width: 50%"/>
    {{serverValidErrors.sales}}
  </el-form-item>
  <el-form-item label="库存" prop="stock">
    <el-input v-model="form.stock" style="width: 50%"/>
    {{serverValidErrors.stock}}
  </el-form-item>
</el-form>

为了触发后端校验, 先把前端校验解除

} else {//表示添加
  //表单验证是否通过
  this.$refs['form'].validate(valid => {
    //这里我们让前端校验放行, 测试后端校验的效果, 测试完毕, 再改回来
    valid = true;
    //valid就是表单校验后返回的结果
    if (valid) {//如果校验通过

测试
在这里插入图片描述

修改add()方法, 清空错误信息

add() {//显示添加对话框-带表单
  //显示对话框
  this.dialogVisible = true;
  //情况添加表单数据
  this.form = {};
  //清空上次前端校验的信息
  this.$refs['form'].resetFields();
  //清空上次后端校验的信息
  this.serverValidErrors = {};
},

在这里插入图片描述

下一讲, 我们学习 SSM整合-前后端分离(实现分页+前后端校验)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1837299.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信ipad协议8049新版本

首先我们要先了解下ipad协议是什么 &#xff0c;ipad协议又叫微信协议 是基于微信IPad协议的智能控制系统帮助企业快速连接客户&#xff0c;创造营销氛围&#xff0c;实现自动获客、自动传播、自动转化、智能营销等分布式营销服务。 通过API 实现 个性化微信功能 &#xff08;例…

和鲸101计划:以神经计算建模培训,助力北大学术人才培养

探索与求知&#xff0c;培养与传承。 让青年人更早地触摸到科学研究的前沿&#xff0c;便能吸引更多人才投身于学科建设。 11月4日&#xff0c;由北京大学信息处理实验室开展进行&#xff0c;北京大学心理与认知科学学院院长吴思教授及课题组成员授课的第二届神经计算建模及编…

Python 自动化测试入门有哪些内容?

自动化测试是软件测试领域中的一个重要技术&#xff0c;它利用脚本和工具来执行测试任务&#xff0c;减少了人工操作的工作量和时间消耗。Python 是一种功能强大且易于学习的编程语言&#xff0c;被广泛应用于自动化测试领域。本文将从0到1讲解如何使用 Python 进行自动化测试&…

全开源版人才招聘系统源码 小程序运营级平台源码 类似58同城招聘、智联招聘平台

在当今数字化时代&#xff0c;人才招聘与平台运营成为了企业发展的重要环节。分享一套功能全面、易于二次开发的人才招聘系统源码小程序运营级平台源码。这些源码基于类似58同城招聘、智联招聘等大型招聘平台的设计理念&#xff0c;旨在为企业提供高效、便捷的人才招聘与平台运…

企业电脑防泄密软件有哪些|电脑防泄密软件“琅琊榜”排名

企业电脑防泄密软件是用于保护企业内部数据安全、防止敏感信息泄露的专业工具。电脑防泄密软件“琅琊榜”都有哪些呢&#xff1f;以下是八款推荐的防泄密软件。 电脑防泄密软件“琅琊榜”&#xff1a; 1.安企神 - 综合性防泄密解决方案&#xff0c;包括上网行为审计、文档加密…

千锋Vue学习笔记

千锋Vue学习笔记 我终于抓到申请宝贝啦&#xff01; ——20240618 文章目录 千锋Vue学习笔记写在前面1. 前言2. 模板语法3. 组件4. 生命周期5. swiper6. 指令7. vue-cli8. Vue.config.js9. 路由10. 小练习和组件库11. vuex12. git13. nginx14. Vue315. ts16. Vue3补充1-前言2-…

Ubuntu24多版本python解释器使用

1.前言 已给树莓派5安装了Ubuntu24.04&#xff0c;带有python3.12.3&#xff0c;现在用视觉需要用到3.11版本的python解释器 2.实操过程 主要是对用到的命令进行备份&#xff0c;方便后面查询 2.1 安装python3.11 sudo add-apt-repository ppa:deadsnakes/ppa sudo apt-ge…

香港优才,申请材料信息差!中介不会告诉你~

这两年diy申请香港优才身份的人非常多&#xff0c;获批都过万~但是被拒的数量更多~ 我就是打破信息差&#xff0c;快人一步申请&#xff0c;获批也早一点。就我经验来说&#xff0c;材料非常重要&#xff0c;因为申请佐证材料不足被拒的人非常多。 香港优才材料常见注意事项 …

基于SpringBoot+Vue会所产后护理系统设计和实现

基于SpringBootVue会所产后护理系统设计和实现 &#x1f345; 作者主页 网顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &#…

java 导出excel表格POI - XSSFWorkbook,自定义各种格式,多级表格,同一个sheet按照天往后排列

maven的依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version><scope>compile</scope></dependency><dependency><groupId>org.apache.poi</…

超级会员卡积分收银小程序源码系统,在线充值+商家核销+在线下单 附带源代码+搭建部署教程

系统概述 在当今数字化快速发展的时代&#xff0c;移动支付已经成为人们生活中不可或缺的一部分。为了满足商家和消费者对于便捷、高效支付体验的需求&#xff0c;超级会员卡积分收银小程序源码系统应运而生。本文将深入介绍该源码系统的开发背景及其特色功能&#xff0c;附带…

【Linux环境下Hadoop部署】—报错“Unit ntpd.service could not be found.“

项目场景&#xff1a; 执行 “systemctl status ntpd” 命令。 问题描述 报错&#xff1a;Unit ntpd.service could not be found. 原因分析&#xff1a; 没有安装ntp 解决方案&#xff1a; 执行 “yum install ntp” 命令&#xff0c;再次执行 “systemctl status ntpd” 命令…

python 【包含数据预处理】基于词频生成词云图

基于词频生成词云图 背景目的 有一篇中文文章&#xff0c;或者一本小说。想要根据词频来生成词云图。 为什么中文需要分词 中文分词是理解和处理中文文本的关键步骤&#xff0c;它直接影响到后续的文本分析和信息提取的准确性和有效性。 无明显单词分隔&#xff1a;中文文本不…

HTML5基本语法

文章目录 HTML5基本语法一、基础标签1、分级标题2、段标签3、换行及水平线标签4、文本格式标签 二、图片标签1、格式2、属性介绍 三、音频标签1、格式2、属性介绍 四、视频标签1、格式2、属性介绍 五、链接标签1、格式2、显示特点3、属性介绍4、补充&#xff08;空链接&#xf…

【C++】Template模板

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

Boom3D软件下载-Boom3D音效增强工具下载附加详细安装步骤

Boom3D音效增强工具是一款便捷的为用户们进行音频处理和编辑的软件&#xff0c;支持用户们轻松的进行音频的使用&#xff0c;支持超多的音频格式让你可以轻松的进行使用&#xff0c;Boom3D音效增强工具拥有多种音频特效的功能&#xff0c;让你可以在Boom3D音效增强工具轻松的进…

Python办公自动化实例--照片挑选

实例背景 学院举行毕业晚会&#xff0c;要制作照片墙&#xff0c;让学生自己上传一直没有多少回应&#xff0c;上传的没有几张&#xff08;学院的号召力是真的拉&#xff09;&#xff0c;需要从整个学校的学生证件照中挑选出外面学院的同学&#xff0c;于是这个“艰巨”的任务…

Avalonia:一个.NET跨平台UI框架

概述 Avalonia是一个强大的框架&#xff0c;使开发人员能够使用. NET创建跨平台应用程序。它使用自己的渲染引擎来绘制UI控件&#xff0c;确保在各种平台上保持一致的外观和行为&#xff0c;包括Windows&#xff0c;macOS&#xff0c;Linux&#xff0c;Android&#xff0c;iOS…

轻轻松松上手的LangChain学习说明书

本文为笔者学习LangChain时对官方文档以及一系列资料进行一些总结&#xff5e;覆盖对Langchain的核心六大模块的理解与核心使用方法&#xff0c;全文篇幅较长&#xff0c;共计50000字&#xff0c;可先码住辅助用于学习Langchain。 一、Langchain是什么&#xff1f; 如今各类AI…

大模型面试指南:掌握关键技术与策略,成功应对面试挑战

随着人工智能技术的快速发展&#xff0c;大型预训练模型在自然语言处理、计算机视觉、语音识别等领域取得了显著成果。这些模型通过在海量数据上进行预训练&#xff0c;能够捕捉到丰富的特征信息&#xff0c;为各种下游任务提供强大的支持。在求职面试中&#xff0c;掌握大模型…