【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.rhkb.cn/news/142765.html

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

相关文章

linux下CentOS安装mysql-5.7

linux下安装mysql只需要在root用户下安装&#xff0c;普通用户也能使用 1.检查&#xff1a; 通过以下两条命令查看改系统下是否已存在mysql。 ps ajx | grep mysql ps ajx | grep mariadb通过指令如果只显示如下两条信息&#xff0c;则当前系统下不存在MySQL。 就可以直接进…

区块链实验室(27) - 区块链+物联网应用案例

分享最新的区块链物联网应用案例&#xff1a;HPCLS-BC

PHP禁止单个用户多设备同时登陆,限制单个用户在多端重复登录

逻辑简单,主要是3点&#xff1a; 1.登录的时候写入一个最新的登录IP到user表其中一个last_login_ip字段 2.登录成功的时候,转入到index控制器或者index方法之前先进行查询&#xff1a; 1).当前IP 2).数据库字段当前用户存储的last_login_ip里面的IP 3.然后进行判断&#xff0…

虹科方案 | 车辆总线数据记录仪解决方案

全文导读&#xff1a;针对车辆总线的数据记录&#xff0c;虹提出的解决方案是利用CANedge系列的CAN/LIN总线数据记录仪&#xff0c;根据不同的使用场合和传输方式&#xff08;SD卡/WiFi/3G/4G&#xff09;&#xff0c;选择相应的产品轻松记录车辆中的总线数据&#xff0c;助力您…

Redis高可用之持久化、主从复制(附配置实例)

目录 一、Redis高可用1.1 简介1.2 高可用策略 二、Redis 持久化2.1 简介2.2 redis 的 2 种持久化方式2.2.1 RDB持久化2.2.2 AOF持久化 三、Redis主从复制3.1 什么是主从复制&#xff1f;3.2 为什么要用主从复制&#xff1f;3.3 主从复制的特性3.4 主从复制工作原理3.4.1 全量复…

【【萌新的RISCV学习之流水线通路的控制-8】】

萌新的RISCV学习之流水线通路的控制-8 我们在之前学习了整个单周期的模块工作流程 我们按照整体的思路分段 将数据通路划分为5个阶段 IF &#xff1a; 取地址 ID &#xff1a;指令译码和读存储器堆 EX :执行或计算地址 MEM : 数据存储器访问 WB : 写回 单周期数据通路&…

飞书与企业微信的异同

云文档 飞书的云文档会自动用游览器打开&#xff0c;不会直接在PC应用中打开&#xff08;移动端能在应用中打开&#xff09;。 飞书云文档能够插入视频、流程图、问卷等等 聊天消息交互 钉钉也有类似的功能&#xff0c;可以针对消息进行点赞等回复 钉钉的消息回复还有【收到…

5.外部中断

中断初始化配置步骤&#xff1a; IO口初始化配置 开启中断总允许EA 打开某个IO口的中断允许 打开IO口的某一位的中断允许 配置该位的中断触发方式 中断函数&#xff1a; #pragma vector PxINT_VECTOR __interrupt void 函数名(void){}#pragma vector PxINT_VECTOR __int…

【pytest】 标记冒烟用例 @pytest.mark.smoke

1. 使用 pytest.mark.smoke 标记用例 import pytest class Test_Smoke:def test_01(self):assert 112pytest.mark.smokedef test_02(self):assert 121pytest.mark.smokedef test_03(self):assert 1 2 3 2.配置文件pytest.ini [pytest] markers smoke 3. 运行指定标签 运…

网络安全复习大纲wcf

单选10判断10填空30简答25分析25 选择 &#xff08;1&#xff09;计算机网络安全是指利用计算机网络管理控制和技术措施&#xff0c;保证在网络环境中数据的&#xff08; &#xff09;、完整性、网络服务可用性和可审查性受到保护。 A、保密性 B、抗攻击性 C、网络服务管理性 …

