springboot+vue music website combat project


foreword

Front-end use: vue/cli "^4.5.15" Back-end use: springboot2.6.2, mybatis-plus3.5.9, mybatis-plus-generator3.5.1 Deployment: nginx, tomcat, webpack Summary. Although the project is fancy, it is not difficult . The most rewarding are: 1. Technology selection, task requirements. Once determined, later changes are costly. 2. Pay attention to backup 3. Database form design 4. Bug MVVM架构solutions Remember to first perform data validation on the front end.流水线式创建实体并实现业务逻辑domain/pojo/bean → dao/mapper → mapper.xml → service → serviceimpl → controller

==Thanks to senior Wang Hanyuan and the people who helped me in the development of station B. Due to copyright reasons, the open source project does not publish any songs == Due to the wrong selection at that time, there was no development around the api. This resulted in the songs being my own one by one Uploaded....so technical selection is the biggest pit I stepped on.

1. Achievement display

前台大概总览 insert image description here 后台大概总览 insert image description here

2. Back-end process

2.1 Database table design

In this single-user project, you basically have a java development manual in your hand and abide by the stipulations.单用户项目开发基本通用样例,但仍然应当考虑自己项目的实际需求 insert image description here

2.2. Back-end construction

2.2.1 mybatis-plus reverse engineering generates code to simplify development

In order to facilitate development, we should first establish a database. Then use the reverse engineering of mybatis-plus, the code generator! 这里不建议使用 lombok 省略 实体的构造器和get,set方法.(我曾看到过这样一句话,如果java内部到处充斥着这种像lmobok可以修改源代码的插件,那么就如同无根浮萍,没有自己的核心竞争力,java迟早被取代!)But we can't deny that it is also very convenient. I usually use lombok mainly for his @slf4j log.

这种方式可以帮助我们自动生成 ==domain/pojo/bean(完全生成) → dao/mapper (生成模型和一般crud方法)→ mapper.xml (生成模型和一般crud方法)→ service (生成模型和一般crud方法)→ serviceimpl (生成模型和一般crud方法) → controller (生成模型和一般crud方法)== 如果不满意它自带的crud方法,我们可以自己写,建议自己写! 该方法要注意的是mybatis-plus-generator3.5.1版本是一个转变 代码生成详见此处

2.2.2 配置数据,跨域和静态资源放行

由于基本配置是可以复用的,因此我将其粘贴下方. 采用 配置类和yaml配置文件相结合的方式 1.druid类配置文件

package com.vector.music.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Arrays;

/**
 * @author WangYuanJie
 * @description: about jdbcDruidConfig
 * @ClassName MyDataSourceConfig
 * @date 2022/1/21 16:17
 */
@Configuration
public class MyDataSourceConfig {
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource dataSource() throws SQLException {
        DruidDataSource druidDataSource = new DruidDataSource();
        //加入监控功能
//        druidDataSource.setFilters("stat,wall");

        return druidDataSource;
    }
    /*
     * 解决druid 日志报错:discard long time none received connection:xxx
     * */
    @PostConstruct
    public void setProperties(){
        System.setProperty("druid.mysql.usePingMethod","false");
    }
    /**
     * 配置druid的监控页
     * @return
     */
    @Bean
    public ServletRegistrationBean statViewServlet(){
        StatViewServlet statViewServlet = new StatViewServlet();
        ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet, "/druid/*");
        registrationBean.addInitParameter("loginUsername","admin");
        registrationBean.addInitParameter("loginPassword","123456");
        return registrationBean;
    }
    /**
     * WebStatFilter用于采集web-jdbc关联监控的数据
     */
    @Bean
    public FilterRegistrationBean webStatFilter(){
        WebStatFilter webStatFilter = new WebStatFilter();
        FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<>(webStatFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));
        filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.ico,/druid/*");
        return filterRegistrationBean;
    }
}

复制代码

2.后端解决跨域问题

/**
 * 解决跨域问题
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowCredentials(true)
                .allowedMethods("*");
    }
复制代码

3.解决静态资源放行问题

你可以将静态资源放在你想放置的位置,但是尽量不要放在项目工程中,因为项目工程后来只会在内存中运行.不要增加内存负荷,而且你将会出现一个奇怪的问题 springboot图片回显 详见此处

    /**
     * 默认情况下Spring Boot 使用WebMvcAutoConfiguration中配置的各种属性。
     * 默认映射的文件夹有:
     * classpath:/META-INF/resources
     * classpath:/resources
     * classpath:/static
     * classpath:/public
     * 上面这几个都是静态资源的映射路径,优先级顺序为:META-INF/resources > resources > static > public
     * 原理: 静态映射/**。
     * 请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面
     * 静态资源访问前缀
     * 默认无前缀
     * spring:
     * mvc:
     * static-path-pattern: /res/**
     * 当前项目 + static-path-pattern + 静态资源名 = 静态资源文件夹下找
     */
    // 以下是自定义静态资源访问
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        /**
         * spring boot中上传图片回显问题
         * 定位歌手头像地址
         * 绝对路径映射,这个不重新部署就可以回显,因为映射你的本地
         */
        registry.addResourceHandler("static/**").addResourceLocations(
                System.getProperty("user.dir") + File.separator + "static" + File.separator);

    }
