【接口设计】为 APP、PC、H5 网页提供统一风格的 API(实战篇,附源码地址)

news2024/11/15 12:09:01

为 APP、PC、H5 网页提供统一风格的 API

  • 1.实现文章实体
  • 2.实现数据持久层
  • 3.实现服务接口和服务接口的实现类
    • 3.1 创建服务接口
    • 3.2 编写服务接口的实现
  • 4.处理返回结果
    • 4.1 实现响应的枚举类
    • 4.2 实现返回的对象实体
    • 4.3 封装返回结果
  • 4.统一处理异常
    • 4.1 全局捕捉异常
    • 4.2 自定义异常类
  • 5.控制器
    • 5.1 自定义业务测试控制器
    • 5.2 实现数据的 CRUD 控制器
  • 6.测试数据
    • 6.1 添加数据
    • 6.2 获取数据列表
    • 6.3 查询数据
    • 6.3 修改数据
    • 6.4 删除数据
    • 6.5 访问不存在的数据

项目的目录结构如下:

在这里插入图片描述

🚀 GitHub 地址:https://github.com/Beracle/RESTful-Example

1.实现文章实体

package com.example.demo.entity;

import lombok.Data;
import lombok.Getter;
import javax.persistence.*;

@Entity
@Table(name = "article")
@Data
public class Article {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private String title;
    private String body;
}

在这里插入图片描述

2.实现数据持久层

package com.example.demo.repository;

import com.example.demo.entity.Article;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface ArticleRepository extends JpaRepository<Article,Long>, JpaSpecificationExecutor<Article> {
    Article findById(long id);
}

3.实现服务接口和服务接口的实现类

在这里插入图片描述

3.1 创建服务接口

package com.example.demo.service;

import com.example.demo.entity.Article;
import java.util.List;

public interface ArticleService {
    public List<Article> getArticleList();
    public Article findArticleById(long id);
}

3.2 编写服务接口的实现

package com.example.demo.service.impl;

import com.example.demo.entity.Article;
import com.example.demo.repository.ArticleRepository;
import com.example.demo.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ArticleServiceImpl implements ArticleService {
    @Autowired
    private ArticleRepository articleRepository;

    @Override
    public List<Article> getArticleList() {
        return articleRepository.findAll();
    }

    @Override
    public Article findArticleById(long id) {
        return articleRepository.findById(id);
    }
}

4.处理返回结果

4.1 实现响应的枚举类

枚举 是一种特殊的数据类型,它是一种 “类类型”,比类型多了一些特殊的约束。创建枚举类型要使用 enum,表示所创建的类型都是 java.lang.Enum 类(抽象类)的子类。

🚀 枚举类默认继承 java.lang.Enum 类,而不是 Object 类,因此枚举类不能显式继承其他父类。
🚀 枚举类的构造器只能使用 private 访问控制符,如果忽略访问控制符的话,则默认使用 private 修饰;如果强制指定其他的访问控制符(例如 publicprocted 等),则会报错。
🚀 枚举类的所有实例必须在枚举类的第一行显示列出,否则这个枚举类永远都不可能产生实例。列出的这些实例,系统会自动给它们加上 public static final 修饰(无需程序员手动添加)。枚举类的实例 以逗号分隔,分号结束,这些列出的枚举值代表了该枚举类的所有可能的实例。

package com.example.demo.result;

// 实现响应的枚举类
public enum ExceptionMsg {
    SUCCESS("200", "操作成功"),
    FAILED("999999", "操作失败"),
    ParamError("000001", "参数错误!"),
    FileEmpty("000400", "上传文件为空"),
    LimitPictureSize("000401", "图片大小必须小于2M"),
    LimitPictureType("000402", "图片格式必须为'jpg'、'png'、'jpge'、'gif'、'bmp'");

	private String code;
    private String msg;
    
