当前位置: 首页 > news >正文

【基于SprintBoot+Mybatis+Mysql】电脑商城项目之上传头像和新增收货地址

      🧸安清h:个人主页 

   🎥个人专栏:【Spring篇】【计算机网络】【Mybatis篇】

🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。


目录

🚀1.上传头像 -持久层

✨1.1规划SQL语句

✨1.2设计接口和抽象方法

✨1.3 接口的映射

✨1.4单元测试

🚀2.上传头像 -业务层

✨2.1规划异常

✨2.2设计接口和抽象方法

✨2.3抽象方法实现

🚀3.上传头像 -控制层

✨3.1规划异常

✨3.2处理异常

✨3.3设计请求

✨3.4实现请求

🚀4.上传头像 -前端页面

🚀5.解决BUG

✨5.1更改默认的大小限制

✨5.2显示头像

✨5.3登录后显示头像

🎃1.新增收货地址-数据表创建

 🎃2.新增收货地址-创建实体类

🎃3.新增收货地址-持久层

✨1.1各功能的开发顺序

✨1.2规划需要执行的SQL语句

✨1.3接口与抽象方法

✨1.4配置SQL映射

🎃4.新增收货地址-业务层

✨4.1规划异常

✨4.2接口与抽象方法

✨4.3实现抽象方法 

🎃5.新增收货地址-控制层

✨5.1处理异常

✨5.2设计请求

✨5.3处理请求

🎃6.新增收货地址-前端页面


🚀1.上传头像 -持久层

✨1.1规划SQL语句

将对应的文件保存在操作系统上,然后再把这个文件路径给记录下来,因为记录路径是非常方便和便捷的,将来如果要打开这个文件,可以依据这个路径去找到这个文件。在数据库中需要保存这个文件的路径即可。将所有的静态资源(图片,文件,其他)放到某台电脑上,再把这台电脑作为一台单独的服务器使用。

对应的是一个更新用户avatar字段的sql语句。

update t_user set avatar=?,modified_user=?,modified_time=? 
where uid=?

✨1.2设计接口和抽象方法

 UserMapper接口中来定义个抽象方法用于修改用户的头像。

     /*** @Param("SQL映射文件中#{}占位符的变量名"):解决的问题,* 当SQL语句的占位符和映射接口方法参数名不一致时,需要将某个参数强行注入到某个占位符变量上时,* 可以使用@Param这个注解来标注映射关系*也就是说@Param("avatar")就相当于mapper.xml中的#{avatar}** 根据用户的uid修改用户的头像* @param uid* @param avatar* @param modifiedUser* @param modifiedTime* @return 返回值为收影响的行数* */Integer updateAvatarByUid(@Param("uid") Integer uid,@Param("avatar") String avatar,@Param("modifiedUser") String modifiedUser,@Param("modifiedTime") Date modifiedTime);

✨1.3 接口的映射

UserMapper.xml文件中编写映射的SQL语句。

    <update id="updateAvatarByUid">update t_user set avatar=#{avatar},modified_user=#{modifiedUser},modified_time=#{modifiedTime}where uid=#{uid}</update>

✨1.4单元测试

在test->mapper包下的UserMapperTests类中编写测试方法updateAvatarByUid,代码如下:

    @Testpublic void updateAvatarByUid(){userMapper.updateAvatarByUid(7,"/upload/avatar.png","管理员",new Date());}

🚀2.上传头像 -业务层

✨2.1规划异常

1.用户数据不存在,找不到对应的用户数据。

2.更新的时候,有未知异常的产生。

前面已开发完成,无需重新开发。 

✨2.2设计接口和抽象方法

注释的快捷方法:/**+enter

    /*** 修改用户的头像* @param uid 用户id* @param avatar 用户的头像* @param username 用户的名称*/void changeAvatar(Integer uid,String avatar,String username);

✨2.3抽象方法实现

