【基于SprintBoot+Mybatis+Mysql】电脑商城项目之用户注册

      🧸安清h:个人主页

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

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


目录

🎯项目基本介绍

🚦项目功能

🚦开发顺序

🚦模块的开发

🎯项目的开发环境

 🎯搭建项目

 🎯用户注册

🚦1.选中数据表

🚦2.创建t_user表

🚦3.创建用户实体类

 ✨创建BaseEntity

 ✨创建实体类User

🚦4.注册-持久层 

✨规划需要执行的sql语句

✨设计接口和抽象方法

✨编写映射

🚦5.注册-业务层

✨5.1规划异常

🎃5.1.1RuntimeException异常

🎃5.1.2用户名被占用异常

🎃5.1.3数据插入异常

✨ 5.2设计接口和抽象方法 

🚦6.注册-控制层

✨6.1创建响应

✨6.2设计请求

✨6.3处理请求

✨6.4控制层优化设计

🚦7.注册-前端页面


 🎯项目基本介绍

🚦项目功能

本项目主要实现功能为:登录,注册,热销商品,用户管理(密码,个人信息,头像,收货地址),购物车(展示,增加,删除),订单模块。

🚦开发顺序

注册,登录,用户管理,购物车,商品,订单模块。

🚦模块的开发

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

🎯项目的开发环境

1.JDK:1.8及以上版本

2.maven:配置到idea,3.6.1版本

3.数据库:Mysql,要求5.1及以上版本

4.开发的平台:idea开发

 🎯搭建项目

1.项目的名称:store,表示商城

2.结构:com.cy.store

3.资源文件:resources文件夹下(static、templates)

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

5.

6.点击next后,先选择以下三个jar包。

(1)WEB:Spring Web(用于前后端连接)

(2)SQL:Mybatis Framework

(3)SQL:MySQL Driver(用于mysql数据库驱动)

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

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

8.创建一个store数据库

create database store character set utf8;

9.测试连接:

  • 启动SpringBoot主类,是否有对应的Spring图形输出

在src->main->java->com.cy.store->StoreApplication,启动main方法,得到如下图形即为启动成功:

  • 在单元测试类中测试数据库的连接是否可以正常加载

如果出现了以下图片中的Hikari,则代表成功。Hikari是用来管理数据库的连接对象。

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

注意:idea对于JS代码的兼容性较差,编写了js代码但是有时候不能够正常去加载。

  • idea缓存清理
  • clear-install,双击clean后再次install

  • rebuild重新构建
  • 重启idea和操作系统

 🎯用户注册

🚦1.选中数据表

use store

🚦2.创建t_user表

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;
  1. salt盐值:在用户注册时,对其密码进行加密操作,重要
  2. 性别:用阿拉伯数字0和1来表示性别,原因在于前端不太好用文字来展示一个人的性别,性别是单选框,一半给一个整数好去操作和判断。
  3. is_delete:大部分厂商都没有实现真正的删除,只是在登录的时候做一个校验,来检测是否为0,如果不为0,就表示已经删除了。
  4. 四个基础字段,任何一张表都有的,将其作为整个实体类。,

created_user VARCHAR(20) COMMENT ‘创建人’,

created_time DATETIME COMMENT ‘创建时间’,

modified_user VARCHAR(20) COMMENT ‘修改人’,

modified_time DATETIME COMMENT ‘修改时间’,

🚦3.创建用户实体类

 ✨创建BaseEntity

实体基类,里面存放的为所有表的公共字段。

public class BaseEntity implements Serializable {private String createdUser;private Date createdTime;private String modifiedUser;private Date modifiedTime;
}//get和set方法、equals和hashCode()方法、toString方法

 ✨创建实体类User

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和hashCode()方法、toString方法
}

🚦4.注册-持久层 

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

✨规划需要执行的sql语句

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

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

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

select * from t_user where username=?

✨设计接口和抽象方法

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

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")

✨编写映射

