目录

1. 用户注册

1. 创建t_user表

2. 创建用户实体类

3. 注册-持久层

3.1 规划需要执行的SQL语句

3.2 通过Mybatis来操作数据库

3.3 编写映射

3.4.单元测试

4. 注册-业务层

4.1规划异常

5. 注册-控制层

5.1创建响应

5.2 设计请求

5.3 处理请求

5.4 控制层优化设计

6. 注册-前端页面


1. 用户注册

1. 创建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;

2. 创建用户实体类

  • BaseEntity基类中
import java.io.Serializable;import java.util.Date;//作为实体类基类public class BaseEntity implements Serializable {private String createdUser;private Date createdTime;private String modifiedUser;private String modifiedTime;public String getCreatedUser() {return createdUser;}public void setCreatedUser(String createdUser) {this.createdUser = createdUser;}public Date getCreatedTime() {return createdTime;}public void setCreatedTime(Date createdTime) {this.createdTime = createdTime;}public String getModifiedUser() {return modifiedUser;}public void setModifiedUser(String modifiedUser) {this.modifiedUser = modifiedUser;}public String getModifiedTime() {return modifiedTime;}public void setModifiedTime(String modifiedTime) {this.modifiedTime = modifiedTime;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (!(o instanceof BaseEntity)) return false;BaseEntity that = (BaseEntity) o;if (getCreatedUser() != null ? !getCreatedUser().equals(that.getCreatedUser()) : that.getCreatedUser() != null)return false;if (getCreatedTime() != null ? !getCreatedTime().equals(that.getCreatedTime()) : that.getCreatedTime() != null)return false;if (getModifiedUser() != null ? !getModifiedUser().equals(that.getModifiedUser()) : that.getModifiedUser() != null)return false;return getModifiedTime() != null ? getModifiedTime().equals(that.getModifiedTime()) : that.getModifiedTime() == null;}@Overridepublic int hashCode() {int result = getCreatedUser() != null ? getCreatedUser().hashCode() : 0;result = 31 * result + (getCreatedTime() != null ? getCreatedTime().hashCode() : 0);result = 31 * result + (getModifiedUser() != null ? getModifiedUser().hashCode() : 0);result = 31 * result + (getModifiedTime() != null ? getModifiedTime().hashCode() : 0);return result;}@Overridepublic String toString() {return "BaseEntity{" +"createdUser='" + createdUser + '\'' +", createdTime=" + createdTime +", modifiedUser='" + modifiedUser + '\'' +", modifiedTime='" + modifiedTime + '\'' +'}';}}

tips:将来所有的表都会有以下四个字段

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

created_time DATETIME COMMENT ‘创建时间’,

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

modified_time DATETIME COMMENT ‘修改时间’,

所以为了开发方便可以把这四个字段作为整个实体类

  • BaseEntity基类