编写业务层的更新头像的方法。

    @Overridepublic void changeAvatar(Integer uid, String avatar, String username) {User result = userMapper.findByUid(uid);if(result == null || result.getIsDelete() == 1){throw new UserNotFoundException("用户数据不存在");}Integer rows = userMapper.updateAvatarByUid(uid,avatar, username, new Date());if(rows != 1){throw new UpdateException("更新时数据产生未知的异常");}}

测试业务层方法的执行。

    @Testpublic void changeAvatar(){userService.changeAvatar(7,"/upload/test.png","haha");}

🚀3.上传头像 -控制层

✨3.1规划异常

文件异常的父类:

        FileUploadException 泛指文件上传的异常。(父类)继承RuntimeException

父类是:FileUploadException

        FileEmptyException 文件为空的异常。

        FileSizeException 文件大小超出限制的异常。

        FileStateException 文件状态产生异常,即文件在打开状态时无法上传。

        FileTypeException 文件类型异常。

        FileUploadIOException 文件读写的异常。

 五个构造方法显式声明出来,再去继承相关的父类。

在controller包下新建包ex,在ex包里新建以上六个类。其中父类FileUploadException继承RuntimeException,其余五个类继承父类FileUploadException,在此不再做过多代码描述。

✨3.2处理异常

在基类BaseController类中进行编写和统一处理。

else if (e instanceof FileEmptyException) {result.setState(6000);} else if (e instanceof FileSizeException) {result.setState(6001);} else if (e instanceof FileTypeException) {result.setState(6002);} else if (e instanceof FileStateException) {result.setState(6003);} else if (e instanceof FileUploadIOException) {result.setState(6004);}

 在异常统一处理方法的参数列表上增加新的异常处理作为它的参数。

✨3.3设计请求

请求路径:/users/change_avatar

请求方式:POST(get请求提交数据2KB,不够清晰)

请求数据:HttpSession session,MutipartFile file

响应结果:JsonResult<String>(记录图片的路径,图片路径是一个串,即用String,如果不记录下来,再切换到其他页面就展示不出来了)

✨3.4实现请求

MultipartFile接口是SpringMVC提供一个接口,这个接口为我们包装了获取文件类型的数据(任何类型的file都可以接受),SpringBoot它又整合了SpringMVC,只需要在处理请求的方法参数列表上声明一个参数类型为MultipartFile,然后SpringBoot会自动将传递给服务的文件数据赋值给这个参数。

@RequestParam:表示请求中的参数,将请求中的参数注入请求处理方法的某个参数上,如果名称不一致则可以使用@RequestParam注解进行标记和映射。