1.定义xml映射文件,与对应的接口进行关联。所有的映射文件需要放置在resources目录下,在这个目录下创建一个mapper文件夹,然后在这个文件夹存放Mapper的映射文件。

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

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace属性:用于指定当前的映射文件和哪个接口进行映射,需要指定接口的文件路径,需要标注包的完整路径接口-->
<mapper namespace="com.cy.store.mapper.UserMapper"></mapper>

 3.配置接口中的方法对应上SQL语句。需要借助标签来完成,insert/update/delete/select,对应的是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">
<!--namespace属性:用于指定当前的映射文件和哪个接口进行映射,需要指定接口的文件路径,需要标注包的完整路径接口-->
<mapper namespace="com.cy.store.mapper.UserMapper">
<!--    resultMap标签来完成映射规则的定义--><resultMap id="UserEntityMap" type="com.cy.store.entity.User">
<!--       配合完成名称不一致的映射:column:表中的字段名称property:类中的属性名称
-->
<!--        在定义映射规则时,主键是不可以省略的--><id column="uid" property="uid"></id><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><!--    id属性:表示映射的接口中方法的名称,直接在标签的内部来编写SQL语句-->
<!--    useGeneratedKeys:开启某个字段的值递增(主键设为递增)-->
<!--    keyProperty:将表中那个字段作为主键进行递增--><insert id="insert" useGeneratedKeys="true" keyProperty="uid">insert into t_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><select id="findByUsername" resultMap="UserEntityMap">select * from t_user where username=#{username}</select>
</mapper>

4.将mapper文件的位置注册到properties对应的配置文件中,在application.properties文件中添加如下代码:

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

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

//@SpringBootTest标注当前的类是一个测试类,不会随同项目一块打包
@SpringBootTest
public class UserMapperTests {@Autowiredprivate UserMapper userMapper;
//    单元测试方法:可以单独独立运行,不用启动整个项目,提高了代码运行效率
//    1.必须被@Test注解修饰
//    2.返回值类型必须是void
//    3.方法的参数类型不指定任何类型
//    4.方法的访问修饰符必须是public@Testpublic void insert(){User user=new User();user.setUsername("tim");user.setPassword("123");Integer rows=userMapper.insert(user);System.out.println(rows);}@Testpublic void findByUsername(){User user=userMapper.findByUsername("tim");System.out.println(user);}
}

🚦5.注册-业务层

✨5.1规划异常

🎃5.1.1RuntimeException异常

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

//业务层异常的基类
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异常类。 

🎃5.1.2用户名被占用异常

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

//用户名被占用的异常
public class UsernameDuplicatedException extends ServiceException{public UsernameDuplicatedException() {super();}public UsernameDuplicatedException(String message) {super(message);}public UsernameDuplicatedException(String message, Throwable cause) {super(message, cause);}public UsernameDuplicatedException(Throwable cause) {super(cause);}protected UsernameDuplicatedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}

alt+insert打开快捷方式,选中前五个如图:

🎃5.1.3数据插入异常

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

//数据在插入过程中产生的异常
public class InsertException extends ServiceException{public InsertException() {super();}public InsertException(String message) {super(message);}public InsertException(String message, Throwable cause) {super(message, cause);}public InsertException(Throwable cause) {super(cause);}protected InsertException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}

✨ 5.2设计接口和抽象方法 

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

//用户模块业务层接口
public interface IUserService {void reg(User user);
}

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

