欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

springboot模拟天猫整站,分类管理系统后端设计实现(查询)

程序员文章站 2024-03-04 11:26:17
...

11/21
(本文依照how2j思路,个人实现代码,仅供个人学习记录)
今天是做分类管理系统,用的工具是:
最新版IDEA(2020.2)

首先老套路,建立好基础的maven项目之后,在pom文件中设置各种依赖。
值得注意的是:
1.本项目学习的是1.5版本的springboot
2.mysql本人用的是5.1.47,其中在这里有个坑,就是有关时区的坑,后面讲述
3.删除src下的java和resources
4.开干

思路:

首先浏览器*问路径 /admin
2. 这个路径被 AdminPageController 的admin方法匹配,然后客户端跳转到 admin_category_list
3. admin_category_list 被 AdminPageController 的 listCategory 方法匹配,服务端跳转到 admin/listCategory.html
4. listCategory.html 这个html页面通过http协议传输到浏览器端
5. 浏览器根据html 上的js代码,异步调用 categories 这个地址。 CategoryController 获取捕捉到这个请求,到数据库里查出所有的分类数据,并转换为 json数组返回给浏览器。
6. 浏览器根据这个json数组,通过 vue 的v-for 方式把其遍历到 多个 tr 元素上,用户就看到了表格里的多条数据了。
springboot模拟天猫整站,分类管理系统后端设计实现(查询)

编写程序

首先是pom.xml文件,依赖如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
<!--    更换为1.5.9版本的springboot-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.lzf</groupId>
    <artifactId>springboot_tmall</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_tmall</name>
    <description>Demo project for Spring Boot</description>

<!--    设置jdk默认为1.8-->
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
<!--        设置springboot web架构-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<!--        设置提供Tomcat支持-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
<!--        设置热部署,让springboot自动更新-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
<!--        jpa-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
<!--        设置缓存redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
<!--        设置springboot的测试支持-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
<!--        使用thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
<!--        使用elasticsearch-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
<!--        与elasticsearch绑定的jna-->
        <dependency>
            <groupId>com.sun.jna</groupId>
            <artifactId>jna</artifactId>
            <version>3.0.9</version>
        </dependency>
<!--        legacyHTML5支持-->
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
            <version>1.9.22</version>
        </dependency>
<!--        设置junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
<!--        设置Tomcat支持-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <version>8.5.23</version>
        </dependency>
<!--        设置mysql版本-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.6.2</version>
            <scope>test</scope>
        </dependency>
<!--        commons-lang-->
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
<!--        设置shiro依赖,用于加密-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
<!--        hsqldb-->
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

目录如下:
springboot模拟天猫整站,分类管理系统后端设计实现(查询)然后建立java和resources路径

springboot模拟天猫整站,分类管理系统后端设计实现(查询)先创建application.properties配置数据库的链接与各种配置

#database设置数据源
spring.datasource.url=jdbc:mysql://localhost:3306/tmall_springboot?serverTimezone=Asia/Shanghai&allowMultiQueries=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto = none

#thymeleaf配置
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false

#context
server.context-path=/tmall_springboot

#设置上传文件大小,默认只有1 m
spring.http.multipart.maxFileSize=100Mb
spring.http.multipart.maxRequestSize=100Mb

#jpa对实体类的默认字段会把驼峰命名的属性,转换为字段名的时候自动加上下划线。 这个配置的作用就是去掉下划线
#比如属性名称是 createDate, jpa 默认转换为字段名 create_Date。 有了这个配置之后,就会转换为同名字段 createDate
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

#显示 hibernate运行的 sql 语句
spring.jpa.show-sql=true

然后顺便把文件里面前端的东西copy到项目中
现在项目目录是这个样子的:
springboot模拟天猫整站,分类管理系统后端设计实现(查询)

实体类pojo.Category

springboot模拟天猫整站,分类管理系统后端设计实现(查询)

package com.lzf.tmall.pojo;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;

@Entity
@Table(name = "category")
//这里我们做的是前后端的分离,前后端交互所使用的的是json格式
//所以我们在这里把handler和hibernateLazyInitializer这两个无需json化的属性忽略掉
@JsonIgnoreProperties({"handler","hibernateLazyInitializer"})
public class Category {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")