复制代码

4.yaml配置文件

# 声明当前的服务端口号是8083
server:
  port: 8083
#spring配置
spring:
# 解决使用swagger高版本更新后路径匹配更新和mvc路径匹配模式不匹配的问题,导致druid报一个错
  mvc:
    pathmatch:
      matching-strategy: ANT_PATH_MATCHER
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/music?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
    username: music
    password: 123456
    # 配置druid-ui的一些功能
    druid:
      filters: stat,wall,slf4j
      max-active: 12
      stat-view-servlet:
        enabled: true
        login-username: admin
        login-password: 123456
        reset-enable: false
      web-stat-filter:
        enabled: true
        url-pattern: /*
        exclusions: '*.js,*.gif,*.jpg,*.ico,/druid/*'
      aop-patterns: com.vector.admin.*
      filter:
        stat:
          slow-sql-millis: 1000
          log-slow-sql: true
          enabled: true
        wall:
          enabled: true
  # json对象解析处理
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
  # 声明我们后端每次接收的大小和总大小
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 20000MB


# 配置 mybatis 相关内容
mybatis:
  #  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mapper/*.xml
  configuration: #指定mybatis全局配置文件中的相关配置项
    map-underscore-to-camel-case: true
mybatis-plus:
  type-aliases-package: com.vector.music.pojo
复制代码

2.3. 流水线式开发模式

domain/pojo/bean → dao/mapper→ mapper.xml → service → serviceimpl → controller 值得一提的是

一般的实体类的时间属性不要使用localdatetime,你驾驭不住!虽然它线程安全,你肯定要使用HttpRequestServlet来获取前端传入的字符串方法,然后通过datetime转化,之后拼接成必须的格式: yyyy-MM-dd HH:mm:ss 赋值给localdatetime

1.文件上传功能: 详见此处数据库一般存url,之前配置的静态资源路径存上传的实际文件.我们不用害怕uuid或时间戳使我们看不懂,可以通过其他字段确定上传的是什么. 2.注意对前端数据的校验. controller层:注意@RequestMapping等的请求方式和前端是否一致;注意是否写了@ResponseBody. 不要再使用HttpRequestServlet 获取前端传来的对象.因为他的代码重复度太高,修改时候也很麻烦.建议使用@RequestBody注解实体类获取前端的值.(注意前端传值的名称要与实体类的属性相对应) .`

mapper.xml: 我认为尽量带这个参数 insert image description here

三.前端vue搭建

声明: 前端技术自我感觉很菜

3.1 前端基本环境搭建

3.1.1 脚手架搭建和容易出现的错误

webstorm也和idea差不多了,搭建vue-cli很方便.搭建详见此处 需要注意的是后期npm run build 打包时候如果是空白页.就要看看config/index.js的 ==build==方法中的 assetsPublicPath: './'
router路由导航中是否是 history 模式.

3.1.2 axios与后端交互搭建

由于axios代码也是可复用的,因此将其粘贴如下

import axios from 'axios'
import router from '../router'

axios.defaults.timeout = 5000 // 超市时间是5秒
axios.defaults.withCredentials = true // 允许跨域
// Content-Type 响应头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
// 基础url
// 对应后端yaml文件的端口号
axios.defaults.baseURL = 'http://127.0.0.1:8083'

// 响应拦截器
axios.interceptors.response.use(
  response => {
    // 如果reponse里面的status是200,说明访问到接口了,否则错误
    if (response.status === 200) {
      return Promise.resolve(response)
    } else {
      return Promise.reject(response)
    }
  },
  error => {
    if (error.response.status) {
      switch (error.response.status) {
        case 401: // 未登录
          router.replace({
            path: '/',
            query: {
              redirect: router.currentRoute.fullPath
            }
          })
          break
        case 404: // 没找到
          break
      }
      return Promise.reject(error.response)
    }
  }
)

/**
 * 封装get方法
 */
