SpringBoot项目实战笔记:电脑商城项目实战(SpringBoot+MyBatis+MySQL)

这篇具有很好参考价值的文章主要介绍了SpringBoot项目实战笔记:电脑商城项目实战(SpringBoot+MyBatis+MySQL)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

花了一段实现刚学完SpringBoot,做个项目练练手。教程视频来源于B站。
视频链接: 【SpringBoot项目实战完整版】SpringBoot+MyBatis+MySQL电脑商城项目实战_哔哩哔哩_bilibili

目录

一、系统概述与环境搭建

1. 系统开发及运行环境

2.项目分析

3.创建项目

4.配置并运行项目

4.1 运行项目

4.2 配置项目

4.3 其他配置

三、用户登录注册

3.1 用户注册

3.1.1  用户-创建数据表

3.1.2 用户-创建实体类

3.1.3用户-注册-持久层

3.1.4用户-注册-业务层

                1.1 业务的定位

                1.2 规划异常

                1.3 接口和抽象方法

                1.4 实现接口方法


一、系统概述与环境搭建

1. 系统开发及运行环境

       电脑商城系统开发所需的环境及相关软件进行介绍。
        1.操作系统: Windows 10
        2.Java开发包: JDK 8
        3.项目管理工具: Maven 3.6.3
        4.项目开发工具:IntelliJ IDEA 2022.2.2 x64
        5.数据库:MySQL  MariaDB-10.3.7-winx64
        6.浏览器: Google Chrome
        7.服务器架构:Spring Boot 2.7.5 + MyBatis 2.2.2 + AJAX2

2.项目分析

        1.在开发某个项目之前,应先分析这个项目中可能涉及哪些种类的数据。本项目中涉及的数据:用户、商品、商品类别、收藏、订单、购物车、收货地址。

        2.关于数据,还应该要确定这些数据的开发顺序。设计开发顺序的原则是:先开发基础、简单或熟悉的数据。以上需要处理的数据的开发流程是:用户-收货地址-商品类别-商品-收藏-购物车-订单。

        3.在开发每种数据的相关功能时,先分析该数据涉及哪些功能。在本项目中以用户数据为例,需要开发的功能有:登录、注册、修改密码、修改资料、上传头像

        4.然后,在确定这些功能的开发顺序。原则上,应先做基础功能,并遵循增查删改的顺序来开发。则用户相关功能的开发顺序应该是:注册-登录-修改密码-修改个人资料-上传头像。

        5.在实际开发中,应先创建该项目的数据库,当每次处理一种新的数据时,应先创建该数据在数据库中的数据表,然后在项目中创建该数据表对应的实体类。

        6.在开发某个具体的功能时,应遵循开发顺序:持久层-业务层-控制器-前端页面。

3.创建项目

       1.给项目添加Web->Spring Web、SQL->MyBatis Framework、SQL->MySQL Driver的依赖。点击【Next】按钮完成项目创建。

springboot电脑商城项目,SpringBoot,Mybatis,spring boot,mybatis,mysqlspringboot电脑商城项目,SpringBoot,Mybatis,spring boot,mybatis,mysqlspringboot电脑商城项目,SpringBoot,Mybatis,spring boot,mybatis,mysqlspringboot电脑商城项目,SpringBoot,Mybatis,spring boot,mybatis,mysql

        2.Maven配置

        其中在maven的配置上,点击File->Setting->搜索maven->如下配置。 

       但在User settings file 配置不大对,但能项目能正常启动(不知道为什么,后面需要再说),因为我在G:\Maven\apache-maven-3.6.3-bin\目录下没看到/conf目录,可能IDEA自动给我默认选了C盘下的目录了吧

springboot电脑商城项目,SpringBoot,Mybatis,spring boot,mybatis,mysql

        3.首次创建完Spring Initializr项目时,解析项目依赖需消耗一定时间(Resolving dependencies of store...)

springboot电脑商城项目,SpringBoot,Mybatis,spring boot,mybatis,mysql

4.配置并运行项目

