【SpringBoot项目】SpringBoot+MyBatis+MySQL电脑商城

在b站听了袁老师的开发课,做了一点笔记。

01-项目环境搭建_哔哩哔哩_bilibili

基于springboot框架的电脑商城项目(一)_springboot商城项目_失重外太空.的博客-CSDN博客

项目环境搭建

1.项目分析

1.项目功能:登录、注册、热销商品、用户管理(密码、个人信息、头像、收货地址)、购物车(展示、增加、删除) 、订单模块。
2.开发顺序:注册、登录、用户管理、购物车、商品、订单模块。
3.某一个模块的开发

  • 持久层开发:依据前端页面的设置规划相关的SQL语句,以及进行配置
  • 业务层开发:核心功能控制、业务操作以及异常的处理
  • 控制层开发: 接受请求、处理响应
  • 前端开发: JS、Query、AJAX这些技术来连接后台

2.开发环境

  • JDK: 1.8版本及以上的版本
  • maven:配置到idea,3.6.1版本
  • 数据库: MariaDB、MySQL,要求是5.1及以上的版本
  • 开发的平台: idea开发

3.搭建项目

1.项目名称:store

2.结构:com.cy.store

java web

mybatis

mysql driver

3.资源文件:resource文件夹下(static放静态资源、templates模板)

4.单元测试:test.com.cy.store

5.在properties文件中配置数据的连接源信息

spring.datasource.url=jdbc:mysql://localhost:3306/store?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root

6.创建一个store数据库

create database store character set utf8;

7.测试连接:

  • 启动SpringBoot主类,是否有对应的Spring图形输出
  • 在单元测试类中测试数据库的连接是否可以正常的加载

数据库连接池:
1.DBCP
2.C3P0
3.Hikari: 管理数据库的连接对象

8.访问项目的静态资源是否可以正常的加载。所有的静态资源复制static目录下。

注意:idea对于JS代码的兼容性较差,编写了js代码可能不能正常加载。五种解决:在项目的maven下clear清理项目、install重新部署;在项目的file选项下 cash清理缓存;重新构建项目:build选项下 rebuild选项;重启idea;重启电脑。

用户注册

1.创建数据表