export function get(url, params = {}) {
  return new Promise((resolve, reject) => {
    axios.get(url, {params: params})
      .then(response => {
        resolve(response.data)
      })
      .catch(err => {
        reject(err)
      })
  })
}

/**
 * 封装post方法
 */
export function post(url, data = {}) {
  return new Promise((resolve, reject) => {
    axios.post(url, data)
      .then(response => {
        resolve(response.data)
      })
      .catch(err => {
        reject(err)
      })
  })
}

复制代码

3.2 基本书写流程

基本分为axios请求,assets静态资源存放,router路由导航,vuex即store全局方法,view视图组件,componentsc具体功能组件和可复用组件 components分的比较细是为了解耦合.这些是基本的开发流程.但是一想到css我就头大.太难了,太难了啊.

3.3 前端再次强调注意的

1.注意后期npm run build 打包时候如果是空白页.就要看看config/index.js的 ==build==方法中的 assetsPublicPath: './'
router路由导航中是否是 history 模式. 2.注意对可复用组件的抽离,方便日后其他项目直接使用. 3.注意vue对象中的方法不可乱起名字,都要严格遵守vue官方文档.你可以随意发挥的只有,data(),methods(),computed(),watch()里面的.应该懂我说的什么意思吧.mixins混入 4.注意webpack安装失败的话要删除node_modules文件和package-lock.json文件 要想执行webpack命令必须先下载node

四.项目部署步骤.

1.项目中的访问地址修改成服务器的地址即(127.0.0.1或localhost或0.0.0.0修改至目标服务器),注意防火墙端口放行.可以使用tomcat 2.注意后台 端口, 前台 端口,并且都访问同一个后端 端口. 3.前端npm run build 打包前台和后台 dist 4.后端利用idea maven版本控制功能生成jar 在这里插入图片描述 5.注意开发的jdk和linux的jdk版本匹配,之后把jar包随便放一个地方,在该地方执行

nohup java -jar 上传jar包全名 >temp.txt 2>&1 &
复制代码

6.vue开发的前台和后台可以放在tomcat的webapps里 nginx的html里然后

#tomcat 启动 进入tomcat的bin路径下执行 
sh start.sh
#nginx 启动 进入nginx的sbin
nginx
复制代码

7. If the deployed static resources cannot be loaded, then there may be a problem with the cross-platform transmission tool. Default port MySQL 3306 nginx/http 80 https 443 tomcat 8080 Fort tower 8888 Project port customization is recommended after 1024

注意tomcat和nginx以及项目访问路径的端口放行和安全策略组防火墙的放行Another flash of light, forget it...

Summarize

The first time the project was separated and developed was very refreshing. The most rewarding thing was that I was familiar with the development process and learned a lot of techniques to facilitate development. But it is easy to forget. But these things were just like our meal, and they were inadvertently transformed into us. The next stage goal: mysql advanced learning: the main contents include, b+ tree structure in-depth, index optimization, data migration, disaster recovery backup, blocking and deadlock, and then write a boot project. Start redis learning. As for later learning The basic jvm, jmm or cloud, then I think it is jvm, jmm.

重申由于版权原因不会公布服务器地址,当然也怕被打.... github address

Sometimes I am also confused about the basic jvm, jmm, algorithm, compilation principle, database, accounting network; advanced mq message queue, kafka, cloud, zookeeper, k8s... It feels so far away, I have to learn but there is not enough time , I can’t be sure if I take the postgraduate entrance exam or not, and sometimes I feel really tired... I only have the joy of getting results after studying, but after a while, how much of it will feel like I have completed it independently? The sense of loss permeates me again. ... share a song but Taylor Swift's songs always give me renewed confidence!


Guess you like

Origin juejin.im/post/7086759454003675144