/**** @param session* @param file* @return*/@RequestMapping("change_avatar")public JsonResult<String> changeAvatar(HttpSession session,@RequestParam("file") MultipartFile file) {
//        判断文件是否为空if(file.isEmpty()){throw new FileEmptyException("文件为空");}
//        判断文件大小是否超出限制if(file.getSize() > AVATAR_MAX_SIZE){throw new FileSizeException("文件超出限制");}
//        判断文件的类型是否为我们规定的和后缀类型String contentType = file.getContentType();if(!AVATAR_TYPE.contains(contentType)){throw new FileTypeException("文件类型不支持");}
//       上传的文件.../upload/文件.pngString parent = session.getServletContext().getRealPath("upload");
//      File对象指向这个路径,File是否存在File dir = new File(parent);if(!dir.exists()){dir.mkdir();  //创建当前的目录}
//      获取到这个文件名称,UUID工具来将生成一个新的字符串作为文件名
//        返回的只是文件名,不包含目录结构.例如:avatar01.png。
//        在后续中,前面的avatar01即名称部分可以根据uid来生成一个随机的大小写字符串保存下来,
//        后缀需要保存下来String originalFilename =file.getOriginalFilename();System.out.println("OriginalFilename"+originalFilename);int index = originalFilename.lastIndexOf(".");  //查找字符串中最后一次出现的点号(.)的位置。String suffix = originalFilename.substring(index);  //从字符串的指定索引位置开始截取字符串,直到字符串的末尾。String filename = UUID.randomUUID().toString().toUpperCase() + suffix;File dest = new File(dir,filename);  //在dir下创建一个叫filename的文件,此时它是一个空文件
//        将参数file中的数据写入到空文件当中try{file.transferTo(dest);  //将file中的数据写入到dest文件中}catch (FileStateException e){throw new FileStateException("文件状态异常");}catch (IOException e){throw new FileUploadIOException("文件读写异常");}Integer uid = getuidFromSession(session);String username = getUsernameFromSession(session);
//        返回头像路径/upload/test.png,相对路径String avatar = "/upload"+filename;userService.changeAvatar(uid,avatar,username);
//        返回用户头像的路径给前端页面,将来用于头像的展示使用return new JsonResult<>(OK,avatar);}

这里没有办法测试,数据类型模拟不出来,file每一种类型的文件编码都不一样。 

🚀4.上传头像 -前端页面

在upload页面中编写上传头像的代码。.ajax()请求它可以把一个数据解析成一个大串,来拼接在参数名的后边,但file可以直接把一个文件作为一个整体提交。表单中action可以整体提交。

说明:如果直接使用表单进行文件的上传,需要给表单显示的添加一个属性:

enctype="multipart/form-data";声明出来,不会将目标文件的数据结构做修改再上传,不同字符串。

🚀5.解决BUG

✨5.1更改默认的大小限制

SpringMVC默认为1MB文件可以进行上传,手动的去修改SpringMVC默认上传文件爱的大小。

方式一:直接可以在配置文件中进行配置:

spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=15MB

✨5.2显示头像

页面中通过ajax的请求来提交文件,提交完成后返回了json串,解析出data中的数据,设置到img头像标签的src属性上就可以了。

1.在这里把submit改成button,因为submit不能够添加点击事件。

<input id="btn-change-avatar" type="button" class="btn btn-primary" value="上传" />

    2.这里原来的serialize提交的是一个串的类型,不能够解析文件,所以要换成类似一下方式:

    • serialize():可以将表单数据自动拼接成key=value的结构进行提交给服务器,一般提交是普通控件类型中的数据(text/password/radio/checkbox)。
    • FromData类:将表单中的数据保持原有的结构进行提交。new FromData($("#form")[0]);将form表单中某一个元素的整体值作为FromData()创建对象的数据,所以这个对象的格式就放在了这个对象当中,这样格式就不会被看做其他的对象被更改或调整。
    •  ajax默认处理数据时按照字符串的形式进行处理,以及默认会采用字符串的形式进行提交数据。关闭这两个默认的功能。
    new FromData($("#form")[0])

    ✨5.3登录后显示头像

    可以更新头像成功后,将服务器返回的头像路径保存在客户端的cookie对象中,然后每次检测到用户打开上传头像页面,在这个页面中通过ready()方法来自动监测去读取cookie中的头像并设到src上。

    1.设置cookie中的值:

    导入cookie.js的文件:

    <script src="../bootstrap3/js/jquery.cookie.js" type="text/javascript" charset="utf-8"></script><script src="../js/autoLogin.js" type="text/javascript"></script>

    调用cookie的方法:

    $.cookie(key,value,time);  //单位:天(存活时间)

    2.在upload.html页面先引入cookie.js文件

    <script src="../bootstrap3/js/jquery.cookie.js" type="text/javascript" charset="utf-8"></script><script src="../js/autoLogin.js" type="text/javascript"></script>

    3.在upload.html页面通过ready()自动读取cookie中的数据。

    $(document).ready(function (){let avatar = $.cookie("avatar");// 将cookie中的值获取出来设置到头像src属性上$("#img-avatar").attr("src",avatar);});

    5.4显示最新头像

    在更改完头像后,将最新的头像地址,再次保存到cookie,同名保存会覆盖原有cookie中的值。

    $.cookie("avatar",json.data,{expires: 7});

    🎃1.新增收货地址-数据表创建

    CREATE TABLE t_address (aid INT AUTO_INCREMENT COMMENT '收货地址id',uid INT COMMENT '归属的用户id',`name` VARCHAR(20) COMMENT '收货人姓名',province_name VARCHAR(15) COMMENT '省-名称',province_code CHAR(6) COMMENT '省-行政代号',city_name VARCHAR(15) COMMENT '市-名称',city_code CHAR(6) COMMENT '市-行政代号',area_name VARCHAR(15) COMMENT '区-名称',area_code CHAR(6) COMMENT '区-行政代号',zip CHAR(6) COMMENT '邮政编码',address VARCHAR(50) COMMENT '详细地址',phone VARCHAR(20) COMMENT '手机',tel VARCHAR(20) COMMENT '固话',tag VARCHAR(6) COMMENT '标签',is_default INT COMMENT '是否默认:0-不默认,1-默认',created_user VARCHAR(20) COMMENT '创建人',created_time DATETIME COMMENT '创建时间',modified_user VARCHAR(20) COMMENT '修改人',modified_time DATETIME COMMENT '修改时间',PRIMARY KEY (aid)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;
    

     🎃2.新增收货地址-创建实体类

    创建一个类Address类,在类中定义表的相关字段,采用驼峰命名方式,最后再去继承BaseEntity类。

    //收货地址数据的实体类
    public class Address extends BaseEntity {private Integer aid;private Integer uid;private String name;private String provinceName;private String provinceCode;private String cityName;private String cityCode;private String areaName;private String areaCode;private String zip;private String address;private String phone;private String tel;private String tag;private Integer isDefault;
    }

    🎃3.新增收货地址-持久层

    ✨1.1各功能的开发顺序

    当前收货地址功能模块:列表的展示、修改、删除、设置默认、新增收货地址。开发顺序:新增收货地址->列表展示->设置默认收货地址->删除收货地址->修改收货地址。

    ✨1.2规划需要执行的SQL语句

    1.对应的插入语句:

    insert into t_address(除aid外的字段列表) values(字段值列表)

    2. 一个用户的收货地址最多只能有20条数据对应。在插入用户数据之前先做查询操作。收货地址逻辑控制方面的一个异常。

    select count(*) from t_address where uid=?

    ✨1.3接口与抽象方法

    1.创建一个新的接口Address,在这个接口中来定义上面两个SQL语句抽象方法定义。

    /*** 插入用户的收货地址* @param address 收货地址数据* @return 受影响的行数*/Integer insert(Address address);/*** 根据用户的id统计收货地址的数量* @param uid 用户的id* @return 当前用户的收货地址总数*/Integer count(Integer uid);

    ✨1.4配置SQL映射

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.cy.store.mapper.AddressMapper"><resultMap id="AddressEntityMap" type="com.cy.store.entity.Address"><id column="aid" property="aid"/><result column="province_code" property="provinceCode"/><result column="province_name" property="provinceName"/><result column="city_code" property="cityCode"/><result column="city_name" property="cityName"/><result column="area_code" property="areaCode"/><result column="area_name" property="areaName"/><result column="is_delete" property="isDelete"></result><result column="created_user" property="createdUser"></result><result column="created_time" property="createdTime"></result><result column="modified_user" property="modifiedUser"></result><result column="modified_time" property="modifiedTime"></result></resultMap><insert id="insert" useGeneratedKeys="true" keyProperty="aid">insert into t_address (uid, name, province_name, province_code, city_name, city_code, area_name, area_code, zip,address, phone, tel,tag, is_default, created_user, created_time, modified_user, modified_time) values (#{uid}, #{name}, #{provinceName}, #{provinceCode}, #{cityName}, #{cityCode}, #{areaName},#{areaCode}, #{zip}, #{address}, #{phone}, #{tel}, #{tag}, #{isDefault}, #{createdUser},#{createdTime}, #{modifiedUser}, #{modifiedTime})</insert><select id="countByUid" resultType="java.lang.Integer">select count(*) from t_address where uid=#{uid}</select>
    </mapper>

    2.在test下的mapper文件夹下创建一个AddressMapperTests的测试类。

    @Testpublic void insert(){Address address = new Address();address.setUid(6);address.setPhone("15374583927");address.setName("备备");addressMapper.insert(address);}@Testpublic void countByUid(){Integer count = addressMapper.countByUid(6);System.out.println(count);}

    🎃4.新增收货地址-业务层

    ✨4.1规划异常

    1.如果用户是第一次插入收货地址,规则:当用户插入的地址是第一条时,需要将当前地址作为默认收货地址,如果查询到统计总数为0,则将当前地址的is_default设置为1。查询统计的结果为0不代表异常。

    查询到的结果大于20,这时候需要抛出业务控制的异常AddressCountLimitException异常。自行创建这个异常。

    public class AddressCountLimitException extends ServiceException{public AddressCountLimitException() {super();}public AddressCountLimitException(String message) {super(message);}public AddressCountLimitException(String message, Throwable cause) {super(message, cause);}public AddressCountLimitException(Throwable cause) {super(cause);}protected AddressCountLimitException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
    }
    

    2.插入数据时产生异常。 

    ✨4.2接口与抽象方法

    1.创建一个IAddressService接口,在里面定义业务的抽象方法。

        void addNewAddress(Integer uid,String username,Address address);

    2.创建一个AddressServiceImpl实现类,去实现接口中的抽象方法。

    在配置文件中定义数据

    #Spring读取配置文件中数据:@Value(${user.address.max-count})
    user.address.max-count=20

    ✨4.3实现抽象方法 

    在实现类中实现业务控制 。

    //新增收货地址的实现类
    @Service
    public class AddressServiceImpl implements IAddressService {@Autowiredprivate AddressMapper addressMapper;@Value("${user.address.max-count}")private Integer count;@Overridepublic void addNewAddress(Integer uid, String username, Address address) {
    //        调用收货地址统计的方法Integer count = addressMapper.countByUid(uid);if(count >= 20){throw new AddressCountLimitException("用户收货地址超出上限");}//    uid、isDeleteaddress.setUid(uid);Integer isDelete = count == 0?1:0;  //1表示默认,0表示不默认address.setIsDefault(isDelete);
    //    补全4项日志address.setCreatedUser(username);address.setCreatedTime(new Date());address.setModifiedUser(username);address.setModifiedTime(new Date());//        插入收货地址的方法Integer rows = addressMapper.insert(address);if(rows != 1){throw new InsertException("插入用户地址时产生未知异常");}}}
    

    3.测试业务层功能是否正常。AddressServiceTests测试来测试业务功能。

        @Testpublic void addNewAddress(){Address address = new Address();address.setPhone("11874583927");address.setName("备备");addressService.addNewAddress(6,"小明",address);}

    🎃5.新增收货地址-控制层

    ✨5.1处理异常

    业务层抛出了收货地址总数超标的异常,在BaseController中进行处理。

    else if(e instanceof AddressCountLimitException) {result.setState(4003);result.setMessage("用户收货地址超出上限的异常");}

    ✨5.2设计请求

    请求路径:/addresses/add_new_address

    请求方式:POST

    请求数据:Address address,HttpSession session

    响应结果:JsonResult<Void>

    ✨5.3处理请求

    在控制层创建AddressController来处理用户收货地址的请求和响应。

     @RequestMapping("add_new_address")public JsonResult<Void> addNewAddress(Address address, HttpSession session){Integer uid = getuidFromSession(session);String username = getUsernameFromSession(session);addressService.addNewAddress(uid,username,address);return new JsonResult<>(OK);}

    先登录用户,然后再访问http://localhost:8080/address/add_new_address?name=tom&phone=1826478328 进行测试。

    🎃6.新增收货地址-前端页面

    <script>$("#btn-add-new-address").click(function (){$.ajax({url:"/addresses/add_new_address",type:"POST",data:$("#form-add-new-address").serialize(),dataType:"JSON",success:function (json){if(json.state==200){alert("新增收货地址成功");}else{alert("新增收货地址失败");}},error:function (xhr){alert("新增收货地址时产生未知的异常"+xhr.message);}});});</script>

    相关文章:

    【基于SprintBoot+Mybatis+Mysql】电脑商城项目之上传头像和新增收货地址

    &#x1f9f8;安清h&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;【Spring篇】【计算机网络】【Mybatis篇】 &#x1f6a6;作者简介&#xff1a;一个有趣爱睡觉的intp&#xff0c;期待和更多人分享自己所学知识的真诚大学生。 目录 &#x1f680;1.上传头像 -持久…...

    AI知识库和全文检索的区别

    1、AI知识库的作用 AI知识库是基于人工智能技术构建的智能系统&#xff0c;能够理解、推理和生成信息。它的核心作用包括&#xff1a; 1.1 语义理解 自然语言处理&#xff08;NLP&#xff09;&#xff1a;AI知识库能够理解用户查询的语义&#xff0c;而不仅仅是关键词匹配。 …...

    20240817 联想 笔试

    文章目录 1、选择题1.11.21.31.41.51.61.71.81.91.101.111.121.131.141.151.161.171.181.191.202、编程题2.12.2岗位:Linux开发工程师 题型:20 道选择题,2 道编程题 1、选择题 1.1 有如下程序,程序运行的结果为 (D) #include <stdio.h>int main() {int k = 3...

    IntelliJ IDEA 安装与使用完全教程:从入门到精通

    一、引言 在当今竞争激烈的软件开发领域&#xff0c;拥有一款强大且高效的集成开发环境&#xff08;IDE&#xff09;是开发者的致胜法宝。IntelliJ IDEA 作为 JetBrains 公司精心打造的一款明星 IDE&#xff0c;凭借其丰富多样的功能、智能精准的代码提示以及高效便捷的开发工…...

    【JVM详解一】类加载过程与内存区域划分

    一、简介 1.1 概述 JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;是通过在实际的计算机上仿真模拟各种计算机功能来实现的。由一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域等组成。JVM屏蔽了与操作系统平台相关…...

    250207-MacOS修改Ollama模型下载及运行的路径

    在 macOS 上&#xff0c;Ollama 默认将模型存储在 ~/.ollama/models 目录。如果您希望更改模型的存储路径&#xff0c;可以通过设置环境变量 OLLAMA_MODELS 来实现。具体步骤如下&#xff1a; 选择新的模型存储目录&#xff1a;首先&#xff0c;确定您希望存储模型的目标目录路…...

    Win10 部署llama Factory 推荐教程和遇到的问题

    教程 【大模型微调】使用Llama Factory实现中文llama3微调_哔哩哔哩_bilibili 大模型微调&#xff01;手把手带你用LLaMA-Factory工具微调Qwen大模型&#xff01;有手就行&#xff0c;零代码微调任意大语言模型_哔哩哔哩_bilibili 遇到问题解决办法 pytorch gpu国内镜像下载…...

    如何在Android Studio中开发一个简单的Android应用?

    Android Studio是开发Android应用的官方集成开发环境&#xff08;IDE&#xff09;&#xff0c;它提供了许多强大的功能&#xff0c;使得开发者能够高效地创建Android应用。如果你是Android开发的初学者&#xff0c;本文将引导你如何在Android Studio中开发一个简单的Android应用…...

    ubuntu下迁移docker文件夹

    在 Ubuntu 系统中迁移 Docker 文件夹&#xff08;如 Docker 数据存储文件夹 /var/lib/docker&#xff09;到另一个磁盘或目录&#xff0c;通常是为了释放系统盘空间。以下是迁移过程的详细步骤&#xff1a; 1. 停止 Docker 服务 在进行迁移之前&#xff0c;必须停止 Docker 服…...

    嵌入式面试题 C/C++常见面试题整理_7

    一.什么函数不能声明为虚函数? 常见的不能声明为虚函数的有:普通函数(非成员函数):静态成员函数;内联成员函数;构造函数;友元函数。 1.为什么C不支持普通函数为虚函数?普通函数(非成员函数)只能被overload&#xff0c;不能被override&#xff0c;声明为虚函数也没有什么意思…...

    使用OBS推流,大华摄像头 srs服务器播放

    说明&#xff1a; ffmpeg可以推流&#xff0c;但是是命令行方式不太友好&#xff0c;还可以使用主流的OBS开源推流软件&#xff0c;可从官网Open Broadcaster Software | OBS 下载最新版本&#xff0c;目前很多网络主播都是用它做直播。该软件支持本地视频文件以及摄像头推流。…...

    CSS 组合选择符详解与实战示例

    在 Web 开发过程中&#xff0c;CSS 用于定义页面元素的样式&#xff0c;而选择器则帮助我们精确定位需要添加样式的元素。今天我们主要来讲解 CSS 中的组合选择符&#xff0c;它们能够根据 DOM 结构中元素之间的关系来选中目标元素&#xff0c;从而写出结构清晰、易于维护的 CS…...

    Window系统通过Docker本地安装ollama和deepseek

    在 Windows 系统上安装 Ollama 和 DeepSeek 的步骤如下&#xff1a; 安装 Ollama 安装 WSL&#xff08;Windows Subsystem for Linux&#xff09;&#xff1a; 如果还没有安装 过WSL的&#xff08;安装过的你直接跳过就行了&#xff09;&#xff0c;可以按照以下步骤进行安装&…...

    镜头放大倍率和像素之间的关系

    相互独立的特性 镜头放大倍率&#xff1a;主要取决于镜头的光学设计和结构&#xff0c;决定了镜头对物体成像时的缩放程度&#xff0c;与镜头的焦距等因素密切相关。比如&#xff0c;微距镜头具有较高的放大倍率&#xff0c;能将微小物体如昆虫、花朵细节等放大成像&#xff0…...

    P3413 SAC#1 - 萌数

    题目背景 本题由世界上最蒟蒻的 SOL 提供。 寂月城网站是完美信息教室的官网。地址:http://191.101.11.174/mgzd。 题目描述 蒟蒻 SOL 居然觉得数很萌! 好在在他眼里,并不是所有数都是萌的。只有满足“存在长度至少为 22 的回文子串”的数是萌的——也就是说,101 是萌…...

    [RabbitMQ] RabbitMQ常见面试题

    &#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…...

    Java运行时数据区

    JVM主要流程包括三部分&#xff1a; 首先是 ClassLoard 类加载器&#xff0c;加载数据源文件到jvm当中然后将加载好的数据存放在运行时数据区最后由引擎进行解释和编译的工作 1.Java 内存区域&#xff1a; 1.1 程序计数器 程序计数器&#xff08;Program Counter Register&a…...

    【03】 区块链分布式网络

    3-1 P2P网络 传统中心化网络由中央服务器保存全量数据。客户端之间无法直接连接&#xff0c;必须通过中央服务器作为桥梁。客户端必须和中央服务器建立连接后访问资源。客户端之间并无连通。 在P2P网络中通过将数据资源分散在网络各个节点中存储以及节点间交互连接&#xff0…...

    【SQL server】关于SQL server彻底的卸载删除。

    1.未彻底卸载删除SQL Server会出现的问题 如果没有彻底删除之前的SQL server&#xff0c;就可能会出现这个 当要安装新的实例的时候因为之前安装过sql server没有删除干净而导致下图问题&#xff0c;说实例名已经存在。 2.首先要先关闭服务 “开始R”可以快速进入运行&#…...

    【含文档+PPT+源码】基于微信小程序的校园志愿者管理系统的设计与实现

    项目介绍 本课程演示的是一款 基于微信小程序的校园志愿者管理系统的设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本…...

    conda相比python好处

    Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

    OpenLayers 可视化之热力图

    注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

    Ubuntu系统下交叉编译openssl

    一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

    CentOS下的分布式内存计算Spark环境部署

    一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

    3403. 从盒子中找出字典序最大的字符串 I

    3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

    pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

    目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

    HarmonyOS运动开发:如何用mpchart绘制运动配速图表

    ##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

    AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

    【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

    uniapp手机号一键登录保姆级教程(包含前端和后端)

    目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

    NPOI Excel用OLE对象的形式插入文件附件以及插入图片

    static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...