    // 自定义构造函数
    private ExceptionMsg(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public String getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

4.2 实现返回的对象实体

实现返回的 对象实体,返回 CodeMessage(信息),见以下代码:

package com.example.demo.result;

// 实现返回对象实体
public class Response {

    // 返回信息码
    private String rspCode = "000000";
    // 返回信息内容
    private String rspMsg = "操作成功";

    public Response() {
    }

    public Response(ExceptionMsg msg) {
        this.rspCode = msg.getCode();
        this.rspMsg = msg.getMsg();
    }

    public Response(String rspCode) {
        this.rspCode = rspCode;
        this.rspMsg = "";
    }

    public Response(String rspCode, String rspMsg) {
        this.rspCode = rspCode;
        this.rspMsg = rspMsg;
    }

    public String getRspCode() {
        return rspCode;
    }

    public void setRspCode(String rspCode) {
        this.rspCode = rspCode;
    }

    public String getRspMsg() {
        return rspMsg;
    }

    public void setRspMsg(String rspMsg) {
        this.rspMsg = rspMsg;
    }

    @Override
    public String toString() {
        return "Response{" +
                "rspCode='" + rspCode + '\'' +
                ", rspMsg='" + rspMsg + '\'' +
                '}';
    }
}

4.3 封装返回结果

这里把返回的结果进行封装,以显示 数据,见以下代码:

package com.example.demo.result;

// 返回结果数据格式封装
public class ResponseData extends Response {
    private Object data;

    public ResponseData(Object data) {
        this.data = data;
    }

    public ResponseData(ExceptionMsg msg) {
        super(msg);
    }

    public ResponseData(String rspCode, String rspMsg) {
        super(rspCode, rspMsg);
    }

    public ResponseData(String rspCode, String rspMsg, Object data) {
        super(rspCode, rspMsg);
        this.data = data;
    }

    public ResponseData(ExceptionMsg msg, Object data) {
        super(msg);
        this.data = data;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "ResponseData{" +
                "data=" + data +
                "} " + super.toString();
    }
}

4.统一处理异常

4.1 全局捕捉异常

package com.example.demo.exception;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.*;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@RestControllerAdvice
public class GlobalExceptionHandler {
    // 日志记录工具
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Map<String, Object> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        logger.error("缺少请求参数", e);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("rspCode", 400);
        map.put("rspMsg", e.getMessage());
        //发生异常进行日志记录,写入数据库或者其他处理,此处省略
        return map;
    }

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Map<String, Object> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        logger.error("参数解析失败", e);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("rspCode", 400);
        map.put("rspMsg", e.getMessage());
        //发生异常进行日志记录,写入数据库或者其他处理,此处省略
        return map;
    }

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Map<String, Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        logger.error("参数验证失败", e);
        BindingResult result = e.getBindingResult();
        FieldError error = result.getFieldError();
        String field = error.getField();
        String code = error.getDefaultMessage();
        String message = String.format("%s:%s", field, code);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("rspCode", 400);
        map.put("rspMsg", message);
        //发生异常进行日志记录,写入数据库或者其他处理,此处省略
        return map;
    }

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(BindException.class)
    public Map<String, Object> handleBindException(BindException e) {
        logger.error("参数绑定失败", e);
        Map<String, Object> map = new HashMap<String, Object>();
        BindingResult result = e.getBindingResult();
        FieldError error = result.getFieldError();
        String field = error.getField();
        String code = error.getDefaultMessage();
        String message = String.format("%s:%s", field, code);
        map.put("rspCode", 400);
        map.put("rspMsg", message);
        //发生异常进行日志记录,写入数据库或者其他处理,此处省略
        return map;
    }


    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(ConstraintViolationException.class)
    public Map<String, Object> handleServiceException(ConstraintViolationException e) {
        logger.error("参数验证失败", e);
        Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
        ConstraintViolation<?> violation = violations.iterator().next();
        String message = violation.getMessage();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("rspCode", 400);
        map.put("rspMsg", message);
        //发生异常进行日志记录,写入数据库或者其他处理,此处省略
        return map;
    }

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(ValidationException.class)
    public Map<String, Object> handleValidationException(ValidationException e) {
        logger.error("参数验证失败", e);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("rspCode", 400);
        map.put("rspMsg", e.getMessage());
        //发生异常进行日志记录,写入数据库或者其他处理,此处省略
        return map;
    }

    /**
     * 405 - Method Not Allowed
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Map<String, Object> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        logger.error("不支持当前请求方法", e);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("rspCode", 405);
        map.put("rspMsg", e.getMessage());
        //发生异常进行日志记录,写入数据库或者其他处理,此处省略
        return map;
    }

    /**
     * 415 - Unsupported Media Type
     */
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public Map<String, Object> handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) {
        logger.error("不支持当前媒体类型", e);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("rspCode", 415);
        map.put("rspMsg", e.getMessage());
        //发生异常进行日志记录,写入数据库或者其他处理,此处省略
        return map;
    }

    /**
     * 自定义异常类
     */
    @ResponseBody
    @ExceptionHandler(BusinessException.class)
    public Map<String, Object> businessExceptionHandler(BusinessException e) {
        logger.error("自定义业务失败", e);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("rspCode", e.getCode());
        map.put("rspMsg", e.getMessage());
        //发生异常进行日志记录,写入数据库或者其他处理,此处省略
        return map;
    }


    /**
     * 获取其它异常。包括500
     *
     * @param e
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = Exception.class)
    public Map<String, Object> defaultErrorHandler(Exception e) {
        logger.error("Exception", e);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("rspCode", 500);
        map.put("rspMsg", e.getMessage());
        //发生异常进行日志记录,写入数据库或者其他处理,此处省略
        return map;
    }
}

在这里插入图片描述

4.2 自定义异常类

package com.example.demo.exception;

public class BusinessException extends RuntimeException {
    //自定义错误码
    private Integer code;

    // 自定义构造器,必须输入错误码及内容
    public BusinessException(int code, String msg) {
        super(msg);
        this.code = code;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }
}

5.控制器

5.1 自定义业务测试控制器

package com.example.demo.controller;

import com.example.demo.exception.BusinessException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.ValidationException;

@RestController
public class TestController {
    @RequestMapping("/BusinessException")
    public String testResponseStatusExceptionResolver(@RequestParam("i") int i) {
        if (i == 0) {
            throw new BusinessException(600, "自定义业务错误");
        }
        throw new ValidationException();
    }
}

在这里插入图片描述

5.2 实现数据的 CRUD 控制器

实现数据的 增加删除修改删除 控制器,并实现数据的返回,见以下代码:

package com.example.demo.controller;

import com.example.demo.entity.Article;
import com.example.demo.repository.ArticleRepository;
import com.example.demo.result.ExceptionMsg;
import com.example.demo.result.Response;
import com.example.demo.result.ResponseData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("article")
public class ArticleController {
    protected Response result(ExceptionMsg msg) {
        return new Response(msg);
    }

    protected Response result() {
        return new Response();
    }

    @Autowired
    private ArticleRepository articleRepository;
    @Autowired
    RestTemplateBuilder restTemplateBuilder;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ResponseData getArticleList() {
        List<Article> list = new ArrayList<Article>(articleRepository.findAll());
        return new ResponseData(ExceptionMsg.SUCCESS, list);
    }

    //增
    @RequestMapping(value = "/", method = RequestMethod.POST)
    public ResponseData add(Article article) {
        articleRepository.save(article);
        return new ResponseData(ExceptionMsg.SUCCESS, article);
    }

    //删
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public Response delete(@PathVariable("id") long id) {
        articleRepository.deleteById(id);
        return result(ExceptionMsg.SUCCESS);
    }

    //改
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    public ResponseData update(Article model) {
        articleRepository.save(model);
        return new ResponseData(ExceptionMsg.SUCCESS, model);
    }

    //查
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public ResponseData findArticle(@PathVariable("id") Integer id) throws IOException {
        Article article = articleRepository.findById(id);
        if (article != null) {
            return new ResponseData(ExceptionMsg.SUCCESS, article);
        }
        return new ResponseData(ExceptionMsg.FAILED, article);
    }

    //查
    @RequestMapping(value = "/re/{id}", method = RequestMethod.GET)
    public Article findArticled(@PathVariable("id") Integer id) throws IOException {
        RestTemplate client = restTemplateBuilder.build();
        String uri = "http://localhost:8080/article/" + id;
        System.out.println(uri);
        Article article = client.getForObject(uri, Article.class, id);
        return article;
    }
}

6.测试数据

6.1 添加数据

用 POST 方式访问 http://localhost:8080/article/,提交 Article 实体。

//增
@RequestMapping(value = "/", method = RequestMethod.POST)
public ResponseData add(Article article) {
    articleRepository.save(article);
    return new ResponseData(ExceptionMsg.SUCCESS, article);
}

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

6.2 获取数据列表

用 GET 方法访问 http://localhost:8080/article/

@RequestMapping(value = "/", method = RequestMethod.GET)
public ResponseData getArticleList() {
    List<Article> list = new ArrayList<Article>(articleRepository.findAll());
    return new ResponseData(ExceptionMsg.SUCCESS, list);
}

在这里插入图片描述

6.3 查询数据

查询刚刚添加的数据。用 GET 方法访问 http://localhost:8080/article/1

//查
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseData findArticle(@PathVariable("id") Integer id) throws IOException {
    Article article = articleRepository.findById(id);
    if (article != null) {
        return new ResponseData(ExceptionMsg.SUCCESS, article);
    }
    return new ResponseData(ExceptionMsg.FAILED, article);
}

在这里插入图片描述

6.3 修改数据

用 PUT 方法访问 http://localhost:8080/article/1

//改
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public ResponseData update(Article model) {
    articleRepository.save(model);
    return new ResponseData(ExceptionMsg.SUCCESS, model);
}

在这里插入图片描述

6.4 删除数据

用 DELETE 方法访问 http://localhost:8080/article/1

//删
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public Response delete(@PathVariable("id") long id) {
    articleRepository.deleteById(id);
    return result(ExceptionMsg.SUCCESS);
}

如果返回以下结果,则代表删除成功。

在这里插入图片描述

6.5 访问不存在的数据

用 GET 方法访问 http://localhost:8080/article/0

// 查
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseData findArticle(@PathVariable("id") Integer id) throws IOException {
    Article article = articleRepository.findById(id);
    if (article != null) {
        return new ResponseData(ExceptionMsg.SUCCESS, article);
    }
    return new ResponseData(ExceptionMsg.FAILED, article);
}

在这里插入图片描述

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

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

相关文章

【防火墙】防火墙安全策略用户认证综合实验

实验拓扑及要求 拓扑搭建及IP配置 防火墙&#xff08;总公司&#xff09;和交换机&#xff08;汇聚生产区和办公区&#xff09;的接口配置 生产区在vlan2&#xff0c;办公区在vlan3&#xff0c;防火墙在G1/0/3接口上创建子接口G1/0/3.1和G1/0/3.2对两个区域分别进行管理 交换…

时间轮算法理解、Kafka实现

概述 TimingWheel&#xff0c;时间轮&#xff0c;简单理解就是一种用来存储若干个定时任务的环状队列&#xff08;或数组&#xff09;&#xff0c;工作原理和钟表的表盘类似。 关于环形队列&#xff0c;请参考环形队列。 时间轮由两个部分组成&#xff0c;一个环状数组&…

企业智能制造赋能的环境条件为什么重要?需要准备什么样的环境?

在全球制造业不断演进的今天&#xff0c;智能制造已经成为推动行业创新和转型的关键力量。它不仅代表了技术的革新&#xff0c;更是企业管理模式和运营思路的全面升级。然而&#xff0c;智能制造的落地实施并非一蹴而就&#xff0c;它需要企业在环境条件上做好充分的准备&#…

Study--Oracle-07-ASM自动存储管理(一)

一、ASM实例和数据库实例对应关系 1、ASM是Oracle 10g R2中为了简化Oracle数据库的管理而推出来的一项新功能&#xff0c;这是Oracle自己提供的卷管理器&#xff0c;主要用于替代操作系统所提供的LVM&#xff0c;它不仅支持单实例&#xff0c;同时对RAC的支持也是非常好。ASM可…

C语言 | Leetcode C语言题解之第231题2的幂

题目&#xff1a; 题解&#xff1a; const int BIG 1 << 30;bool isPowerOfTwo(int n) {return n > 0 && BIG % n 0; }

防火墙--NAT和智能选路的一些知识

目录 NAT 源NAT 包含 目标NAT 包含 双向NAT 防火墙中web页面的nat配置 新建NAT策略 各个选项意思及使用 NAT类型 转换模式 仅转换源地址选项 原始数据包就相当于抓取流量&#xff0c;相当于NAT中acl的配置 转换后的数据包就是转换后的公网地址 配置地址池 端口地…

低代码商城构建专家:Mall-Cook

Mall-Cook&#xff1a;用Mall-Cook&#xff0c;让电商创新触手可及- 精选真开源&#xff0c;释放新价值。 概览 Mall-Cook是一个面向未来的商城低代码开发平台&#xff0c;它通过提供直观的可视化界面&#xff0c;让开发者和商家能够快速构建和部署跨平台的电商解决方案。这个…

国产精品ORM框架-SqlSugar详解 进阶功能 集成整合 脚手架应用 专题二

国产精品ORM框架-SqlSugar详解 SqlSugar初识 专题一-CSDN博客 sqlsugar 官网-CSDN博客 4、进阶功能 5、集成整合 6、脚手架应用 4、进阶功能 4.1、生命周期 Queryable 什么时候操作库 Queryable是一个引用类型 Queryable拷贝机制 4.2、执行Sql 方法列表 方法名 描述 返…

秋招Java后端开发冲刺——MyBatisPlus总结

一、 基本知识 1. 介绍 yBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上增加了大量功能和简化操作&#xff0c;以提高开发效率。 2. 特点 无侵入&#xff1a;只做增强不做改变&#xff0c;引入它不会对现有项目产生影响。依赖少&#xff1a;仅仅依赖 …

智慧校园信息化大平台整体解决方案PPT(75页)

1. 教育信息化政策 教育部印发《教育信息化2.0行动计划》&#xff0c;六部门联合发布《关于推进教育新型基础设施建设构建高质量教育支撑体系的指导意见》&#xff0c;中共中央、国务院印发《中国教育现代化2035》。这些政策文件强调了教育的全面发展、面向人人、终身学习、因…

Linux对文件访问的基本权限

文件权限控制对文件的访问。 有三种权限类别可应用&#xff1a;读取、写入和执行。 权限对文件和目录的影响&#xff1a; 权限 对文件的影响 对目录的影响 r读取 可以读取文件的内容 可以列出目录的内容 w写入 可以更改文件的内容 可以创建或删除目录中任一文件 x执行…

uniapp 支付宝小程序 芝麻免押 免押金

orderStr参数如下&#xff1a; my.tradePay({orderStr:res, // 完整的支付参数拼接成的字符串&#xff0c;从 alipay.fund.auth.order.app.freeze 接口获取success: (res) > {console.log(免押成功);console.log(JSON.stringify(res),不是JOSN);console.log(JSON.stringify…

ClickHouse 查看表的大小

查看表的大小&#xff1a; 使用以下查询语句可以列出表及其占用的磁盘空间大小&#xff1a; SELECTtable,formatReadableSize(sum(bytes_on_disk)) AS size_on_disk FROM system.parts WHERE active GROUP BY table ORDER BY size_on_disk DESC

部署一台本机的ai智能模型

部署ai模型 1.打开地址搜 https://ollama.com/&#xff08;开源ai模型网址&#xff09;下载软件 2.点击安装具有羊驼图标的文件 3.在右下角查看 羊驼图标 4。打开脚本&#xff0c;执行可以切换羊驼安装的位置与环境变量 5.winR 输入cmd,在命令窗口输入ollama命令 如果安装成功…

底软驱动 | Linux字符设备驱动开发基础

文章目录 知识整理--Linux字符设备驱动开发基础字符设备基础1从一个最简单的模块源码说起字符设备驱动工作原理字符设备驱动代码实践--给空模块添加驱动壳子应用程序如何调用驱动 字符设备基础2添加读写接口&#xff08;应用和驱动之间的数据交换&#xff09;驱动中如何操控硬件…

Redis持久化RDB,AOF

目 录 CONFIG动态修改配置 慢查询 持久化 在上一篇主要对redis的了解入门&#xff0c;安装&#xff0c;以及基础配置&#xff0c;多实例的实现&#xff1a;redis的安装看我上一篇&#xff1a; Redis安装部署与使用,多实例 redis是挡在MySQL前面的&#xff0c;运行在内存…

《Linux系统编程篇》vim的使用 ——基础篇

引言 上节课我们讲了&#xff0c;如何将虚拟机的用户目录映射到自己windows的z盘&#xff0c;虽然这样之后我们可以用自己的编译器比如说Visual Studio Code&#xff0c;或者其他方式去操作里面的文件&#xff0c;但是这是可搭建的情况下&#xff0c;在一些特殊情况下&#xf…

Web学习day04

mybatis 目录 mybatis 文章目录 一、查询 1.1结果映射 1.2多条件查询 1.3模糊查询 二、XML 书写规范 三、动态SQL 四、配置文件 4.1settings标签 4.2mappers标签 4.3environments标签 五、案例 5.1数据表 5.2实现类 5.3mapper实现 5.4工具类实现 5.5XML动态…

Ubuntu 安装搜狗输入法

搜狗输入法已支持Ubuntu1604、1804、1910、2004、2010 各系统安装步骤可能略有不同 1、添加中文语言支持 打开 系统设置——区域和语言——管理已安装的语言——在“语言”tab下——点击“添加或删除语言” 弹出“已安装语言”窗口&#xff0c;勾选中文&#xff08;简体&…

【 香橙派 AIpro评测】烧系统到运行并使用Jupyter Lab 界面体验 AI 应用样例(新手福音)

文章目录 ⭐前言⭐初始化开发板⭐下载镜像烧系统⭐开发板初始化系统&#x1f496; 远程ssh&#x1f496;查看ubuntu桌面&#x1f496; 远程向日葵 ⭐体验 AI 应用样例&#x1f496; 运行 jupyterLab&#x1f496; 打开Jupyter Lab页面&#x1f496; 释放内存&#x1f496; 运行…