4.1 运行项目

        首先先保证Springboot项目能够启动起来,找到程序的入口,即被@SpringBootApplication注解修饰的入口启动类,运行入口启动类,如果观察到图形化的界面,即项目成功启动。

```java
package com.cy.store;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class StoreApplication {
    public static void main(String[] args) {
        SpringApplication.run(StoreApplication.class, args);
    }
}

springboot电脑商城项目,SpringBoot,Mybatis,spring boot,mybatis,mysql

4.2 配置项目

        检查数据库是否成功连接,在/test包中写个测试代码:

@SpringBootTest
class StoreApplicationTests {
    @Autowired  //自动注入/自动装配
    private DataSource dataSource;

    @Test
    void contextLoads() {
    }

    @Test
    void getConnection() throws SQLException {
        System.out.println(dataSource.getConnection());
    }

}

        如果启动项目时提示:“配置数据源失败:'url'属性未指定,无法配置内嵌的数据源”。有如下的错误提示。

springboot电脑商城项目,SpringBoot,Mybatis,spring boot,mybatis,mysql

        解决以上操作提示的方法:在resources文件夹下的application.properties文件中添加数据源的配置。

        配置数据源,数据库信息。这一步建议在创建项目完后立马检查配置。步骤:按照上面测试代码的方式获取数据源连接观察是否能成功连接。

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

4.3 其他配置

        1.为了方便查询JSON数据,隐藏没有值的属性,减少流量消耗,服务器不应该向客户端响应为null的属性。解决方式有两种:

        方式一:在属性或类之前添加@JsonInclude(value=Include.NON_NULL)

        方式二:可以在application.propertise配置文件中添加全局配置:

# 服务器向客户端不响应为null的属性
spring.jackson.default-property-inclusion=NON_NULL

        2.SpringBoot项目的默认访问路径是“/”,如果需要修改的话可以在配置文件中指定SpringBoot访问项目路径的项目名。但是不建议修改

server.servlet.context-path=/store

三、用户登录注册

3.1 用户注册

3.1.1  用户-创建数据表

        创建store数据库,创建t_user用户数据表。

        1.使用use命令先选中store数据库:use store;

        2.在store数据库中创建t_user表。(直接复制到Navicat中,点击查询,执行脚本)

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;

3.1.2 用户-创建实体类

1.项目中许多实体类都会有日志相关的四个属性,所以在创建实体类之前,应先创建这些实体类的基dsdi 类,将4个日志属性声明在基类中。在com.cy.store.entity包下创建BaseEntity,作为实体类的基类。

package com.cy.store.entity;
import java.io.Serializable;
import java.util.Date;
/** 实体类的基类 */
public class BaseEntity implements Serializable {
private String createdUser;
private Date createdTime;
private String modifiedUser;
private Date modifiedTime;
// Generate: Getter and Setter、toString()
}

因为这个基类的作用就是用于被其他实体类继承的,所以应声明为抽象类。

为什么要继承sealization接口?因为要在网络中以流的形式传输,所以需要serialize序列化

2.创建com.cy.store.entity.User用户数据的实体类,继承自BaseEntity类,在中声明相关属性。

package com.cy.store.entity;
import java.io.Serializable;
import java.util.Objects;
/** 用户数据的实体类 */
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;
// Generate: Getter and Setter、Generate hashCode() and equals()、toString()
}

Tips:实体类可使用lombok插件,类上声明几个注解@Data @AllArgConsturctor等注解表示自动生成get/set方法,以及有参和无参构造函数。

3.1.3用户-注册-持久层

(1)准备工作

        1.在src/test/java下的com.store.StoreApplicationTest测试类中编写并执行获取数据库连接的单元测试,以检查数据库连接的配置是否正确。参加上面环境配置的数据源的代码。

        2.执行src/test/java下的com.cy.storeApplicationTests测试类中的contextLoad观察是否执行成功。

(2)规划需要执行的SQL语句

        1.用户注册的本质就是向用户表中插入数据,需要执行的SQL语句大致是:

insert into t_user(除uid之外的字段列表) values(匹配的值列表)

        2.由于数据库表中的用户名字段被设计为UNIQUE,在执行插入数据之前,还应该检查该用户名是否被注册,因此需要有“根据用户名查询用户数据”的功能。需要执行的SQL语句大致是:

select * from t_user where username = ? 

(3)接口与抽象方法

        1.在com.cy.store包下创建一个mapper包,接着创建com.cy.store.mapper.UserMapper接口,并在接口中添加抽象方法。

/** 处理用户数据操作的持久层接口 */
public interface UserMapper {
/**
* 插入用户数据
* @param user 用户数据
* @return 受影响的行数
*/
Integer insert(User user);
/**
* 根据用户名查询用户数据
* @param username 用户名
* @return 匹配的用户数据,如果没有匹配的数据,则返回null
*/
User findByUsername(String username);
}

        2.由于这是项目中第一次创建持久层接口,还应在StoreApplication启动类之前添加@MapperScan("com.cy.store.mapper")注解,表示在项目一启动自动扫描这个包下的mapper接口。因为SpringBoot一开始不知道mapper接口放在哪,你得在项目启动入口告诉它在那个地方,通过注解的方式配置包扫描路径。

@SpringBootApplication
@MapperScan("com.cy.store.mapper")
public class StoreApplication {
public static void main(String[] args) {
SpringApplication.run(StoreApplication.class, args);
}
}

Mybats与Spring整合后需要实现实体类和数据表的映射关系。实现实体类和数据表的映射关系可以在Mapper接口添加@Mapper注解。但建议以后直接在SpringBoot启动类中加@MapperScan("mapper包")注解,这样比较方便,不需要对每个Mapper都添加@Mapper注解。

复习一下:一个数据表对应一个实体类,每个实体类都有一个Mapper接口,每个Mapper自动生成一个Mapper实现类,每个Mapper接口对应一个Mapper配置文件。

eg: t_user -->  User  --> UserMapper.java  --> UserMapper.xml 

(4)配置SQL映射

        1.在src/main/resource下创建mapper文件夹,并在文件夹下创建UserMapper.xml配置文件,进行以上两个抽象方法的映射配置。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cy.store.Mapper.UserMapper">

    <!--实体类属性和数据库表字段创建映射关系,映射的属性:把有下划线改成驼峰的
        映射关系用于查询语句select,增删改不需要
    -->
    <resultMap id="userEntityMap" type="com.cy.store.Entity.User">
        <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>

    <!--插入语句  使用主键自增userGenerateKeys  keyProperty-->
    <!-- 插入用户数据:Integer insert(User user) -->
    <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>

    <!-- 根据用户名查询用户数据:User findByUsername(String username) -->
    <select id="findByUsername" resultMap="userEntityMap">
        select * from t_user where username = #{username}
    </select>


</mapper>

几点说明:

1.插入/删除/修改语句会有返回值(int),返回受影响的行数;

2.实体类属性和表字段创建映射关系,映射方式:字段下划线变为属性驼峰形式。自己手动改吧,字段复制过来自己去掉下划线改成驼峰命名

3.插入标签里往往需要主键自增,开启主键自增的几个核心属性: userGeneratedKeys   keyProperty

        userGeneratedKeys:表示开启的某个属性的字段递增,值为true

        keyProperty:将表中的哪个属性自增

4.映射关系仅仅出现在select语句中,需要使用到reseltMap属性,来建立属性和字段的映射。也可以使用resultType,但必须实体类实行和表字段属性完全一致;增删改语句不存在属性字段映射的,因为看语句就知道了。

5.resultMap标签里的几个属性:

        id表示唯一标识,select标签需要指定resultMap属性为这个id;

        type标识映射那个实体类的全类名。在<result>标签中指定字段column和属性property的映射。字段名属性名一致的就不用指定映射了,长的一样的Mybatis可以自动映射成功。

        注意:主键一定得指定映射,无论字段名和属性名是否一致。<id>标签里

6.#{}和¥{}的区别 ?

程序执行流程分析

    比如执行insertUser(User user)方法,业务层调用insertUser(User user),业务层里的userMapper已经自动注入了,然后业务层调用持久层的userMapper接口的insertUser(User user)方法,因为userMapper配置文件有个SQL语句的id=“insertUser”(方法名),因此执行这个SQL,把方法里的参数user对象里的所有属性注入到<select>里面来了(有用没用都进来了),因为SQL语句会用到对象中的某些属性呀(比如username password等等其他的),接下来就可以顺利执行SQL语句了,数据库成功执行,插入一条记录后,返回受影响的行数1给这个接口方法int insertUser(User user)。

2.由于这是项目中第一次使用SQL映射(配置文件中SQL语句和Mapper中的抽象方法映射),所哟需要在application.properties中添加mybatis.mapper-locations属性的配置,来指定XML的位置,告诉SpringBoot配置文件在哪个目录下,它方便和mapper接口抽象方法映射上。

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

前面顺便提了一下啊,使用@MapperScan告诉SpringBoot把mapper接口都放在com.cy.store.mapper接口下,项目自动给给mapper下的接口当作mapper接口。然后SpringBoot知道了配置文件的的目录,再通过配置文件里的命名空间就实现了mapper接口和xml配置文件文件的映射了。

3.完成后及时执行单元测试,检查以上开发的功能是否正确运行。在src/test/java下创建com.cy.store.mapper.UserMapperTest单元测试类。在测试类的声明之前添加@RunWith(SpringRunner)@SpringBootTest注解,并在测试类中声明持久化对象,通过自动装配注入值。

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.util.Date;


@RunWith(SpringRunner.class)   //注解是一个测试启动器,可以加载SpringBoot测试注解
@SpringBootTest
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
}

4.如果在第四步自动装配userMapper时,报“Could not autowire. No beans of 'UserMapper' type

found” 错,无法进行自动装配。解决方案是,将 Autowiring for bean class 选项下的 Severity 设置为
Warning即可。
(出现这个错误的原因:@Mapper 注解是  Mybatis 提供的,而 @Autowried 注解是 Spring 提供的,IDEA能理解 Spring 的上下文,但是不能理解Mybatis。
springboot电脑商城项目,SpringBoot,Mybatis,spring boot,mybatis,mysql

 5.然后编写两个测试方法,对以上完成的两个功能进行单元测试。

单元测试必须为public修饰,方法的返回值必须是void,方法不能有参数列表,并且方法被@Test注解修饰。

@Test
public void insertUser(){
        User user = new User();
        user.setUsername("user01");
        user.setPassword("1328478917");
        Integer row = userMapper.insert(user);
        System.out.println(row);
    }

@Test
public void findUserByUsername(){
        String username ="user01";
        User result = userMapper.findByUsername(username);
        System.out.println(result);
    }

如果出现org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)异常,可能原因:

1.在resources文件检查下创建的mapper文件夹类型没有正确选择(eclipse选择Folder,IDEA选择Directory)

2.映射文件的mapper标签的namespace属性没有正确映射到dao层接口,或者application.properties中的属性mybatis.mapper-locations没有正确配置xml映射文件。。

3.1.4用户-注册-业务层

1.1 业务的定位

1. 业务:一套完整的数据处理过程,通常表现为用户认为的一个功能,但是在开发时对应多项数据操作。在项目中,通过业务控制每个“ 功能 (例如注册、登录等)的处理流程和相关逻辑。
2. 流程:先做什么,再做什么。例如:注册时,需要先判断用户名是否被占用,再决定是否完成注册。
3. 逻辑:能干什么,不能干什么。例如:注册时,如果用户名被占用,则不允许注册;反之,则允许注 册。
4. 业务的主要作用是保障数据安全和数据的完整性、有效性。

1.2 规划异常

(一)关于异常

1.列举至少十种异常:

Throwable
        Error
                OutOfMemoryError(OOM)
        Exception
                SQLException
                IOException
                        FileNotFoundException
        RuntimeException
                NullPointerException
                ArithmeticException
                ClassCastException
                IndexOutOfBoundsException
                        ArrayIndexOutOfBoundsException
                        StringIndexOutOfBoundsException

2.异常的处理方法和处理原则:

        异常的处理方式有:
                捕获处理(try...catch...finally)
                声明抛出(throw/throws)
        如果当前方法适合处理,则捕获处理;如果当前方法不适合处理,则声明抛出。

(二)异常规划

1.为了便于统一管理自定义异常,应先创建com.cy.store.service.ex.ServiceException自定义异常的基类异常,继承自RuntimeException,并从父类生成子类的五个构造方法。

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

2.当用户进行注册时,可能会因为用户名的占用导致无法正常注册,此时需要抛出用户名被占用的异常,因此可以设计一个用户名重复的com.cy.store.service.ex.UsernameDuplicateException异常类,继承自ServiceException类,并从父类生成子类的五个构造方法。

package com.cy.store.service.ex;

public class UsernameDuplicatedException extends ServiceException{
    ... 
}

3.在用户进行注册时,会执行数据库的INSERT操作,该操作也有可能失败的,则创建com.cy.store.service.ex.InsertException异常类,继承自ServiceException类,并从父类生成子类的5个构造方法。

/*注册插入操作出现异常*/
public class InsertException extends ServiceException{
    ...
}

4.所有的自定义异常,都应是RuntimeException的子孙类异常。项目中目前异常的继承结构如下。

RuntimeException
        -- ServiceException
                -- UsernameDuplicateException
                -- InsertException

1.3 接口和抽象方法

1.先创建com.cy,store,service.IUserService业务层接口,并在接口中添加抽象方法。

public interface IUserService {
    /**
     * 用户注册
     * @param user
     */
    public void reg(User user);
}

2.创建业务层接口的目的就是为了解耦。关于业务层的抽象方法的设计原则。

1.仅以操作成功为前提来设计返回值类型,不考虑操作失败的情况;
2.方法名称可以自定义,通常与用户操作的功能相关;
3.方法的参数列表根据执行的具体业务功能来确定,需要哪些数据就设计哪些数据。通常情况下,参数需要足
以调用持久层对应的相关功能;同时还要满足参数是客户端可以传递给控制器的;
4.方法中使用抛出异常的方式来表示操作失败。

1.4 实现接口方法

1.创建com.cy.store.service.impl.UserServiceImpl业务层实现类,并实现IUserService接口。在类之前添加@Service注解,并在类中添加持久层UserMapper对象。

public class IUserServiceImpl implements IUserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public void reg(User user) {
      
        }

    }

2.UserServiceImpl类需要重写IUserService接口中的抽象方法

    @Override
    public void reg(User user) {
        //根据参数user对象获取注册的用户名
        String username = user.getUsername();
        //调用持久层的User findByUsername(String username)方法,根据用户名查询用户数据
        User result = userMapper.findByUsername(username);
        //判断查询结果是否不为null
        if(result !=null){
            //是,表示用户名已被占用,则抛出UsernameDuplicateException异常
            throw new UsernameDuplicatedException("尝试注册的用户名["+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);

        //判断受影响的行数是否不为1
        if (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.完成后再src/test/java下创建com.cy.store.service.UserServiceTests测试类,编写并执行用户注册业务层的单元测试。

@RunWith(SpringRunner.class)   
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private IUserService iUserService;

    @Test
    public void reg(){
        try{
            User user = new User();
            user.setUsername("1ower");
            user.setPassword("123456");
            user.setGender(1);
            user.setPhone("13953948109");
            user.setEmail("136@qq.com");
            user.setAvatar("xxxx");
            iUserService.reg(user);
            System.out.println("注册成功!!");
        }catch (ServiceException e){
            System.out.println("注册失败!"+e.getClass().getSimpleName());
            System.out.println(e.getMessage());
        }

    }

3.1.5 用户-注册-控制层

5.1 创建响应结果类

创建com.cy.store.util.jsonResult响应结果类型

结果响应信息(JsonResult):就是控制层需要返回给前端页面所封装的数据类型,自定义的

应包含的内容:状态码state,状态描述信息message,具体数据data

@NoArgsConstructor
@Data
public class JsonResult<E> implements Serializable {
    /* 状态码 */
    private Integer state;
    /* 状态描述信息 */
    private String message;
    /* 数据 */
    private E data;

    public JsonResult(Integer state) {
        super();
        this.state = state;
    }

    public JsonResult(Integer state, E data) {
        super();
        this.state = state;
        this.data = data;
    }

    /* 出现异常时调用*/
    public JsonResult(Throwable e){
        super();
        //获取异常对象中的异常信息
        this.message = e.getMessage();
    }


}

5.2 设计请求

        设计用户提交的请求,并设计响应的方式:

请求路径:/user/reg

请求参数:User user

请求参数:POST

响应结果:JsonResult<Void>

Alt + 鼠标左键 选中多行

5.3处理请求

        1.创建com.cy.store.controller.UserController控制器类,在类的声明之前添加@RestController和@RequestMapping("users")注解,在类中添加IUserService业务对象并使用@Autowired注解修饰。(之所以继承BaseControl后面再解释)

@RestController
@RequestMapping("users")
public class UserController extends BaseController {
    @Autowired
    private IUserService userService;
}

        2.然后在类中添加处理请求的用户注册方法。

        

  @RequestMapping("reg")
    public JsonResult<Void> reg(User user){

//        JsonResult<Void> result = new JsonResult<Void>();
//        try{
//            //调用业务对象执行注册
//            userService.reg(user);
//            //响应成功
//            result.setState(200);
//        }catch (UsernameDuplicatedException e){
//            //用户名被占用
//            result.setState(40000);
//            result.setMessage("用户名已经被占用!!!");
//        }catch (InsertException e){
//            //插入数据异常
//            result.setState(5000);
//            result.setMessage("注册失败,请联系管理员!");
//        }
//        return result;

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

        3.完成后启动项目,打开浏览器访问进行测试

        http://localhost:8080/users/reg?username=controller&password=123456

        返回的应该是一个JsonResult数据

        {

                state : 200 ,
                message : null ,
                data : null
        }

5.4控制器层的调整

1. 然后创建提供控制器类的基类 com.cy.store.controller.BaseController ,在其中定义表示响应成功的状态码及统一处理异常的方法。
@ExceptionHandler 注解用于统一处理方法抛出的异常。当我们使用这个注解时,需要定义一个 异常的处理方法,再给这个方法加上@ExceptionHandler 注解,这个方法就会处理类中其他方法 (被@RequestMapping 注解)抛出的异常。 @ExceptionHandler 注解中可以添加参数,参数是某 个异常类的class ,代表这个方法专门处理该类异常。
public class BaseController {
    /**操作成功的状态码**/
    public static final int OK = 200;

    /** @ExceptionHandle用于处理统一处理方法的异常 **/
    @ExceptionHandler(ServiceException.class)
    public JsonResult<Void> handleException(Throwable e){
        JsonResult<Void> result = new JsonResult<Void>(e);
        if (e instanceof UsernameDuplicatedException) {
            result.setState(4000);
        }  else if (e instanceof InsertException) {
            result.setState(5000);
        } 

        return result;
    }
2.最后简化UserControl控制器类中的用户注册reg()方法的代码。
/** 处理用户相关请求的控制器类 */
@RestController
@RequestMapping("users")
public class UserController extends BaseController {
    @Autowired
    private IUserService userService;
    
    @RequestMapping("reg")
    public JsonResult<Void> reg(User user) {
    // 调用业务对象执行注册
    userService.reg(user);
    // 返回
    return new JsonResult<Void>(OK);
    }
}

3.完成后启动项目,打开浏览器访问请求进行测试。

        http://localhost:8080/users/reg?username=controller&password=123456

3.1.6用户-注册 前端页面

1. 将电脑商城前端资源页面 pages 文件夹下的静态资源: bootstrap3 css images js web
index.html 相关的资源复制到项目 src/main/resources/static 文件夹下。如图所示。
2. register.html 页面中 body 标签内部的最后,添加 script 标签用于编写 JavaScript 程序。请求的 url 中需要添加项目的访问名称。

3.完成后启动项目,打开浏览器访问http://localhost:8080/web/register.html页面并进行注册。 文章来源地址https://www.toymoban.com/news/detail-525720.html

到了这里,关于SpringBoot项目实战笔记:电脑商城项目实战(SpringBoot+MyBatis+MySQL)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于springboot框架的电脑商城项目(二)

    当用户输入用户名和密码将数据提交给后台数据库进行查询,如果存在对应的用户名和密码则表示登录成功,登录成功之后跳转到系统的主页就是index.html页面,跳转在前端使用jquery来完成。 1.规划sql语句 依据用户提交的用户名和密码做select查询。 2.设计接口和抽象方法 在

    2024年02月05日
    浏览(43)
  • 基于springboot框架的电脑商城项目(六)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 1.规划sql 在删除之前判断该数据是否存在,需要执行查询语句看能否查到该数据,还需要根据返回的aid获取uid并和session中的uid进行比较判断归属是否正确,这一条SQL语句在设置收货地址时

    2024年02月03日
    浏览(51)
  • 基于springboot框架的电脑商城项目(九)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 1.规划sql 用户在购物车列表页中通过随机勾选相关的商品,在点击\\\"结算\\\"按钮后跳转到\\\"确认订单页\\\",在这个页面中需要展示用户在上个页面所勾选的\\\"购物车列表页\\\"中对应的数据.且展示

    2024年02月05日
    浏览(41)
  • 基于springboot框架的电脑商城项目(七)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 1.规划sql 根据商品id显示商品详情的SQL语句 2.设计接口和抽象方法 在ProductMapper接口中添加抽象方法 在ProductMapper.xml文件中配置findById(Integer id)方法的映射 2.规划异常 如果商品数据不存

    2024年02月05日
    浏览(47)
  • 基于springboot框架的电脑商城项目(四)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 在store数据库中创建t_address表 在entity包下创建实体类Address继承baseEntity类 1.规划sql 1.新增收货地址对应的是插入语句: 2.大部分平台都会规定一个用户的收货地址数量,这里规定最多20个

    2024年02月03日
    浏览(42)
  • 基于springboot框架的电脑商城项目(十)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 在store数据库中创建t_order和t_order_item数据表 在entity包下创建Order实体类并继承BaseEntity类 在com.cy.store.entity包下创建OrderItem实体类并继承BaseEntity类 1.规划sql 插入订单数据的SQL语句 插入

    2024年02月06日
    浏览(39)
  • 基于springboot框架的电脑商城项目(八)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 1.规划sql 这里需要将商品表和购物车表进行连表查询 2.设计接口和抽象方法 在store包下创建一个vo包,在该包下面创建CartVO类,不需要继承BaseController类,那相应的就需要单独实现Serializa

    2024年02月05日
    浏览(44)
  • 基于springboot框架的电脑商城项目(五)

    🎁🎁静态资源及sql文件分享 链接:https://pan.baidu.com/s/1X-yjmQcPD3PqS21x0HplNA?pwd=23gr 提取码:23gr 1.规划需要执行的SQL语句 其中order by is_default DESC是为了让默认收货地址展示在最上面,order by可以有多个子句,中间用逗号隔开,后面加的create_time DESC是为了让非默认收货地址创建的越晚

    2024年02月03日
    浏览(41)
  • SpringBoot项目--电脑商城【加入购物车】

    1.使用use命令先选中store数据库 2.在store数据库中创建t_cart用户数据表 在entity包下创建购物车的Cart实体类并使其继承BaseEntity 1.向购物车表中插入商品数据的SQL语句 2.如果当前商品已经在购物车存在,则直接更新商品即可 3.在插入或者更新具体执行哪个语句,取决于数据库中是否

    2024年02月09日
    浏览(63)
  • 【五一创作】基于springboot框架的电脑商城项目(三)

    1.规划sql 根据用户id修改信息的SQL语句 根据用户id查询的sql语句 2.接口与抽象方法 更新用户的信息方法的定义 在UserMapper.xml文件中进行映射编写 设计两个功能: 1.当打开页面时显示当前登录的用户的信息 2.点击修改按钮时更新用户的信息 1.异常规划 点击个人资料页面时可能找

    2024年02月04日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包