Unity之NetCode多人网络游戏联机对战教程(2)--简单实现联机

文章目录 1.添加基本组件2.创建NetworkManager组件3.创建Player4.创建地面5.创建GameManager6.编译运行7. 测试联机后话 1.添加基本组件 NetworkManagerPlayerScene 2.创建NetworkManager组件 创建一个空物体&#xff0c;命名为NetworkManager 选择刚刚创建的NetworkManager…

VS2022 编译protobuf , qt 使用

一、下载源码 protobuf: 同步 https://github.com/protocolbuffers/protobuf (gitee.com) 下载如v3.11.2 版本 二、下载CMake 三、编译 1、在1处选择源码目录下的cmake 目录&#xff1b;在2处选择一处空目录&#xff08;自己随便建&#xff09; 2、点击config&#xff0c;选择…

【面试八股】IP协议八股

IP协议八股 子网掩码的作用为什么IP协议需要分片IP协议什么时候需要分片IP协议是怎么进行分片的那么IP协议是如果进行标识属于同一个分片呢&#xff1f;TCP协议和UDP协议将数据交给IP协议之后&#xff0c;是否需要分片传输&#xff1f; 子网掩码的作用 用来标识网络号和主机号…

新媒体运营的未来:ChatGPT的智能助手

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 新媒体运营是数字时代的…

【李沐深度学习笔记】线性回归的从零开始实现

课程地址和说明 线性回归的从零开始实现p3 本系列文章是我学习李沐老师深度学习系列课程的学习笔记&#xff0c;可能会对李沐老师上课没讲到的进行补充。 线性回归的从零开始实现 不使用任何深度学习框架提供的计算功能&#xff0c;只使用PyTorch提供的Tensor来实现线性回归…

合肥对新通过(CMMI)五级、四级、三级认证的软件企业,对新通过信息技术服务标准(ITSS)认证的软件企业,给予最高50万奖励

合肥市加快软件产业发展 推进软件名城创建若干政策实施细则 为贯彻落实《合肥市人民政府办公室关于印发合肥市加快软件产业发展推进软件名城创建若干政策的通知》&#xff08;合政办〔2023〕9号&#xff09;文件精神&#xff0c;规范政策资金管理&#xff0c;制定本实施细则。…

linux内网渗透

一、信息收集 主机发现&#xff1a; nmap -sP 192.168.16.0/24 端口探测 masscan -p 1-65535 192.168.16.168 --rate1000 开放端口如下 nmap端口详细信息获取 nmap -sC -p 8888,3306,888,21,80 -A 192.168.16.168 -oA ddd4-port目录扫描 gobuster dir…

同创永益CNBR平台——云原生时代下的系统稳定器

随着各行业数字化的快速发展&#xff0c;企业的业务运作、经营管理越来越依赖于云原生系统的可靠运行。信息系统服务的连续性, 业务数据的完整性、正确性、有效性会直接关系到企业的生产、经营与决策活动。一旦因自然灾害、设备故障或人为因素等引起信息数据丢失和云原生业务处…

TextSniper for Mac: 革新您的文本识别体验

你是否曾经需要从图片或扫描文档中提取文本&#xff0c;却苦于没有合适的工具&#xff1f;那么&#xff0c;TextSniper for Mac将是你的完美解决方案。这款文本识别工具将彻底改变你处理图像和扫描文件的方式&#xff0c;让你更快速、更高效地完成任务。 TextSniper for Mac 是…

Apache Hive安装部署详细图文教程

目录 一、Apache Hive 元数据 1.1 Hive Metadata 1.2 Hive Metastore 二、Metastore 三种配置方式 ​2.1 内嵌模式 ​2.2 本地模式 ​2.3 远程模式 ​三、Hive 部署实战 3.1 安装前准备 3.2 Hadoop 与 Hive 整合 3.3 远程模式安装 3.3.1 安装 MySQL 3.3.2 …