# store
**Repository Path**: juntom/store
## Basic Information
- **Project Name**: store
- **Description**: 这是一个跟练项目,视频地址链接:https://www.bilibili.com/video/BV1bf4y1V7Bx/?spm_id_from=333.999.0.0
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2022-11-01
- **Last Updated**: 2023-05-09
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Store商城(14天搞定)
2022.11.1~2022.11.14
## 某一模块的开发
1. 持久层开发:依据前端页面的设置规划相关的SQL语句了,以及进行配置
2. 业务层开发:核心功能控制、业务操作以及异常的处理
3. 控制层开发:接收请求、处理响应
4. 前端开发:JS、Query、AJAX这些技术来连接后台
## 搭建项目
1.jdk 1.8
2.maven:配置到3.61
3.数据库:MariaDB、Mysql,5.1及以上
4.项目名称:store,商城
5.结构:com.cy.store
6.资源:resources文件夹(static、templates)
7.单元测试:test.com.cy.store
这里用老师的是错误的,改为自己的
```xml
spring.datasource.url=jdbc:mysql://localhost:3306/store?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=123456
```
8.访问项目的静态资源是否可以正常的加载
## (1)用户注册
通过MyBatis来操作数据库,在做mybatis开发的流程。
### 注册-持久层
#### 1.规划需要执行的SQL语句
1.用户的注册功能,相当于在做数据的插入操作
```sql
insert into t_user (username,password) value(值列表)
```
2.在用户的注册时首先要查询当前的用户名是否存在,如果存在则不能进行注册。相当于是一条查询语句。(创建一个UserMapper的接口。要在接口中定义这两个SQL语句抽象方法。
```sql
select * from t_user where username=?
```
(一定是先规划语句,然后再想代码怎么写)
#### 2.设计接口和抽象方法
定义Mapper接口,在项目的目录结构下首先创建一个mapper包,在这个包下在再根据不同的功能模块来创建mapper接口,创建一个UserMapper的接口。
```java
package com.cy.store.mapper;
import com.cy.store.entiy.User;
/**
*用户模块的持久层接口
*/
//@Mapper这种写法不建议使用,一个项目当中会有很多个mapper接口,很麻烦,所有我们采用在启动类里添加Mapper的路径,让SpringBoot知道你的mapper在哪
public interface UserMapper {
/**
* 插入用户的数据
* @param user 用户的数据
* @return 受影响的行数(增、删、改,都受影响的行数作为返回值,可根据返回值来判断是否执行成功
*/
//插入的操作,建议用Integer作为返回值,影响的行数来判断是否存在,注:这里字段太多,建议生成对象的形式,即User用户对象
Integer insert(User user);
/**
* 根据用户名来查询用户的数据
* @param username 用户名
* @return 如果找到对应的用户则返回这个用户的数据,如果没有找到则返回NULL值
*/
User findByUsername(String username);
}
```
#### 3.编写映射
1.定义xml映射文件,与对应的接口进行关联。所有的映射文件需要防止resource目录下,在这个目录下创建一个mapper文件夹,然后在这个文件夹下存放Mapper的映射文件。
2.创建一个接口对应的映射文件,遵循和接口的名称保持一致即可。创建一个UserMapper.xml文件。
```xml
```
3.配置接口中的方法对应上的SQL语句上,需要借助标签来完成,insert\update\delete\select,对应的是SQL语句的增删改查操作。
4.单元测试:每个独立的层编写完毕后需要编写单元测试,来测试当前的功能,在test包结构下创建一个mapper包,在这个包下在创建持久层的功能测试
5.在测试的过程中发现有一个错误一直出现, 最后发现在实体类的基类中,createdUser我写成了createUser,少了一个d就导致后面一直找不到createdUser在User实体类中。
### 注册-业务层
#### 规划异常
1. RuntimeException异常,作为异常的子类,然后再去定义具体的异常类型来继承这个异常。业务层异常的基类,ServeiceException异常。这个异常继承RuntimeException异常,异常机制的建立。
```java
package com.cy.store.service.ex;
/*
* @Author: jun
* @Date:2022/11/1 14:23
* @概述:
*/
/**
* 业务层异常的基类:throws new ServiceException("业务层产生未知的异常")
*/
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. 用户在进行注册时可能会产生用户名被占用的错误,抛出一个异常:
用户名被占用:UsernameDuplitedException异常。
```java
package com.cy.store.service.ex;
/*
* @Author: jun
* @Date:2022/11/1 15:32
* @概述:
*/
/**用户名被占用异常**/
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);
}
}
```
3. 正在执行数据插入操作的时候,服务器、数据库宕机。处于正在执行插入的过程中所产生的异常
```java
package com.cy.store.service.ex;
/*
* @Author: jun
* @Date:2022/11/1 15:35
* @概述:
*/
/**
* 数据在插入的过程中所产生的异常
*/
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);
}
}
```
#### 设计接口和抽象方法
在service包下创建了一个UserService接口
```Java
package com.cy.store.service;
import com.cy.store.entity.User;
/**
* 用户模块业务层接口
*/
public interface IUserService {
/**
* 用户注册方法
* @param user 用户的额数据对象
*/
void reg(User user);
}
```
创建一个实现类UserServicempl类,需要实现这个接口,并且实现抽象方法
然后在单元测试
### 注册-控制层
#### 创建响应
状态码、状态描述信息、数据。这部分功能封装到一个类中,将这类作为方法放回值,返回给前端浏览器。
```java
package com.cy.store.util;
import java.io.Serializable;
/*
* @Author: jun
* @Date:2022/11/2 10:08
* @概述:
*/
/**
* Json格式的数据进行响应
* @param
*/
public class JsonResult implements Serializable {
/**
* 状态码
*/
private Integer state;
/**
* 描述信息
*/
private String message;
/**
* 数据,不知道类型就泛型描述
*/
private E date;
public JsonResult() {
}
//捕获异常
public JsonResult(Throwable e) {
this.message = e.getMessage();
}
public JsonResult(Integer state, E date) {
this.state = state;
this.date = date;
}
//再将get和set方法声明出来
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 getDate() {
return date;
}
public void setDate(E date) {
this.date = date;
}
}
```
#### 设计请求
依据当前的业务功能模块进行请求的设计
请求路径:/users/reg
请求参数:User user
请求类型:POST
响应结果:JsonResult
#### 处理请求
1.创建一个控制层对应的类UserController类。依赖于业务层的接口。
```java
package com.cy.store.controller;
import com.cy.store.entity.User;
import com.cy.store.service.IUserService;
import com.cy.store.service.ex.InsertException;
import com.cy.store.service.ex.UsernameDuplicatedException;
import com.cy.store.util.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/*
* @Author: jun
* @Date:2022/11/2 10:47
* @概述:
*/
//@Controller
@RestController //这个注解的功能等效于@Controller+@ResponseBody
@RequestMapping("users")
public class UserController {
@Autowired
private IUserService userService;
@RequestMapping("reg")
// @ResponseBody //表示此方法的响应结果以json格式进行数据的响应给到前端,比较麻烦
public JsonResult