    int id;
    String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

编写dao层

package com.lzf.tmall.dao;

import com.lzf.tmall.pojo.Category;
import org.springframework.data.jpa.repository.JpaRepository;
//直接使用jpa的特性,不用编写分页和CRUD
public interface CategoryDao extends JpaRepository<Category,Integer> {
}

编写service层

package com.lzf.tmall.service;
import java.util.List;
import com.lzf.tmall.dao.CategoryDao;
import com.lzf.tmall.pojo.Category;
//这里sort的导包不要导错
import org.springframework.data.domain.Sort;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


//抛弃了接口+Impl实现类的组合方式,直接使用Service类来作为实现类
@Service
public class CategoryService {
    //自动装配dao层的对象
    @Autowired
    CategoryDao categoryDao;
    //创建sort对象来进行ID的DESC(倒序)然后填充到categoryDao中
    public List<Category> list(){
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return categoryDao.findAll(sort);
    }
}

编写控制器AdminPageController

package com.lzf.tmall.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class AdminPageController {
    //访问admin路径的时候,就会从admin跳转到admin_category_list
    //然后再跳转到admin_category_list
    @GetMapping(value = "/admin")
    public String admin(){
        return "redirect:admin_category_list";
    }
    @GetMapping(value = "/admin_category_list")
    public String listCategory(){
        return "admin/listCategory";
    }
}

因为是做前后端分离,所以数据是通过 RESTFUL接口来取的,而在业务上,除了 RESTFUL 服务要提供,还要提供页面跳转服务,所以所有的后台页面跳转都放在 AdminPageController 这个控制器里。 而RSTFUL 专门放在 Category 对应的控制器 CategoryController.java 里面。

编写控制器CategoryController

package com.lzf.tmall.web;

import com.lzf.tmall.pojo.Category;
import com.lzf.tmall.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class CategoryController {
    @Autowired
    CategoryService categoryService;

    @GetMapping("/categories")
    public List<Category> list() throws Exception{
    // 因为是声明为 @RestController, 所以这个list集合,又会被自动转换为 JSON数组抛给浏览器。 
        return categoryService.list();
    }
}

编写配置类

package com.lzf.tmall.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;


@Configuration
public class CORSConfiguration extends WebMvcConfigurerAdapter {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //令所有的请求都允许跨域
        /*
        因为是二次请求,第一次是获取 html 页面, 
        第二次通过 html 页面上的 js 代码异步获取数据,
        一旦部署到服务器就容易面临跨域请求问题,
        所以允许所有访问都跨域,就不会出现通过 ajax 获取数据获取不到的问题了
         */
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*");
    }
}

编写异常处理类

package com.lzf.tmall.exception;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

@RestController
@ControllerAdvice
public class GloabalExceptionHandler {
    @ExceptionHandler(value = Exception.class)
    public String defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        e.printStackTrace();
        Class constraintViolationException =
                Class.forName("org.hibernate.exception.internal.CacheSQLExceptionConversionDelegate");
        if (null != e.getCause() && constraintViolationException == e.getCause().getClass()) {
            return "违反了外键的约束";
        }
        return e.getMessage();
    }
}

编写启动类,先别急着启动main方法

package com.lzf.tmall;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

}

整个系统的目录现在是这个样子的:
springboot模拟天猫整站,分类管理系统后端设计实现(查询)
先编写测试类,用jdbc来添加十条数据库数据

package com.lzf.tmall.test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
//不要导错包
import java.sql.Statement;

public class TestTmall {
    public static void main(String args[]){
        //准备分类测试数据:

        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        try (
                Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/tmall_springboot?useUnicode=true&characterEncoding=utf8",
                        "root", "admin");
                Statement s = c.createStatement();
        )
        {
            for (int i = 1; i <=10 ; i++) {
                String sqlFormat = "insert into category values (null, '测试分类%d')";
                String sql = String.format(sqlFormat, i);
                s.execute(sql);
            }

            System.out.println("已经成功创建10条分类测试数据");

        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

然后启动测试类:
springboot模拟天猫整站,分类管理系统后端设计实现(查询)
springboot模拟天猫整站,分类管理系统后端设计实现(查询)
可以看出已经导入了十条测试数据。
然后我们再启动启动类
springboot模拟天猫整站,分类管理系统后端设计实现(查询)表示启动成功无报错,打开我们的测试地址:

http://localhost:8080/tmall_springboot/admin

springboot模拟天猫整站,分类管理系统后端设计实现(查询)
显示成功!
该分类系统就已经做完了。
接下来说中间的错误
错误都主要来源于pom文件中的依赖错误,还有数据库的时区设置问题,这方面我也搞不清楚,一会时区出错一会不出错,我的设置是如下的:

spring.datasource.url=jdbc:mysql://localhost:3306/tmall_springboot?serverTimezone=Asia/Shanghai&allowMultiQueries=true&characterEncoding=UTF-8

让他设置为上海的时区就可以了!
这个子系统的主要难点在于controller层的理解和config层的配置。

相关标签: springboot