Spring Boot+Vite+Vue3二手商城 软件环境
node .js v16.16.0
npm v8.11.0
jdk v1.8
vite v2.9.13
后端JAVAIDE
前端开发IDE
webStrom 2022.2.1
HBuilderX 3.6.14
maven-3.8.6-bin
前端框架搭建 vite 搭建 1 2 3 4 5 # npm 7+, 需要额外的双横线: npm init vite@latest 项目名称 -- --template vue cd 安装路径 npm install npm run dev
引入element-plus 1 npm install element-plus --save
引入vue-router 1 npm install vue-router -S
修改vite项目下的main.js 1 2 3 4 5 6 7 8 9 10 import { createApp } from 'vue' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import App from './App.vue' import router from './router' const app = createApp (App )app.use (ElementPlus ).use (router).mount ('#app' )
前端框架编写 编写router配置
在src目录下创建router目录
在目录下床架index.js来配置路由文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import { createRouter, createWebHistory, } from 'vue-router' const defaultTitle = 'home' ;const routes = [ { path : '/' , name : 'Home' , component : () => import ('../views/Home.vue' ), meta : {hidden : true , title : "主页" } }, ] const router = createRouter ({ history : createWebHistory ("/" ), routes : routes, }) router.beforeEach ((to, from , next ) => { document .title = to.meta .title ? to.meta .title : defaultTitle; next (); }); export default router;
应用router配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <template > <router-view /> </template > <script > </script > <style > * { margin : 0 ; padding : 0 ; } </style >
运行前端框架
编写登录页面 页面主体 编写SM.MS图床上传(巨坑) 在vite.config.js中配置跨域设置
1 2 3 4 5 6 7 8 9 10 server :{ proxy : { '/api' : { secure : false , changeOrigin : true , target : 'https://smms.app/api/v2/' , rewrite : path => path.replace (/^\/api/ , '' ) } } }
编写前端请求 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <template > <input type ="file" accept ="image/*" ref ="picture" multiple ="multiple" @change ="getPicture($event)" /> </template > <script setup > import axios from "axios" ; function getPicture (e ) { const formData = new FormData (); formData.append ("smfile" , e.target .files [0 ]); axios ({ method : "POST" , url : "/api/upload" , headers : {'Content-Type' : 'multipart/form-data' , 'Authorization' : 'kNpYkOLitfvgPOkitOTBwDfzNzGPMDLY' }, data : formData }).then ((response ) => { console .log (response.data ) }); } </script > <style > </style >
后端框架搭建 配置maven(提高导包速度)
apache-maven-3.8.6\conf\setting.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <mirror > <id > alimaven</id > <name > aliyun maven</name > <url > http://maven.aliyun.com/nexus/content/groups/public/</url > <mirrorOf > central</mirrorOf > </mirror > <mirror > <id > uk</id > <mirrorOf > central</mirrorOf > <name > Human Readable Name for this Mirror.</name > <url > http://uk.maven.org/maven2/</url > </mirror > <mirror > <id > CN</id > <name > OSChina Central</name > <url > http://maven.oschina.net/content/groups/public/</url > <mirrorOf > central</mirrorOf > </mirror > <mirror > <id > nexus</id > <name > internal nexus repository</name > <url > http://repo.maven.apache.org/maven2</url > <mirrorOf > central</mirrorOf > </mirror >
设置idea 安装插件
更改文件编码格式
设置maven路径
创建Spring-Boot项目
编写后端框架 设置application.properties来链接数据库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 spring.application.name =demo mybatis.mapper-locations =classpath:mappers/*xml mybatis.type-aliases-package =com.example.demo.entity spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver spring.datasource.name =defaultDataSource spring.datasource.url =jdbc:mysql://localhost:3306/数据库名称?serverTimezone=GMT%2b8&characterEncoding=utf8 spring.datasource.username =root spring.datasource.password =root server.port =8080
解决跨域问题
在路径下新建common 包
新建Java类,命名为CorsConfig
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.cors.CorsConfiguration;import org.springframework.web.cors.UrlBasedCorsConfigurationSource;import org.springframework.web.filter.CorsFilter;@Configuration public class CorsConfig { private static final long MAX_AGE = 24 * 60 * 60 ; @Bean public CorsFilter corsFilter () { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource (); CorsConfiguration corsConfiguration = new CorsConfiguration (); corsConfiguration.addAllowedOrigin("*" ); corsConfiguration.addAllowedHeader("*" ); corsConfiguration.addAllowedMethod("*" ); corsConfiguration.setMaxAge(MAX_AGE); source.registerCorsConfiguration("/**" , corsConfiguration); return new CorsFilter (source); } }
创建Mapper(接口)目录 在resources文件下创建mapper目录(mybatis.mapper-locations=classpath:mappers/*xml由上方该条语句来确定创建目录的位置)
创建entity(实体)类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import lombok.Data;@Data public class User { private Integer id; private String username; private String password; private String sex; private Integer age; private String phone; private String email; private String address; private String avatar; }
创建和编写dao(工具)类
创建dao包,用于管理不同实例dao类
以实例UserDao为例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import com.example.demo.entity.User;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;import java.util.List;@Mapper public interface UserDao { List<User> findAll () ; User findById (Integer id) ; User getByUser (@Param("username") String username, @Param("password") String password) ; int insert (User user) ; int update (User user) ; int deleteById (Integer id) ; User findByUser (String username) ; }
配置相应Mapper.xml的文件头部来相互链接
以UserMapper.xml文件为例
1 2 3 4 5 6 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="对应Dao类的空间地址" > </mapper >
编写Mapper(写SQL查询语句)文件
1 2 3 4 <insert id ="insert" > INSERT INTO `user`(username, password,sex,age,phone,email,address,avatar) values (#{username}, #{password},#{sex},#{age},#{phone},#{email},#{address},#{avatar}); </insert >
1 2 3 4 5 <delete id ="deleteById" > DELETE from `user` where id = #{id}; </delete >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <update id ="update" > update `user` <set > <if test ="username != null and username != ''" > username = #{username}, </if > <if test ="password != null and password != ''" > password = #{password}, </if > <if test ="sex != null and sex != ''" > sex = #{sex}, </if > <if test ="age != null" > age = #{age}, </if > <if test ="phone != null and phone != ''" > phone = #{phone}, </if > <if test ="email != null and email != ''" > email = #{email}, </if > <if test ="address != null and address != ''" > address = #{address}, </if > <if test ="avatar != null and avatar != ''" > avatar = #{avatar}, </if > </set > where id = #{id} </update >
查询所有:
1 2 3 4 <select id ="findAll" resultType ="com.example.demo.entity.User" > SELECT * FROM user; </select >
通过Id查询
1 2 3 4 5 <select id ="findById" resultType ="com.example.demo.entity.User" > SELECT * FROM user WHERE id = #{id}; </select >
通过用户名和密码查询
1 2 3 4 5 6 <select id ="getByUser" resultType ="com.example.demo.entity.User" > SELECT * FROM user WHERE username = #{username} AND password = #{password}; </select >
创建Result(返回数据打包)类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package com.example.demo.common;import lombok.Data;@Data public class Result { private String code; private String msg; private Object data; private static final String SUCCESS_CODE = "200" ; private static final String SUCCESS_MSG = "请求成功" ; private static final String ERROR_CODE = "-1" ; public static Result success () { Result result = new Result (); result.setCode(SUCCESS_CODE); result.setMsg(SUCCESS_MSG); return result; } public static Result success (Object data) { Result result = success(); result.setData(data); return result; } public static Result error (String msg) { Result result = new Result (); result.setCode(ERROR_CODE); result.setMsg(msg); return result; } }
创建和编写controller(控制)类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 package com.example.demo.controller;import com.example.demo.common.Result;import com.example.demo.dao.UserDao;import com.example.demo.entity.User;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.List;@RestController @RequestMapping("/user") public class UserController { @Autowired private UserDao userDao; @GetMapping public Result findAll () { return Result.success(userDao.findAll()); } @GetMapping("/{id}") public Result findById (@PathVariable Integer id) { return Result.success(userDao.findById(id)); } @GetMapping("/username/{username}") public Result findByUser (@PathVariable String username) { return Result.success(userDao.findByUser(username)); } @PostMapping public Result save (@RequestBody User user) { if (user.getUsername() == null || user.getPassword() == null ) { return Result.error("参数错误" ); } Result result = Result.success(userDao.insert(user)); return result; } @PostMapping("/login") public Result login (@RequestBody User user) { if (user.getUsername() == null || user.getPassword() == null ) { return Result.error("参数错误" ); } User result = userDao.getByUser(user.getUsername(), user.getPassword()); if (result == null ) { return Result.error("账号或密码错误" ); } return Result.success(result); } @PutMapping public Result update (@RequestBody User user) { if (user.getId() == null ) { return Result.error("参数错误" ); } userDao.update(user); return Result.success(); } @DeleteMapping("/{id}") public Result delete (@PathVariable Integer id) { if (id == null || id == 0 ) { return Result.error("参数错误" ); } return Result.success(userDao.deleteById(id) == 1 ); } }