import java.io.Serializable;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;  //性别 0-女 1-男private String avatar; // 头像private Integer isDelete; //用户数据是否被删除public Integer getUid() {return uid;}public void setUid(Integer uid) {this.uid = uid;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getSalt() {return salt;}public void setSalt(String salt) {this.salt = salt;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public Integer getGender() {return gender;}public void setGender(Integer gender) {this.gender = gender;}public String getAvatar() {return avatar;}public void setAvatar(String avatar) {this.avatar = avatar;}public Integer getIsDelete() {return isDelete;}public void setIsDelete(Integer isDelete) {this.isDelete = isDelete;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (!(o instanceof User)) return false;if (!super.equals(o)) return false;User user = (User) o;if (getUid() != null ? !getUid().equals(user.getUid()) : user.getUid() != null) return false;if (getUsername() != null ? !getUsername().equals(user.getUsername()) : user.getUsername() != null)return false;if (getPassword() != null ? !getPassword().equals(user.getPassword()) : user.getPassword() != null)return false;if (getSalt() != null ? !getSalt().equals(user.getSalt()) : user.getSalt() != null) return false;if (getPhone() != null ? !getPhone().equals(user.getPhone()) : user.getPhone() != null) return false;if (getEmail() != null ? !getEmail().equals(user.getEmail()) : user.getEmail() != null) return false;if (getGender() != null ? !getGender().equals(user.getGender()) : user.getGender() != null) return false;if (getAvatar() != null ? !getAvatar().equals(user.getAvatar()) : user.getAvatar() != null) return false;return getIsDelete() != null ? getIsDelete().equals(user.getIsDelete()) : user.getIsDelete() == null;}@Overridepublic int hashCode() {int result = super.hashCode();result = 31 * result + (getUid() != null ? getUid().hashCode() : 0);result = 31 * result + (getUsername() != null ? getUsername().hashCode() : 0);result = 31 * result + (getPassword() != null ? getPassword().hashCode() : 0);result = 31 * result + (getSalt() != null ? getSalt().hashCode() : 0);result = 31 * result + (getPhone() != null ? getPhone().hashCode() : 0);result = 31 * result + (getEmail() != null ? getEmail().hashCode() : 0);result = 31 * result + (getGender() != null ? getGender().hashCode() : 0);result = 31 * result + (getAvatar() != null ? getAvatar().hashCode() : 0);result = 31 * result + (getIsDelete() != null ? getIsDelete().hashCode() : 0);return result;}@Overridepublic String toString() {return "User{" +"uid=" + uid +", username='" + username + '\'' +", password='" + password + '\'' +", salt='" + salt + '\'' +", phone='" + phone + '\'' +", email='" + email + '\'' +", gender=" + gender +", avatar='" + avatar + '\'' +", isDelete=" + isDelete +'}';}}

tips:

实体类BaseEntity中自动导入Getter and Setter方法,euqals()方法,hashCode()方法,toString方法,其中euqals()方法,hashCode()方法自动导入步骤:

  • enter+insert
  • euqals() and hashCode()
  • Accept…和Use这两段话,并且选择Template为IntelliJ Default
  • next到底

ssm框架开发项目的时候需要在实体类上面加@Component然后spring才能自动进行对象的创建维护,而springboot不再需要,因为springboot遵循的原则是约定大于配置,如果字段名称相同那就可以自动完成字段的初始化。

3. 注册-持久层

通过Mybatis来操作数据库。

3.1 规划需要执行的SQL语句

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

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

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

select * from t_user where username=?

3.2 通过Mybatis来操作数据库

1.定义Mapper接口。在项目的目录结构下首先创建一个mapper包,在这个包下根据不同的功能模块来创建mapper接口。创建一个UserMapper接

//用户模块持久层接口

public interface UserMapper {/*** 插入用户数据* @param user 用户数据* @return 受影响的行数(增删改 都受影响的行数作为返回值,可以根据返回值来判断是否执行成功)*/Integer integer(User user);/*** 根据用户名来查询用户的数据* @param username 用户名* @return 如果找到对应的用户则返回这个用户的数据,如果没有找到则返回null值*/User findByUsername(String username);}

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

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

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

3.3 编写映射

1.定义xml映射文件,与对应接口进行关联。所有的映射文件需要放置在resource目录结构下,一般在这个目录下创建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.wzh.store.mapper.UserMapper"></mapper>

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

  • into () values (),因为values后面插入的值是动态值,mybatis规定需要用占位符来占位,并给占位符起一个变量的名字,且变量的名字需要在占位符#{}内部
  • t_user表时 uid INT AUTO_INCREMENT COMMENT  ‘用户id’中的AUTO_INCREMENT表示主键uid自增,所以需要useGeneratedKeys和keyProperty