//用户模块业务层的实现类
@Service
public class UserServiceImpl implements IUserService {@Autowiredprivate UserMapper userMapper;@Overridepublic void reg(User user) {
//        通过user参数来获取传递过来的usernameString username= user.getUsername();//调用findByUsername(username)判断用户是否被注册过User result = userMapper.findByUsername(username);
//        判断结果集是否不为null,则抛出用户名被占用的异常if(result !=null){throw new UsernameDuplicatedException("用户名被占用");}
//        密码加密处理的实现:md5算法的形式
//        串+password+串------md5算法进行加密,连续加载三次
//        盐值+password+盐值------盐值就是一个随机的字符串String oldPassword = user.getPassword();
//        获取盐值(随机生成一个盐值)String salt = UUID.randomUUID().toString().toUpperCase();
//        补全数据:盐值的记录user.setSalt(salt);
//        将密码和盐值作为一个整体进行加密处理,忽略原有密码的强度,提升了数据的安全性String md5Password = getMD5Password(oldPassword,salt);
//        将加密之后的密码重新补全设置到user对象中user.setPassword(md5Password);//        补全数据:is_delete设置成0user.setIsDelete(0);
//        补全数据:四个日志字段信息user.setCreatedUser(user.getUsername());user.setModifiedUser(user.getUsername());Date date=new Date();user.setCreatedTime(date);user.setModifiedTime(date);//        执行注册业务功能的实现(rows=1)Integer rows=userMapper.insert(user);if(rows!=1){throw new InsertException("在用户注册过程中产生了未知的异常");}}
//    定义一个md5算法的加密处理private String getMD5Password(String password,String salt){
//        md5加密算法方法的调用(进行三次加密)for(int i=0;i<3;i++){password=DigestUtils.md5DigestAsHex((salt+password+salt).getBytes()).toUpperCase();}
//        返回加密之后的密码return password;}
}

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

//@SpringBootTest标注当前的类是一个测试类,不会随同项目一块打包
@SpringBootTest
public class UserServiceTests {@Autowiredprivate IUserService userService;
//    单元测试方法:可以单独独立运行,不用启动整个项目,提高了代码运行效率
//    1.必须被@Test注解修饰
//    2.返回值类型必须是void
//    3.方法的参数类型不指定任何类型
//    4.方法的访问修饰符必须是public@Testpublic void reg(){try {User user=new User();user.setUsername("yuanxin01");user.setPassword("123");userService.reg(user);System.out.println("OK");} catch (ServiceException e) {
//            获取类的对象,再获取类的名称System.out.println(e.getClass().getSimpleName());
//            获取异常的具体描述信息System.out.println(e.getMessage());}}}

🚦6.注册-控制层

✨6.1创建响应

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

//Json格式的数据进行响应
public class JsonResult<E> implements Serializable {
//    状态码private Integer state;
//    描述信息private String message;
//    数据private E data;public JsonResult(Integer state) {this.state = state;}public JsonResult(Throwable e) {this.message = e.getMessage();}public JsonResult(Integer state, E data) {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;}
}

✨6.2设计请求

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

请求路径:/users/reg

请求参数:user user

请求类型:POST

响应结果:JsonResult<void>

✨6.3处理请求

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

@RestController  //@Controller+@RequestBody
@RequestMapping("users")
public class UserController {@Autowiredprivate IUserService userService;@RequestMapping("reg")// @RequestBody //表示此方法的响应结果以json格式进行数据的响应给到前端public JsonResult<Void> reg(User user){JsonResult<Void> result=new JsonResult<>();try {userService.reg(user);result.setState(200);result.setMessage("用户注册成功");} catch (UsernameDuplicatedException e) {result.setState(4000);result.setMessage("用户名被占用");}catch (InsertException e) {result.setState(5000);result.setMessage("注册时产生未知的异常");}return result;}
}

✨6.4控制层优化设计

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

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

 重新构建了reg()方法。

@RestController  //@Controller+@RequestBody
@RequestMapping("users")
public class UserController extends BaseController{@Autowiredprivate IUserService userService;@RequestMapping("reg")public JsonResult<Void> reg(User user){userService.reg(user);return new JsonResult<>(OK);}
}

🚦7.注册-前端页面

1.在register页面中编写发送请求的方法,点击事件来完成。选中对应的按钮($("选择器")),再去添加点击的事件,$.ajax()函数发送异步请求。

2.JQuery封装了一个函数,称之为$.ajax()函数,通过对象调用ajax,可以异步加载相关的请求。ajax可以把某一部分的局部看做成一个独立的整体。依靠的是javascript提供的一个对象XHR(XmlHttpResponse),封装了这个对象。

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

$.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>//1.监听注册按钮是否被点击,如果被点击可以执行一个方法$("#btn-reg").click(function () {// 2.发送ajax()的异步请求来完成用户的注册功能$.ajax({url: "/users/reg",type: "POST",data: $("#form-reg").serialize(),dataType: "JSON",success: function (json) { if (json.state == 200) {alert("注册成功")} else {alert("注册失败")}},error: function (xhr) { alert("注册时产生未知的错误!"+xhr.status);}});});</script>

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

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

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

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