CREATE TABLE t_user (uid INT AUTO_INCREMENT COMMENT '用户id',username VARCHAR(20) NOT NULL UNIQUE COMMENT '用户名',password CHAR(32) NOT NULL COMMENT '密码',salt CHAR(36) COMMENT '盐值',phone VARCHAR(20) COMMENT '电话号码',email VARCHAR(30) COMMENT '电子邮箱',gender INT COMMENT '性别:0-女,1-男',avatar VARCHAR(50) COMMENT '头像',is_delete INT COMMENT '是否删除:0-未删除,1-已删除',created_user VARCHAR(20) COMMENT '日志-创建人',created_time DATETIME COMMENT '日志-创建时间',modified_user VARCHAR(20) COMMENT '日志-最后修改执行人',modified_time DATETIME COMMENT '日志-最后修改时间',PRIMARY KEY (uid)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

2.创建用户的实体类

2.1通过表的结构提取表的公共字段,放在实体类的基类中

public class baseEntity implements Serializable {private String createdUser;private Date createdTime; //import java.util.Dataprivate String modifiedUser;private Date modifiedTime;//再手动声明get、set方法,equals() and hashCode();toString();}

为什么要用implements Serializable:实体类User因为要在网络中以流的形式传输,所以需要serialize序列化(为什么要用implements Serializable_IT_wjj的博客-CSDN博客)

2.2创建用户的实体类,需要继承baseEntity基类

public class User extends baseEntity implements Serializable {private Integer uid;private String username;private String password;private String salt;private String phone;private String email;private Integer gender;private String avatar;private Integer isDelete;//再手动声明get、set方法,equals() and hashCode();toString();
}

任何实体类都要:get和set方法、equals()和hashCode()、toString()

3.注册-持久层

通过MyBatis来操作数据库。在做mybatis开发的流程。

3.1规划需要执行的SQL语句

1.用户的注册功能,相当于在做数据的插入操作。

insert into t_user (username, password) values (值列表)

2.在用户注册时首先查询当前用户名是否存在,如果存在则不能注册,相当于一条查询语句。

select * from t_user where username=?

3.2设计接口和抽象方法

1.定义Mapper接口。在项目的目录结构下创建一个mapper包,在这个包下根据不同的功能模块创建mapper接口。创建UserMapper的接口(interface)。要在接口中定义这两个SQL语句的抽象方法。

package com.cy.store.mapper;
import com.cy.store.entity.User;/** 处理用户数据操作的持久层接口 */
public interface UserMapper {/*** 插入用户数据* @param user 用户数据* @return 受影响的行数(在增删改都有受影响的行数作为返回值,可以根据返回值来判断是否执行成功)*/Integer insert(User user);/*** 根据用户名查询用户数据* @param username 用户名* @return 找到对应的用户数据则返回用户的数据,如果没有找到的数据则返回null*/User findByUsername(String username);
}

2.在启动类配置mapper接口文件的位置

//MapperScan注解指定当前项目中的Mapper接口路径的位置,在项目启动的时候会自动加载所有的接口。

@MapperScan("com.cy.store.mapper")

package com.cy.store;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.unit.DataSize;
import org.springframework.util.unit.DataUnit;import javax.servlet.MultipartConfigElement;@Configuration
@SpringBootApplication
@MapperScan("com.cy.store.mapper")
public class StoreApplication {public static void main(String[] args) {SpringApplication.run(StoreApplication.class, args);}@Beanpublic MultipartConfigElement getMultipartConfigElement() {MultipartConfigFactory factory = new MultipartConfigFactory();// DataSize dataSize = DataSize.ofMegabytes(10);// 设置文件最大10M,DataUnit提供5中类型B,KB,MB,GB,TBfactory.setMaxFileSize(DataSize.of(10, DataUnit.MEGABYTES));factory.setMaxRequestSize(DataSize.of(10, DataUnit.MEGABYTES));// 设置总上传数据总大小10Mreturn factory.createMultipartConfig();}
}

3.3编写映射

1.定义xml映射文件,与对应的接口进行关联。所有映射文件属于资源文件,需要放在resource目录结构下,在这个目录下创建一个mapper文件夹(Directory),然后在这个文件夹下存放mapper的映射文件。

2.创建接口对应的映射文件,遵循和接口的名称保持一致即可。创建一个UserMapper.xml文件(file)

namespace的属性:用于指定当前的映射文件和那个接口进行映射,需要指定接口的文件路径,需要标注包的完整路径结构。

<?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.UserMapper"><resultMap id="UserEntityMap" type="com.cy.store.entity.User"><id column="uid" property="uid"/><result column="is_delete" property="isDelete"/><result column="created_user" property="createdUser"/><result column="created_time" property="createdTime"/><result column="modified_user" property="modifiedUser"/><result column="modified_time" property="modifiedTime"/></resultMap><!-- 插入用户数据:Integer insert(User user) --><insert id="insert" useGeneratedKeys="true" keyProperty="uid">INSERT INTOt_user (username, password, salt, phone, email, gender, avatar, is_delete, created_user, created_time, modified_user, modified_time)VALUES(#{username}, #{password}, #{salt}, #{phone}, #{email}, #{gender}, #{avatar}, #{isDelete}, #{createdUser}, #{createdTime}, #{modifiedUser}, #{modifiedTime})</insert><!-- 根据用户名查询用户数据:User findByUsername(String username) --><select id="findByUsername" resultMap="UserEntityMap">SELECT*FROMt_userWHEREusername = #{username}</select></mapper>

3.配置接口中的方法对应上SQL语句。需要借助标签完成,insert/update/delete/selete,对应SQL语句的增删改查操作。

insert

  • id属性:表示映射的接口中方法的名称,直接在标签的内容部来编写SQL语句。
  • useGeneratedKeys属性:表示开启某个字段的值递增(主键设置为递增)
  • keyProperty属性:表示将表中的哪个字段作为主键进行递增。

select在执行的时候,查询的结果是一个对象、多个对象。

  • resultType表示查询的结果集类型,只需要指定对应映射的类的类型,并且包含完整的包接口。resultType="com.cy.store.entity.User"。这种要求表的字段名字和类属性的名字一模一样。
  • resultMap表示当表的字段和类的对象属性的字段名称不一致时,来自定义查询结果集的映射规则。resultMap id属性表示给映射规则分配唯一的id值,对应resultMap="id属性的值"属性的取值。type属性取值是一个类,表示的是数据库中的查询结果与java中的哪个实体类进行结果集的映射,将表的字段和类的属性不一致的字段进行匹配指定,名称一致的字段可以省略不写。column属性:表示表中的字段名称;proprerty属性:表示类中的属性名称。column属性、proprerty属性配合完成名称不一致的映射。在定义映射规则时,主键是不可以省略的

4.将mapper文件的位置注册到properties对应的配置文件中。(固定写法)

mybatis.mapper-locations=classpath:mapper/*.xml

5.单元测试:每个独立的层编写完毕后需要编写单元测试方法,来测试当前的功能。在test包结构下创建一个mapper包,在这个包下在创建持久层的功能测试。

@SpringBootTest:表示标注当前的类是一个测试类,不会随同项目一块打包发送。

@RunWith(SpringRunner.class):表示启动这个单元测试类(如果不写-单元测试类是不能运行的),需要传递一个固定的参数,必须是SpringRunner的实例类型。

单元测试方法(可以单独的独立运行,不用启动整个项目,可以做单元测试,提升了代码的测试效率必须被@Test注解所修饰,返回值类型必须是void,方法的参数列表不能指定任何类型,方法的访问修饰符必须是public。

package com.cy.store.mapper;import com.cy.store.entity.User;
import com.cy.store.mapper.UserMapper;
import org.junit.Test;//记住
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.text.SimpleDateFormat;
import java.util.Date;// @RunWith(SpringRunner.class)注解是一个测试启动器,可以加载Springboot测试注解
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTests {//idea有检测的功能,接口是不能直接创建Bean的(动态代理技术来解决)@Autowiredprivate UserMapper userMapper;@Testpublic void insert() {User user = new User();user.setUsername("user05");user.setPhone("12345678910");Integer rows = userMapper.insert(user);System.out.println("rows=" + rows);}@Testpublic void findByUsername() {String username = "user02";User result = userMapper.findByUsername(username);System.out.println(result);}
}

4.注册-业务层

4.1规划异常

1.RuntimeException异常,作为这个异常的子类,再去定义具体的异常类型来继承这个异常。业务层异常的基类ServiceException,这个异常继承RuntimeException异常。异常机制就建立起来了。

Alt+insert --override methods 

package com.cy.store.service.ex;/** 业务异常的基类 */
public class ServiceException extends RuntimeException {public ServiceException() {super();}public ServiceException(String message) {super(message);}public ServiceException(String message, Throwable cause) {super(message, cause);}public ServiceException(Throwable cause) {super(cause);}protected ServiceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}

根据业务层不同的业务功能来详细定义具体异常类型,统一去继承ServiceException。

2.用户在进行注册的时候可能会产生用户名被占用的错误,抛出一个异常:UsernameDuplicatedException

3.正在执行数据插入操作的时候,服务器宕机、数据库宕机。处于正在执行插入的过程中所产生的异常:InsertException异常。

4.2设计接口和抽象方法

1.在service包下创建一个IUserService接口(interface)。

package com.cy.store.service;
import com.cy.store.entity.User;/** 处理用户数据的业务层接口 */
public interface IUserService {/*** 用户注册* @param user 用户数据的对象*/void reg(User user);
}

@Service注解:将当前类的对象交给Spring来管理,自动创建对象以及对象的维护。

2.创建一个实现类UserServiceImpl类,需要实现这个接口,并且实现抽象的方法。

package com.cy.store.service.impl;import java.util.UUID;
import com.cy.store.entity.User;
import com.cy.store.mapper.UserMapper;
import com.cy.store.service.IUserService;
import com.cy.store.service.ex.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;import java.util.Date;/** 处理用户数据的业务层实现类 */
@Service
public class UserServiceImpl implements IUserService {@Autowiredprivate UserMapper userMapper;@Overridepublic void reg(User user) {// 根据参数user对象获取注册的用户名String username = user.getUsername();// 调用持久层的User findByUsername(String username)方法,根据用户名查询用户数据User result = userMapper.findByUsername(username);// 判断查询结果是否不为nullif (result != null) {// 是:表示用户名已被占用,则抛出UsernameDuplicateException异常throw new UsernameDuplicateException("尝试注册的用户名[" + username + "]已经被占用");}// 创建当前时间对象Date now = new Date();// 补全数据:加密后的密码。盐值是一个随机的字符串。String salt = UUID.randomUUID().toString().toUpperCase();String md5Password = getMd5Password(user.getPassword(), salt);user.setPassword(md5Password);// 补全数据:盐值user.setSalt(salt);// 补全数据:isDelete(0)user.setIsDelete(0);// 补全数据:4项日志属性user.setCreatedUser(username);user.setCreatedTime(now);user.setModifiedUser(username);user.setModifiedTime(now);// 表示用户名没有被占用,则允许注册// 调用持久层Integer insert(User user)方法,执行注册并获取返回值(受影响的行数)Integer rows = userMapper.insert(user);// 判断受影响的行数是否不为1if (rows != 1) {// 是:插入数据时出现某种错误,则抛出InsertException异常throw new InsertException("添加用户数据出现未知错误,请联系系统管理员");}}/*** 执行密码加密* @param password 原始密码* @param salt 盐值* @return 加密后的密文*/private String getMd5Password(String password, String salt) {/** 加密规则:* 1、无视原始密码的强度* 2、使用UUID作为盐值,在原始密码的左右两侧拼接* 3、循环加密3次*/for (int i = 0; i < 3; i++) {password = DigestUtils.md5DigestAsHex((salt + password + salt).getBytes()).toUpperCase();}return password;}}

3.在单元测试包下创建一个UserServiceTests类,在这个类中添加单元测试功能。

package com.cy.store.service;import com.cy.store.entity.User;
import com.cy.store.service.ex.ServiceException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTests {@Autowiredprivate IUserService iUserService;@Testpublic void reg() {try {User user = new User();user.setUsername("lower");user.setPassword("123456");iUserService.reg(user);System.out.println("注册成功!");} catch (ServiceException e) {//获取类的对象,再获取类的名称System.out.println("注册失败!" + e.getClass().getSimpleName());//获取异常的具体描述信息System.out.println(e.getMessage());}}
}

5.注册-控制层

5.1创建响应

状态码、状态描述信息、数据。这部分功能封装在一个类中,将这个类作为方法的返回值,返回给前端浏览器。

package com.cy.store.util;
import java.io.Serializable;/*** 响应结果类* Json格式的数据进行相应* @param <E> 响应数据的类型*/
public class JsonResult<E> implements Serializable {/** 状态码 */private Integer state;/** 状态描述信息 */private String message;/** 数据 */private E data;public JsonResult() {super();}public JsonResult(Integer state) {super();this.state = state;}/** 出现异常时调用 */public JsonResult(Throwable e) {super();// 获取异常对象中的异常信息this.message = e.getMessage();}public JsonResult(Integer state, E data) {super();this.state = state;this.data = data;}public Integer getState() {return state;}public void setState(Integer state) {this.state = state;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public E getData() {return data;}public void setData(E data) {this.data = data;}
}

5.2设计请求

依据当前的业务功能模块进行请求的设计。

  • 请求路径:/users/reg
  • 请求参数:User user
  • 请求类型:POST(有敏感数据)、GET
  • 请求结果:JsonResult<void>

5.3处理请求

创建一个控制层对应的UserController类,依赖于业务层的接口。

/** 处理用户相关请求的控制器类 */
@RestController
@RequestMapping("users")
public class UserController extends BaseController {@Autowiredprivate IUserService userService;/*@RequestMapping("reg")public JsonResult<Void> reg(User user) {// 调用业务对象执行注册userService.reg(user);// 返回return new JsonResult<Void>(OK);}*/@RequestMapping("reg")public JsonResult<Void> reg(User user) {// 创建返回值(创建响应结果对象)JsonResult<Void> result = new JsonResult<Void>();try {// 调用业务对象执行注册userService.reg(user);// 响应成功result.setState(200);} catch (UsernameDuplicateException e) {// 用户名被占用result.setState(4000);result.setMessage("用户名已经被占用");} catch (InsertException e) {// 插入数据异常result.setState(5000);result.setMessage("注册失败,请联系系统管理员");}return result;}
}

 @RestController

@RestController 详解_换个角度看代码的博客-CSDN博客

@RestController是@controller和@ResponseBody 的结合

@Controller 将当前修饰的类注入SpringBoot IOC容器,使得从该类所在的项目跑起来的过程中,这个类就被实例化。
@ResponseBody 它的作用简短截说就是指该类中所有的API接口返回的数据,甭管你对应的方法返回Map或是其他Object,它会以Json字符串的形式进行数据的响应给到前端。

@RequestMapping注解能将请求和处理请求的控制器方法关联起来,建立映射关系。

SpringMvc---@RequestMapping注解和它的属性_@requestmapping 定义数组_妙Lin的博客-CSDN博客

5.4控制层优化设计

在控制层抽离一个父类,在这个父类中统一的处理关于异常的操作。编写BaseController类统一处理异常。

@ExceptionHandler 用于统一处理抛出的异常

/** 控制器类的基类 */
public class BaseController {/** 操作成功的状态码 */public static final int OK = 200;/** @ExceptionHandler用于统一处理方法抛出的异常 *///请求处理方法,这个方法的返回值就是需要传递给前端的数据//自动将异常对象传递给此方法的参数列表上//当项目中产生了异常,会被统一拦截到此方法中,这个方法此时充当请求处理方法,方法的返回值直接给到前端@ExceptionHandler({ServiceException.class, FileUploadException.class})public JsonResult<Void> handleException(Throwable e) {JsonResult<Void> result = new JsonResult<Void>(e);if (e instanceof UsernameDuplicateException) {result.setState(4000);} } else if (e instanceof InsertException) {result.setState(5000);}return result;}
}

重新构建了reg()方法。

@RequestMapping("reg")public JsonResult<Void> reg(User user) {// 调用业务对象执行注册userService.reg(user);// 返回return new JsonResult<Void>(OK);}

6.注册-前端页面

1.在\store\src\main\resources\static\web\register.html页面编写发送请求的方法,点击事件来完成,先选中对应的按钮($(“选择器”)),再去添加点击事件,$.ajax()函数发送异步请求。

2.JQuery封装了一个函数,称之为$.ajax()函数,通过对象调用ajax()函数,可以异步加载相关的请求。依靠的是JavaScript提供的一个对象XHR(XmlHttpResponse),封装了这个对象。

3.ajax()使用方式。需要传递一个方法体作为方法的参数来使用,一对大括号称之为方法体,ajax接收多个参数,参数与参数之间要求使用英文逗号分割,每一组参数之间使用英文冒号分割,参数的组成部分是参数名称(不能随意定义)和参数的值(要求使用字符串来表示"双引号引起来"),参数的声明顺序没有要求。语法结构:

$.ajax(fun());

function fun(){

        //TODO

}

$.ajax({url:"",type:"",data:"",   dataType:"",success:function(){},error:function(){},
});

4. ajax()函数参数的含义: 

参数功能描述
url标识请求的地址(url地址),不能包含参数列表部分的内容。例如:url:"localhost:8080/users/reg"
type请求的类型(GET、POST)。例如:type:"POST"
data向指定请求url地址提交的数据。例如:data:"username=tom&pwd=123"
dataType提交数据的类型。数据类型一般指定为json类型。dataType:"json"

success

当服务器正常响应客户端是,会自动调用success参数的方法,并将服务器返回的数据以参数的形式传递给这个方法的参数上

error

当服务器未正常响应客户端是,会自动调用error参数的方法,并将服务器返回的数据以参数的形式传递给这个方法的参数上

5.js代码可以独立存放在一个后缀为js的文件里,或者声明在一个script标签中。

<script type="text/javascript">//1.监听注册按钮是否被点击,如果被点击可以执行一个方法$("#btn-reg").click(function() {//麻烦 动态获取表单中控件的数据//麻烦 let username = $("#username").val();//麻烦 let pwd = $("#password").val(); //console.log($("#from-reg").serialize());//输出表单看看       //2.发送ajax()的异步请求来完成用户的注册功能$.ajax({url: "/users/reg",type: "POST",data: $("#form-reg").serialize(),//麻烦 data: "username="+username+"&password="+pwd,dataType: "json",success: function(json) {if (json.state == 200) {alert("注册成功!");// location.href = "login.html";} else {alert("注册失败!" + json.message);}}error: function(xhr){alert("注册时产生未知错我!" + xhr.status);}});});
</script>

6.js代码无法正常被服务器解析执行,体现在点击页面中的按钮没有任何响应,解决方案:

  • 在项目的maven下clear清理项目、install重新部署
  • 在项目的file选项下 cash清理缓存
  • 重新构建项目:build选项下 rebuild选项
  • 重启idea
  • 重启电脑



PostMapping和GetMapping区别

PostMapping和GetMapping区别,使用场景个人理解_BACKLS的博客-CSDN博客

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

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

相关文章

Redis之hash类型

文章目录 Redis之hash类型1. 设置一个字段/获取一个字段2. 获取所有字段值3. 判断字段是否存在4. 设置多个字段/获取多个字段5. 只获取字段名/字段值6. 获取某个key内全部数量7. 增加数字8. 删除key内字段9. 字段不存在时赋值10. 应用场景 Redis之hash类型 redis的hash类型&…

postman接口传参案例

目录 案例1&#xff1a; 接口A 接口B 案例2&#xff1a; //断言 案例1&#xff1a; 接口A 根据返回值需要从返回值中提取userid值&#xff0c;在Tests标签栏下编写脚本 //获取返回的响应值&#xff0c;并转化为json格式 var jsonData pm.response.json(); // 获取返回…

Transformer 01(自注意机制Self-attention)

一、Self-attention [台大李宏毅] 1.1 向量序列的输入 一个序列作为输入&#xff1a; 多个向量输入举例&#xff1a; 一个句子&#xff1a; 声音信号&#xff1a; 图&#xff1a; 1.2 输出 二、Sequence labeling 输入与输出一样多&#xff1a;Sequence labeling 窗口开的…

DDR模块电路的PCB设计建议

DDR电路简介 RK3588 DDR 控制器接口支持 JEDEC SDRAM 标准接口&#xff0c;原理电路16位数据信号如图8-1所示&#xff0c;地址、控制信号如图8-2所示&#xff0c;电源信号如图8-3所示。电路控制器有如下特点&#xff1a; 1、兼容 LPDDR4/LPDDR4X/LPDDR5 标准&#xff1b; 2、…

[补题记录] Atcoder Beginner Contest 309(E)

URL&#xff1a;https://atcoder.jp/contests/abc309 目录 E Problem/题意 Thought/思路 解法一&#xff1a; 解法二&#xff1a; Code/代码 E Problem/题意 一个家庭有 N 个人&#xff0c;根节点为 1&#xff0c;给出 2 ~ N 的父节点。一共购买 M 次保险&#xff0c;每…

数据包络分析(DEA)——CCR模型

写在前面&#xff1a; 博主本人大学期间参加数学建模竞赛十多余次&#xff0c;获奖等级均在二等奖以上。为了让更多学生在数学建模这条路上少走弯路&#xff0c;故将数学建模常用数学模型算法汇聚于此专栏&#xff0c;希望能够对要参加数学建模比赛的同学们有所帮助。 目录 1. …

Java基于微信小程序的青少年健康心理科普平台

第一章 简介 青少年心理健康科普平台为用户提供心理医生咨询服务&#xff0c;系统包括微信小程序端和后台。 微信小程序用户可以先进行注册&#xff0c;填写个人的基本信息提交到服务器&#xff0c;服务器把数据保存到数据库。管理员对青少年的信息进行验证后&#xff0c;青少…

Fedora Linux 39 Beta 预估 10 月底发布正式版

Fedora 39 Beta 镜像于今天发布&#xff0c;用户可以根据自己的使用偏好&#xff0c;下载 KDE Plasma&#xff0c;Xfce 和 Cinnamon 等不同桌面环境版本&#xff0c;正式版预估将于 10 月底发布 Fedora 39 Beta 版本主要更新了 DNF 软件包管理器&#xff0c;并优化了 Anaconda …

ASfP: 增强AOSP平台开发的利器——Android Studio for Platform

ASfP: 增强AOSP平台开发的利器——Android Studio for Platform Android Studio for Platform (ASfP) 是一个为使用 Soong 构建系统构建的 Android 开源项目&#xff08;AOSP&#xff09;平台开发者而设计的 Android Studio IDE 版本。与标准 Android Studio 不同&#xff0c;…

【Zabbix监控一】zabbix的原理与安装

利用一个优秀的监控软件&#xff0c;我们可以: ●通过一个友好的界面进行浏览整个网站所有的服务器状态 ●可以在 Web 前端方便的查看监控数据 ●可以回溯寻找事故发生时系统的问题和报警情况 总结&#xff1a;zabbix主要功能 监控&#xff0c;cpu负载&#xff0c;内存使用&a…

IT行业未来三年最靠谱的职业方向选择,一定要看完!

近些年“互联网”模式不断发展&#xff0c;以信息化带动传统产业的升级中&#xff0c;社会对IT互联网人才的需求量也在不断增加。随着AI、大数据、人工智能、云计算的兴起&#xff0c;也为对新兴事物充满兴趣热爱和探索的年轻人带来了更多的就业机会&#xff0c;在很大程度上激…

Nginx rewrite+防盗链

Nginx Nginx6、重写功能rewrite6.1 if指令6.2 return6.3 set指令6.4 break指令6.5 rewrite指令6.5.1 基本原理6.5.2 语法格式6.5.3 举例6.5.3.1 测试访问bj跳转到beijing6.5.3.2 域名重定向&#xff1a;所有域名都跳转到accp 7、防盗链7.1 什么是防盗链7.2 防盗链简介7.3 实现防…

《研发效能(DevOps)工程师国家职业技术认证》工信部教考中心认证证书:塑造研发效能的黄金标准丨IDCF

随着科技的飞速发展和市场竞争的日益激烈&#xff0c;高素质的技术管理人才在当今社会中扮演着越来越重要的角色。特别是在信息技术领域&#xff0c;企业对于拥有专业技能和丰富知识的研发效能管理与技术人才的需求愈发旺盛。工业和信息化部教育与考试中心&#xff08;以下简称…

MissionPlanner编译过程

环境 windows 10 mission planner 1.3.80 visual studio 2022 git 2.22.0 下载源码 (已配置git和ssh) 从github上克隆源码 git clone gitgithub.com:ArduPilot/MissionPlanner.git进入根目录 cd MissionPlanner在根目录下的ExtLibs文件下是链接的其它github源码&#xff0…

【深度学习】 Python 和 NumPy 系列教程(十二):NumPy详解:4、数组广播;5、排序操作

目录 一、前言 二、实验环境 三、NumPy 0、多维数组对象&#xff08;ndarray&#xff09; 多维数组的属性 1、创建数组 2、数组操作 3、数组数学 4、数组广播 5、排序操作 1. np.sort() 函数 2. np.argsort() 函数 3. ndarray.sort() 方法 4. 按列或行排序 5. n…

Mybatis 映射器中使用@InsertProvider,@UpdateProvider,@DeleteProvider,@SelectProvider

上一篇我们介绍了在Mybatis映射器的映射方法中使用Param接收多个参数&#xff1b;本篇我们继续介绍如何在Mybatis的映射器中使用动态SQL。 如果您对Mybatis映射器的映射方法中使用Param接收多个参数不太了解&#xff0c;建议您先进行了解后再阅读本篇&#xff0c;可以参考&…

【Java 基础篇】Java 多线程详解

多线程是 Java 编程中的一个重要概念&#xff0c;它允许程序同时执行多个任务&#xff0c;提高了程序的性能和响应能力。本篇博客将深入探讨 Java 多线程&#xff0c;从基础概念到实际应用&#xff0c;适用于 Java 初学者和希望深入了解多线程的开发人员。 什么是多线程&#…

Vue之路由及Node.js环境搭建(一起探索新事物)

目录 ​编辑 前言 一、Vue之路由 1.路由简介 1.1 什么是路由 1.2 什么是SPA 1.3 SPA的实现思路 1.4 使用路由的优势 2. 案例演示 2.1 导入所需的js文件 2.2 编写案例代码&#xff08;模拟页面跳转&#xff09; 二、Vue之node.js 1. node.js简介 1.1 什么是node.j…

ubuntu 18.04 中 eBPF samples/bpf 编译

1. history 信息 一次成功编译 bpf 后执行 history 得到的信息&#xff1a; yingzhiyingzhi-Host:~/ex/ex_kernel/linux-5.4$ history1 ls2 mkdir ex3 cd ex4 mkdir ex_kernel5 ls /boot/6 sudo apt install linux-source7 ls /usr/src/8 uname -r9 cd ex_kernel/10…

postman记录backup

之前一直未登录postman&#xff0c;在临时空间处理请求&#xff0c;可能是因为postman更新了&#xff0c;导致其记录没了 别着急&#xff01; 首先我们先登录postman&#xff0c;有谷歌登录方式等 第一步、登录后点击import 第二步、点击files 第三步、找到c:/users/AppData…