需要项目源码请点赞关注收藏后评论区留言并且私信~~~
前后端分离的核心思想时前端页面通过掉用后端的RESTfulApI进行数据交互。本次项目使用Spring Boot+Spring Data JPA实现后端系统,使用Vue.js实现前端系统,数据库采用mysql,集成开发环境为Intellij IDEA
名片系统是针对注册用户使用的系统 有以下几种功能
1:非注册用户可以注册为注册用户
2:成功注册的用户可以登录系统
3:成功登录的用户,可以添加,修改,删除以及浏览自己客户的名片信息
添加mysql依赖和热部署依赖 具体代码如下
- <?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>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.1.9.RELEASE</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <groupId>com.ch</groupId>
- <artifactId>cardmis</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <name>cardmis</name>
- <description>Demo project for Spring Boot</description>
-
- <properties>
- <java.version>11</java.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-jpa</artifactId>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>8.0.30</version>
- </dependency>
-
- <!-- 热部署 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-devtools</artifactId>
- <optional>true</optional>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- </project>
在配置文件application.properties中 配置端口号 数据源以及文件上传等信息
-
- server.port=8443
- ###
- ##数据源信息配置
- ###
- #数据库地址
- spring.datasource.url=jdbc:mysql://localhost:3306/card?characterEncoding=utf8
- #数据库用户名
- spring.datasource.username=root
- #数据库密码
- spring.datasource.password=root
- #数据库驱动
- spring.datasource.driver-class-name=com.mysql.jdbc.Driver
- #要导入驱动包
- #数据库MySQL为8.x时,驱动类为com.mysql.cj.jdbc.Driver
- ####
- #JPA持久化配置
- ####
- #指定数据库类型
- spring.jpa.database=MYSQL
- #指定是否在日志中显示SQL语句
- spring.jpa.show-sql=true
- #指定自动创建、更新数据库表等配置,update表示如果数据库中存在持久化类对应的表就不创建,
- #不存在就创建对应的表
- spring.jpa.hibernate.ddl-auto=update
- #上传文件时,默认单个上传文件大小是1MB,max-file-size设置单个上传文件大小
- spring.servlet.multipart.max-file-size=50MB
- #默认总文件大小是10MB,max-request-size设置总上传文件大小
- spring.servlet.multipart.max-request-size=500MB
-
-
-
根据名片系统功能可知,名片系统一共有两个实体:用户和卡片,并且是一对多的关系,因此后端系统的持久化实体类一共有两个 分别为UserEntitiy和CardEntity
用户实体类代码如下
- package com.ch.cardmis.entity;
- import java.util.List;
- import java.io.Serializable;
- import javax.persistence.CascadeType;
- import javax.persistence.Entity;
- import javax.persistence.FetchType;
- import javax.persistence.GeneratedValue;
- import javax.persistence.GenerationType;
- import javax.persistence.Id;
- import javax.persistence.OneToMany;
- import javax.persistence.Table;
-
- import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
- @Entity
- @Table(name = "user_table")
- @JsonIgnoreProperties(value = { "hibernateLazyInitializer"})
- public class UserEntity implements Serializable{
- private static final long serialVersionUID = 1L;
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private int id;//主键
- private String uname;
- private String upwd;
- //名片列表,用户与名片是一对多的关系
- @OneToMany(
- mappedBy = "user",
- cascade=CascadeType.ALL,
- targetEntity = CardEntity.class,
- fetch=FetchType.LAZY
- )
- private List<CardEntity> cardEntityList;
-
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getUname() {
- return uname;
- }
- public void setUname(String uname) {
- this.uname = uname;
- }
- public String getUpwd() {
- return upwd;
- }
- public void setUpwd(String upwd) {
- this.upwd = upwd;
- }
-
- public List<CardEntity> getCardEntityList() {
- return cardEntityList;
- }
-
- public void setCardEntityList(List
cardEntityList ) { - this.cardEntityList = cardEntityList;
- }
- }
卡片实体类代码如下
- package com.ch.cardmis.entity;
- import java.io.Serializable;
- import javax.persistence.*;
- import com.fasterxml.jackson.annotation.JsonIgnore;
- import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
- @Entity
- @Table(name = "card_table")
- @JsonIgnoreProperties(value = { "hibernateLazyInitializer"})
- public class CardEntity implements Serializable {
- private static final long serialVersionUID = 1L;
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private int id;//主键
- private String name;
- private String telephone;
- private String email;
- private String company;
- private String post;
- private String address;
- private String logo;
- //所属用户,名片与用户是多对一的关系
- @ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},optional=false)
- //可选属性optional=false,表示用户不能为空。删除名片,不影响用户
- @JoinColumn(name="id_user_id")//设置在card_table表中的关联字段(外键)
- @JsonIgnore
- private UserEntity user;
- 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;
- }
-
- public String getTelephone() {
- return telephone;
- }
-
- public void setTelephone(String telephone) {
- this.telephone = telephone;
- }
-
- public String getEmail() {
- return email;
- }
-
- public void setEmail(String email) {
- this.email = email;
- }
-
- public String getCompany() {
- return company;
- }
-
- public void setCompany(String company) {
- this.company = company;
- }
-
- public String getPost() {
- return post;
- }
-
- public void setPost(String post) {
- this.post = post;
- }
-
- public String getAddress() {
- return address;
- }
-
- public void setAddress(String address) {
- this.address = address;
- }
-
- public String getLogo() {
- return logo;
- }
-
- public void setLogo(String logo) {
- this.logo = logo;
- }
-
- public UserEntity getUser() {
- return user;
- }
-
- public void setUser(UserEntity user) {
- this.user = user;
- }
-
- }
后端系统的数据访问是基于Spring Data JPA的,数据访问接口需要继承Repository接口,与持久化实体类一样,同样有用户和卡片两个数据访问接口
用户访问接口代码如下
- package com.ch.cardmis.repository;
-
- import com.ch.cardmis.entity.UserEntity;
- import org.springframework.data.jpa.repository.JpaRepository;
-
- public interface UserRepository extends JpaRepository<UserEntity, Integer> {
- /**
- * 查询用户名是否已存在
- */
- public UserEntity findByUname(String uname);
-
- /**
- *登录
- */
- public UserEntity findByUnameAndUpwd(String uname, String upwd);
- }
卡片访问接口代码如下
- package com.ch.cardmis.repository;
-
- import com.ch.cardmis.entity.CardEntity;
- import org.springframework.data.domain.Sort;
- import org.springframework.data.jpa.repository.JpaRepository;
-
- import java.util.List;
-
- public interface CardRepository extends JpaRepository<CardEntity, Integer> {
- //根据用户id查询该用户的名片
- public List<CardEntity> findByUser_id(Integer id, Sort sort);
- }
在Spring框架中 提倡使用接口,因此在业务层中涉及Service接口和Service实现类 代码如下
卡片实现类
- package com.ch.cardmis.service;
-
- import com.ch.cardmis.entity.CardEntity;
- import com.ch.cardmis.entity.UserEntity;
- import com.ch.cardmis.repository.CardRepository;
- import com.ch.cardmis.util.MyUtil;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.domain.Sort;
- import org.springframework.stereotype.Service;
- import org.springframework.web.multipart.MultipartFile;
-
- import javax.servlet.http.HttpSession;
- import java.io.File;
-
- @Service
- public class CardServiceImpl implements CardService {
- @Autowired
- private CardRepository cardRepository;
- @Override
- public String add(CardEntity cardEntity, HttpSession session, MultipartFile file) {
- if("noLogin".equals(isLogin(session))){
- return "noLogin";
- }else{
- UserEntity user = (UserEntity)session.getAttribute("user");
- cardEntity.setUser(user);
- //防止文件名重名
- String newFileName = "";
- if(file != null){
- String fileName = file.getOriginalFilename();
- newFileName = MyUtil.getNewFileName(fileName);
- String realpath = "C:\\Users\\ChenHeng\\IdeaProjects\\cardmis-vue\\cardmis-vue\\static";
- File targetFile = new File(realpath, newFileName);
- if(!targetFile.exists()){
- targetFile.mkdirs();
- }
- //设置文件名
- cardEntity.setLogo("static/" + newFileName);
- //上传
- try {
- file.transferTo(targetFile);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- cardRepository.save(cardEntity);
- return "ok";
- }
- }
- @Override
- public Object cards(HttpSession session) {
- if("noLogin".equals(isLogin(session))){
- return "noLogin";
- }/*
- else {
- Sort sort = new Sort(Sort.Direction.DESC, "id");
- UserEntity user = (UserEntity)session.getAttribute("user");
- return cardRepository.findByUser_id(user.getId(), sort);
- }
- */
- return null;
- }
- @Override
- public String delete(HttpSession session,Integer cid) {
- if("noLogin".equals(isLogin(session))){
- return "noLogin";
- }else {
- cardRepository.deleteById(cid);
- return "ok";
- }
- }
- @Override
- public Object aCard(HttpSession session, Integer cid) {
- if("noLogin".equals(isLogin(session))){
- return "noLogin";
- }else {
- return cardRepository.getOne(cid);
- }
- }
- @Override
- public String isLogin(HttpSession session) {
- Object user = session.getAttribute("user");
- if(user == null)
- return "noLogin";
- return "yes";
- }
-
-
- }
用户实现类
- package com.ch.cardmis.service;
- import com.ch.cardmis.entity.UserEntity;
- import com.ch.cardmis.repository.UserRepository;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
-
- import javax.servlet.http.HttpSession;
-
- @Service
- public class UserServiceImpl implements UserService {
- @Autowired
- private UserRepository userRepository;
- @Override
- public String register(UserEntity requestUser) {
- UserEntity ue = userRepository.findByUname(requestUser.getUname());
- if(ue != null)
- return "no";
- else{
- userRepository.save(requestUser);
- return "yes";
- }
- }
- @Override
- public String login(UserEntity requestUser, HttpSession session) {
- UserEntity ue = userRepository.findByUnameAndUpwd(requestUser.getUname(), requestUser.getUpwd());
- if(ue != null){//登录成功
- session.setAttribute("user", ue);
- return "ok";
- }
- return "no";
- }
- }
卡片控制器
- package com.ch.cardmis.controller;
-
- import com.ch.cardmis.entity.CardEntity;
- import com.ch.cardmis.service.CardService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.*;
- import org.springframework.web.multipart.MultipartFile;
-
- import javax.servlet.http.HttpSession;
-
- @RestController
- public class CardController {
- @Autowired
- private CardService cardService;
- @CrossOrigin//跨域访问
- @PostMapping(value = "cardmis/add")
- public String add(CardEntity cardEntity, HttpSession session, MultipartFile file) {
- return cardService.add(cardEntity, session, file);
- }
- @CrossOrigin//跨域访问
- @GetMapping(value = "cardmis/cards")
- public Object cards(HttpSession session) {
- return cardService.cards(session);
- }
- @CrossOrigin//跨域访问
- @PostMapping(value = "cardmis/delete")
- public String delete(HttpSession session,Integer cid) {
- return cardService.delete(session,cid);
- }
- @CrossOrigin//跨域访问
- @GetMapping(value = "cardmis/aCard")
- public Object aCard(HttpSession session,Integer cid) {
- return cardService.aCard(session,cid);
- }
- }
用户控制器
- package com.ch.cardmis.controller;
-
- import com.ch.cardmis.entity.UserEntity;
- import com.ch.cardmis.service.UserService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.*;
- import javax.servlet.http.HttpSession;
-
- @RestController
- public class UserController {
- @Autowired
- private UserService userService;
- @CrossOrigin//跨域访问
- @PostMapping(value = "cardmis/register")
- public String register(@RequestBody UserEntity requestUser) {
- return userService.register(requestUser);
- }
-
- @CrossOrigin//跨域访问
- @PostMapping(value = "cardmis/login")
- public String login(@RequestBody UserEntity requestUser, HttpSession session) {
- return userService.login(requestUser, session);
- }
- }
后端系统项目目录结构如下
后面几个类代码省略不表 有需要请点赞关注收藏后评论区留言并且私信

Node.js与Vue.js的部署请参考我这篇博客 此处不再赘述
项目结构目录如下

开发前端页面
在开发的时候,前端用前端的服务器开发,后端用后端的服务器开发。当开发前端内容时,可以把前端的请求通过前端服务器转发给后端,即可实现观察结果,并且不需要知道后端怎么实现,而只需要知道接口提供的功能,前后端的开发人员各司其职
部分Vue代码如下
- <template>
- <div class="active">
- <NavMain></NavMain>
- <h3>添加名片</h3>
- <form>
- 姓名:<input type="text" v-model="name" placeholder="请输入用户名"/><br><br>
- 电话:<input type="text" v-model="telephone" placeholder="请输入电话"/><br><br>
- 邮箱:<input type="text" v-model="email" placeholder="请输入邮箱"/><br><br>
- 单位:<input type="text" v-model="company" placeholder="请输入单位"/><br><br>
- 邮编:<input type="text" v-model="post1" placeholder="请输入邮编"/><br><br>
- 地址:<input type="text" v-model="address" placeholder="请输入地址"/><br><br>
- 头像:
- <input type="file" @change="getFile($event)"/><br><br>
- <button type="button" @click="add($event)" :disabled="isDisable">添加</button>
- <button type="reset">重置</button>
- </form>
- <br>
- </div>
- </template>
- <script>
- import NavMain from '@/components/NavMain'
- export default {
- name: 'Add',
- components: {NavMain},
- data () {
- return {
- isDisable:false
- }
- },
- methods: {
- //获得文件对象
- getFile(event) {
- this.file = event.target.files[0];
- },
- add (event) {
- this.isDisable = true;
- event.preventDefault();
- let formData = new FormData();
- formData.append('name', this.name === undefined ? '': this.name);
- formData.append('telephone', this.telephone === undefined ? '': this.telephone);
- formData.append('email', this.email === undefined ? '': this.email);
- formData.append('company', this.company === undefined ? '': this.company);
- formData.append('post', this.post1 === undefined ? '': this.post1);
- formData.append('address', this.address === undefined ? '': this.address);
- formData.append('file', this.file === undefined ? null: this.file);
- let config = {
- headers:{'Content-Type':'multipart/form-data'}
- };
- this.$axios
- .post('/add', formData, config)//直接提交表单
- .then(successResponse => {
- if (successResponse.data === "ok") {
- alert("添加成功")
- this.$router.replace({path: '/main'})
- }else if(successResponse.data === "noLogin"){
- alert("没有登录,请登录!")
- this.$router.replace({path: '/login'})
- }else {
- alert("添加失败")
- this.isDisable = false
- }
- })
- .catch(failResponse => {
- alert("响应异常")
- })
- }
- }
- }
- </script>
- <style>
- .active {
- background-image: url("../assets/bb.jpg");
- }
- </style>
同样还有修改路由配置,使用钩子函数判断是否登录等操作 此处不再赘述
首先运行后端系统cardmis的主类,然后再启动前端系统cardmis-vue的主类 通过访问
https://localhost:8080/测试运行 效果如下
首页如下

登录界面如下 会自动查询mysql数据库中有无匹配记录

注册界面如下 新用户可以先注册

主页面显示已有的名片信息

同时可以实现基本的增删改查功能

创作不易 觉得有帮助请点赞关注收藏~~~