<mapper namespace="com.wzh.store.mapper.UserMapper"><!--id属性:表示给这个映射规则分配一个唯一的id值,对应的就是resultMap="id属性值"type属性:取值是一个类,表示数据库中的查询结果与java中哪个实体类进行结果集的映射--><resultMap id="UserEntityMap" type="com.wzh.store.entity.User"><!--将标的资源和类的属性不一致的字段进行匹配指定,名称一致的字段可以省略不写无论何时主键都不可以省略!!!!!!!!!--><id column="uid" property="uid"/><result column="is_delete" property="isDelete"/><result column="created_user" property="createdUser"/><result column="modified_user" property="modifiedUser"/><result column="modified_time" property="modifiedTime"/><result column="created_time" property="createdTime"/></resultMap><!--id: 表示映射的接口中方法的名称useGeneratedKeys属性: 表示开启某个字段的值递增keyProperty属性: 标签将表中的哪个字段作为主键进行递增--><insert id="insert" useGeneratedKeys="true" keyProperty="uid">INSERT INTO t_user (uid,username,password,salt,phone,email,gender,avatar,is_delete,created_user,created_time,modified_user,modified_time)VALUES (#{uid},#{username},#{password},#{salt},#{phone},#{email},#{gender},#{avatar},#{is_delete},#{created_user},#{created_time},#{modified_user},#{modified_time})</insert><!--resultType: 表示查询的结果集类型,只需要指定对应映射类的类型,并且包含完整包接口resultMap: 表示当表的资源和类的对象属性的字段名称不一致时,来定义查询结果集的映射规则--><select id="findByUsername" resultMap="UserEntityMap">SELECT * FROM t_user WHERE username = #{username}</select></mapper>

3.4.单元测试

1. 每个独立的层编写完毕后都需要编写单元测试方法,来测试当前的功能。

2. 在test包结构下创建一个mapper包,在这个包下再创建持久层的功能测试,单元测试方法是独立运行,不用启动整个项目,提高了代码的测试效率

3. 因为测试方法要用到mapper层的接口来访问刚刚写的两个方法,所以要在类里面声明UserMapper对象:即private UserMapper userMapper;且需要加上@Autowired完成值的初始化,但此时会发现提示"Could not autowire.No beans of’UserMapper’type found",报错原因是idea有自动检测的功能,在java中接口是不能够直接创建bean的,所以idea认为这个语法不合理,但本质上在项目启动时mybatis自动创建了接口的动态代理实现类,所以从项目的运行角度讲这不能算是错.解决办法:

  • Settings里面搜索inspections,依次找到Spring->Spring Core->Code->Autowiring for Bean Class然后将Severity的Error改为Warning

关于第三条,建议直接使用@Resource

4. 在application.properties文件中增添:

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

4. 注册-业务层

4.1规划异常

1. 作为RuntimeException异常的子类,然后再去定义具体的异常类型来继承这个异常。创建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);}}

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

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

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);}}

4.2设计接口和抽象方法

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

import com.wzh.store.entity.User;public interface IUserService {/*** 用户注册方法* @param user 用户的数据对象*/void reg(User user);}

2. 创建实现类UserServiceImpl 来实现接口和抽象方法。

package com.wzh.store.service.impl;import com.wzh.store.entity.User;import com.wzh.store.mapper.UserMapper;import com.wzh.store.service.IUserService;import com.wzh.store.service.ex.InsertException;import com.wzh.store.service.ex.UsernameDuplicateException;import org.springframework.stereotype.Service;import org.springframework.util.DigestUtils;import javax.annotation.Resource;import java.nio.charset.StandardCharsets;import java.util.Date;import java.util.Locale;import java.util.UUID;@Service //将当前类的对象交给Spring来管理,自动创建对象以及对象的维护public class UserServiceImpl implements IUserService {//调用mapper层方法@Resourceprivate UserMapper userMapper;@Overridepublic void reg(User user) {//通过user参数来获取传递过来的usernameString username = user.getUsername();//调用mapper的findByUsername方法(username)判断用户是否被注册过User result = userMapper.findByUsername(username);//判断结果集是否为nullif(result != null){//抛出异常throw new UsernameDuplicateException("用户名被占用");}//密码加密处理//(串 + password + 串) ------ md5算法加密 连续加载三次//串也叫盐值 盐值为随机的字符串String oldPassword = user.getPassword();//获取盐值(随机生成盐值) 盐值需要记录String salt = UUID.randomUUID().toString().toUpperCase(Locale.ROOT);user.setSalt(salt);//将密码和盐值作为一个整体进行加密处理String md5Password = getMD5Password(oldPassword,salt);//将加密之后的密码重新补全设置到user对象中user.setPassword(md5Password);//补全数据 is_delete 设置成0user.setIsDelete(0);//补全数据 4个日志字段信息user.setCreatedUser(user.getUsername());user.setModifiedUser(user.getUsername());Date date = new Date();user.setCreatedTime(date);user.setModifiedTime(date);//执行注册业务功能的实现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类,在这个类中实现单元测试功能。