    相关文章

    Microsoft Power BI:融合 AI 的文本分析

    Microsoft Power BI 是微软推出的一款功能强大的商业智能工具&#xff0c;旨在帮助用户从各种数据源中提取、分析和可视化数据&#xff0c;以支持业务决策和洞察。以下是关于 Power BI 的深度介绍&#xff1a; 1. 核心功能与特点 Power BI 提供了全面的数据分析和可视化功能&…

    电控三周速成计划参考

    第1周&#xff1a;基础搭建与GPIO控制 学习目标&#xff1a;建立开发环境&#xff0c;掌握最基础的硬件控制能力 每日学习&#xff08;2-3小时&#xff09;&#xff1a; 环境搭建&#xff08;2天&#xff09; 安装Keil MDK-ARM STM32CubeMX使用CubeMX创建第一个工程&#xf…

    [SAP ABAP] 在ABAP Debugger调试器中设置断点

    在命令框输入/H&#xff0c;点击回车以后&#xff0c;调试被激活&#xff0c;点击触发任意事件进入ABAP Debugger调试器界面 点击按钮&#xff0c;可以在Debugger调试器中新增临时断点 我们可以从ABAP命令、方法、功能、表单、异常、消息、源代码等多个维度在Debugger调试器中设…

    【NEXT】网络编程——上传文件(不限于jpg/png/pdf/txt/doc等),或请求参数值是file类型时,调用在线服务接口

    最近在使用华为AI平台ModelArts训练自己的图像识别模型&#xff0c;并部署了在线服务接口。供给客户端&#xff08;如&#xff1a;鸿蒙APP/元服务&#xff09;调用。 import核心能力&#xff1a; import { http } from kit.NetworkKit; import { fileIo } from kit.CoreFileK…

    RssWebAll:抓取任意网页的内容生成 RSS 订阅源

    RssWebAll&#xff1a;抓取任意网页的内容生成 RSS 订阅源 RssWebAll 是一个强大的工具&#xff0c;可以帮助用户抓取任意网页的内容&#xff0c;并生成相应的 RSS 订阅源&#xff0c;让用户随时随地获取他们感兴趣的内容更新。 功能亮点 简单易用&#xff1a;所见即所得&…

    从一到无穷大 #43:Presto History Based Optimizer,基于PlanNode粒度统计的查询计划选择策略

    本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言MotivationArchitectureHBO ScenarioExperiments结束语 引言 过年回家这件事在挚…

    【C++】继承(下)

    大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解C的继承&#xff08;下&#xff09;&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 5.继承与友元6.继承与静态成员7.复杂的菱形继承及菱形虚拟继承8.继…

    项目开发实践——基于SpringBoot+Vue3实现的在线考试系统(九)(完结篇)

    文章目录 一、成绩查询模块实现1、学生成绩查询功能实现1.1 页面设计1.2 前端页面实现1.3 后端功能实现2、成绩分段查询功能实现2.1 页面设计2.2 前端页面实现2.3 后端功能实现二、试卷练习模块实现三、我的分数模块实现1、 页面设计2、 前端页面实现3、 后端功能实现四、交流区…

    【流媒体】搭建流媒体服务器

    搭建Windows Nginx服务器 搭建 下载nginx工具包解压至本地&#xff0c;并在cmd窗口中切换至nginx所在的本地目录修改 conf/nginx.conf 文件&#xff0c;更改其端口号 server中的 listen的端口号从 80改为 8080&#xff0c;因为80经常被其他服务占用&#xff0c;导致无法打开 …

    携程Java开发面试题及参考答案 (200道-下)

    insert 一行数据的时候加的是什么锁?为什么? 在 MySQL 中,当执行 INSERT 操作插入一行数据时,加锁的情况会因存储引擎和具体的事务隔离级别而有所不同。一般来说,在 InnoDB 存储引擎下,INSERT 操作加的是行级排他锁(Row Exclusive Lock),以下详细说明原因。 行级排他…