package com.wzh.store.service;import com.wzh.store.entity.User;import com.wzh.store.mapper.UserMapper;import com.wzh.store.service.ex.ServiceException;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;import javax.annotation.Resource;@SpringBootTest/*** 1.@RunWith表示启动这个单元测试类,否则这个单元测试类是不能运行的,需要传递* 一个参数,该参数必须是SpringRunner.class即SpringRunner的实例类型* 2.敲完@RunWith(SpringRunner.class)后鼠标分别放在SpringRunner和@RunWith上按alt+enter分别导入包* 3.单元测试类中出现的方法必须是单元测试方法* 4.单元测试方法的特点:      1.必须被@Test注解修饰;*                          2. 返回值类型必须是void;*                          3. 方法的参数列表不指定任何类型;*                          4. 方法的访问修饰符必须是public*/@RunWith(SpringRunner.class)public class UserServiceTests {@Resourceprivate IUserService userService;@Testpublic void reg(){try {User user = new User();user.setUsername("wzh02");user.setPassword("123");userService.reg(user);System.out.println("OK");} catch (ServiceException e) {System.out.println(e.getClass().getSimpleName());System.out.println(e.getMessage());}}}

5. 注册-控制层

5.1创建响应

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

package com.wzh.store.util;import java.io.Serializable;/** Json格式的数据进行响应*/public class JsonResult<E> implements Serializable {//状态码private Integer state;//描述信息private String message;//数据private E data;public JsonResult() {}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;}}

5.2 设计请求

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

请求路径:/user/reg

请求参数:User user

请求类型:POST

响应结果:JsonResult<void>

5.3 处理请求

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

package com.wzh.store.controller;import com.wzh.store.entity.User;import com.wzh.store.service.IUserService;import com.wzh.store.service.ex.InsertException;import com.wzh.store.service.ex.UsernameDuplicateException;import com.wzh.store.util.JsonResult;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController   //@ResponseBody + @Controller@RequestMapping("users")public class UserController {@Resourceprivate IUserService userService;@RequestMapping("reg")public JsonResult<Void> reg(User user){//创建响应结果对象JsonResult<Void> result = new JsonResult<>();try {userService.reg(user);result.setState(200);result.setMessage("注册成功");} catch (UsernameDuplicateException e) {result.setState(4000);result.setMessage("用户名被占用");} catch (InsertException e) {result.setState(5000);result.setMessage("注册时产生未知异常");}return result;}}

5.4 控制层优化设计

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

package com.wzh.store.controller;import com.wzh.store.entity.User;import com.wzh.store.service.ex.InsertException;import com.wzh.store.service.ex.ServiceException;import com.wzh.store.service.ex.UsernameDuplicateException;import com.wzh.store.util.JsonResult;import org.springframework.web.bind.annotation.ExceptionHandler;//控制层类的基类 主要做异常的捕获处理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 UsernameDuplicateException){result.setState(4000);result.setMessage("用户名被占用");}else if(e instanceof InsertException){result.setState(5000);result.setMessage("注册时产生未知错误");}return result;}}

UserController类改动后:

package com.wzh.store.controller;import com.wzh.store.entity.User;import com.wzh.store.service.IUserService;import com.wzh.store.service.ex.InsertException;import com.wzh.store.service.ex.UsernameDuplicateException;import com.wzh.store.util.JsonResult;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController   //@ResponseBody + @Controller@RequestMapping("users")public class UserController extends BaseController{@Resourceprivate IUserService userService;@RequestMapping("reg")public JsonResult<Void> reg(User user){userService.reg(user);return new JsonResult<>(OK);}//    @RequestMapping("reg")//    public JsonResult<Void> reg(User user){//        //创建响应结果对象//        JsonResult<Void> result = new JsonResult<>();//        try {//            userService.reg(user);//            result.setState(200);//            result.setMessage("注册成功");//        } catch (UsernameDuplicateException e) {//            result.setState(4000);//            result.setMessage("用户名被占用");//        } catch (InsertException e) {//            result.setState(5000);//            result.setMessage("注册时产生未知异常");//        }//        return result;//    }}

6. 注册-前端页面

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

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

3. ajax()使用方式: 需要穿第一个方法体作为方法的参数来使用,一堆大括号称之为方法体。语法结构:

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

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

参数

功能描述

url

表示请求的地址,不能包含参数列表部分内容。例如:url:"localhost:8080/users/reg"

type

请求类型(GET,POST类型)例如: type:"POST"

data

向指定的请求url地址提交的数据。例如:data:"username=tom&password=123"

dataType

提交数据的类型。数据一般指定为hson类型。dataType:"json"

success

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

error

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

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

一般放在页脚结束和</body>之间。

<script type="text/javascript">//1. 监听注册按钮是否被点击$("#btn-reg").click(function () {console.log($("#form-reg").serialize());//2. 发送ajax()的异步请求来完成用户的注册功能$.ajax({url: "/users/reg",type: "POST",data: $("#form-reg").serialize(),//dataType: "username=" + username + "&password=" + password,dataType: "JSON",success: function (json){if(json.state == 200){alert("注册成功")}else{alert("注册失败")}},error: function (xhr){alert("注册时产生未知错误" + xhr.status)}});});</script>

电脑商城-02-注册相关推荐

  1. web电商、商城pc端、商城、购物车、订单、线上支付、web商城、pc商城、登录注册、人工客服、收货地址、现金券、优惠券、礼品卡、团购订单、评价晒单、消息通知、电子产品商城、手机商城、电脑商城

    web电商.商城pc端.商城.购物车.订单.线上支付.web商城.pc商城.登录注册.人工客服.收货地址.现金券.优惠券.礼品卡.团购订单.评价晒单.消息通知.电子产品商城.手机商城.电脑商城 Axu ...

  2. 使用SpringBoot编写电脑商城项目笔记(每一步都详细记录,前后端数据交互使用html+ajax+json)

    项目环境 JDK1.8 Maven3.8.3 Tomcat9.0.54 Mysql8.0 技术栈:springboot+mybatis+mysql+html+javascript+css+json+j ...

  3. 基于springboot的外星人电脑商城项目(四)(用户管理)

    外星人电脑商城项目(四) 如果需要源码,点赞+关注+留言备注邮箱,晚上统一发送 外星人商城项目介绍 项目背景 项目功能 项目技术 项目模块 项目要求 外星人商城项目开发流程 第一节 基础构建 第二节 ...

  4. SpringBoot项目电脑商城项目实战(适合刚学完SpringBoot的初学者)

    今天来分享一个SpringBoot项目,该项目是哔哩哔哩袁庭新老师讲的springboot电脑商城项目,里面的东西涉及到很多基础,统一异常处理,统一结果集返回,登录注册,上传文件等. 另外项目里使用的 ...

  5. idea运行jsp显示源码_基于jsp+mysql+Spring+mybatis的SSM在线个人PC电脑商城平台网站系统...

    运行环境: 最好是java jdk 1.8,我们在这个平台上运行的.其他版本理论上也可以.IDE环境: Eclipse,Myeclipse,IDEA都可以tomcat环境: Tomcat 7.x,8. ...

  6. 如何更改计算机性能,如何修改注册表优化电脑性能 修改注册表优化电脑性能方法...

    注册表相信电脑爱好者都不会陌生,通过 修改注册表可以实现优化各种电脑技能 ,在电脑安全设置,系统稳定性方面起着很重要的作用,但由于注册均为表值,因此很多电脑爱好者对于注册表都不赶去触及,害怕因此而影响 ...

  7. html没有注册类,电脑提示没有注册类别的解决方法大全

    电脑提示没有注册类别怎么办?在使用电脑的过程中,我们最常遇到的就是没有注册类别的问题,大多都是在打开软件的时候遇见这种错误提示,那么win7系统提示没有注册类别怎么办呢?下面小编就为大家介绍电脑提示没 ...

  8. 计算机管理器没有注册类别,Win10电脑系统没有注册类别怎么解决

    最近有Win10电脑系统用户反映,打开edge浏览器的时候,出现一个没有注册类别的提示,导致edge浏览器打开失败,这让用户非常烦恼.那么,Win10电脑系统没有注册类别怎么解决呢?接下来,我们就一起 ...

  9. 电脑管家卸载后留下的一个叫 电脑管家-安全注册 的进程,无法关闭。展开的服务是 qmbsrv

    友情链接 解决一切电脑提示在××中已经被打开而删不掉的文件 问题描述如题: 卸载完电脑管家以后会有一些文件还在,想删掉,结果提示不能删,在另一程序已打开 打开任务管理器是这样的 点结束任务一直都结束不 ...

  10. 基于SpringBoot vue的电脑商城平台源码和论文含支付宝沙箱支付

    演示视频: 基于SpringBoot vue的电脑商城平台源码和论文含支付宝沙箱支付演示视频 支付宝沙箱: package com.java.controller;import java.util.* ...

最新文章

  1. C++C#外挂(内存修改)
  2. 商品规格可选怎么设计_商品模块数据库表解析(一)
  3. 小米Redmi 5G旗舰 K30 Pro,最大亮点:怼华为荣耀
  4. 产品必备:注册登录完整解决方案 | 含原型下载
  5. Ansible Playbook企业案例:利用 playbook 安装 nginx、安装和卸载 httpd、安装mysql
  6. 使用pushMeBaby后台测试远程推送
  7. jpa jsf_完整Web应用程序Tomcat JSF Primefaces JPA Hibernate –第2部分
  8. cdn转发防攻击_高防CDN和高防服务器的区别?
  9. ARMA模型的性质之方法性工具
  10. 基础知识(五)对齐变换相关函数
  11. Spring : BeanFactoryPostProcessor 子类 BeanDefinitionRegistryPostProcessor
  12. java编写一个移动物体_java编写一个可以上下移动的小球:运行后,可以通过上下左右键进行移动...
  13. 多线程的那点儿事(之多线程数据结构)
  14. 程序员如何切入区块链去中心化应用开发 1
  15. HTTP 连接管理进化论
  16. 计算机基础 软件系统与硬件系统
  17. html实现手机截屏,iPhone手机如何实现网页长截图?
  18. 8月书讯丨11本新上好书速览(计算机+经管)
  19. 关于unity中使用solidwork模型材质及动画丢失问题
  20. PBR之IBL和球谐的梳理

热门文章

  1. Libre OJ #10064 黑暗城堡(spfa+STL求短路)
  2. 了解arXiv,及arXiv的注册详细操作。
  3. spanning-tree Protocol 简称STP,生成树协议,被广泛部署在二层交换网络中,用于防止网络出现环路,同时增加网络的冗余性
  4. Classic界面chatter中的子选项卡配置
  5. iOS 微信8.0.11更新,新功能,新变化
  6. codelite解决中文乱码问题
  7. zynq 的时钟频率
  8. iOS开发UI基础—09UIImageView动画示例之汤姆猫程序
  9. BH1750FVI光强度传感器及其STM32驱动程序
  10. 玩转亚马逊 AWS IoT(3): SpringBoot 2.7 集成 AWS IoT 服务