    洛谷P11655「FAOI-R5」Lovely 139

    P11655「FAOI-R5」Lovely 139 题目背景 Update&#xff1a;数据有 0 0&#xff0c;答案为 1&#xff0c;请选手特判以正常通过。 Height ≤ 139 \text{Height}\leq139 Height≤139。 题目描述 对于一个 01 \tt 01 01 串 S S S&#xff08;下标从 1 1 1 开始&#xff09;…

    【Linux】24.进程信号(1)

    文章目录 1. 信号入门1.1 进程与信号的相关知识1.2 技术应用角度的信号1.3 注意1.4 信号概念1.5 信号处理常见方式概览 2. 产生信号2.1 通过终端按键产生信号2.2 调用系统函数向进程发信号2.3 由软件条件产生信号2.4 硬件异常产生信号2.5 信号保存 3. 阻塞信号3.1 信号其他相关…

    《手札·开源篇》从开源到商业化:中小企业的低成本数字化转型路径 ——以Odoo为数据中台低成本实现售前售中一体化

    某机电设备有限公司数字化转型案例&#xff1a;以Odoo为数据中台实现售前售中一体化 一、企业背景某机电设备有限公司在机电设备领域历经多年发展&#xff0c;业务广泛&#xff0c;涵盖工业自动化设备、电力设备等产品的销售与服务。随着业务版图不断拓展&#xff0c;企业面临…

    笔试-业务逻辑4

    应用 小明在玩一个数字加减游戏&#xff0c;输入4个正整数&#xff1a;s、t、a、b&#xff0c;其中s>1&#xff0c;b<105&#xff0c;a!b。只使用加法或者减法&#xff0c;使得st。 每回合&#xff0c;小明用当前的数字&#xff0c;加上或减去一个数字&#xff1b;目前有…

    Windows 中的 WSL:开启你的 Linux 之旅

    今天在安装windows上安装Docker Desktop的时候&#xff0c;遇到了WSL。下面咱们就学习下。 欢迎来到涛涛聊AI 一、什么是 WSL&#xff1f; WSL&#xff0c;全称为 Windows Subsystem for Linux&#xff0c;是微软为 Windows 系统开发的一个兼容层&#xff0c;它允许用户在 Win…

    编程题-电话号码的字母组合(中等)

    题目&#xff1a; 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 解法一&#xff08;哈希表动态添加&#xff09;&#x…

    python:如何播放 .spx 声音文件

    .spx 是 Speex音频编解码器的文件扩展名&#xff0c;它是一种开源的、免费的音频编解码器&#xff0c;主要用于语音压缩和语音通信领域。spx 文件通常用于语音记录、VoIP应用、语音信箱等场景。 .mp3 是一种广泛使用的音频格式&#xff0c;它采用了有损压缩算法&#xff0c;可…

    数据结构课程设计(三)构建决策树

    3 决策树 3.1 需求规格说明 【问题描述】 ID3算法是一种贪心算法&#xff0c;用来构造决策树。ID3算法起源于概念学习系统&#xff08;CLS&#xff09;&#xff0c;以信息熵的下降速度为选取测试属性的标准&#xff0c;即在每个节点选取还尚未被用来划分的具有最高信息增益的…

    Vue3学习笔记-事件-4

    一、事件处理 使用v-on或者后面加事件&#xff1a; <template><button v-on:click"addCount()">{{count}}</button> </template> 二、事件传参 传event&#xff1a; 不传参时&#xff0c;默认自动接收 event 传自定义参数时&#xff0c…

    Node.js下载安装及环境配置

    目录 一、下载 1. 查看电脑版本&#xff0c;下载对应的安装包 2. 下载路径下载 | Node.js 中文网 二、安装步骤 1. 双击安装包 2. 点击Next下一步 3. 选择安装路径 4. 这里我选择默认配置&#xff0c;继续Next下一步&#xff08;大家按需选择&#xff09; 5. 最后inst…