164
社区成员
发帖
与我相关
我的任务
分享1. 项目目录结构(对应 Github 后端仓库)
src/
├── main/
│ ├── java/com/student/contact/
│ │ ├── ContactApplication.java(启动类)
│ │ ├── controller/ContactController.java(接口层)
│ │ ├── entity/Contact.java(实体类)
│ │ ├── mapper/ContactMapper.java(数据库操作)
│ │ └── service/ContactService.java(业务层)
│ └── resources/
│ ├── application.yml(配置文件)
│ └── mybatis/mapper/ContactMapper.xml(SQL映射)
└── test/(测试类可省略,作业暂不要求)
2. 核心文件代码
(1)实体类 Contact.java
package com.student.contact.entity;
import lombok.Data;
@Data // 简化getter/setter,需在pom.xml添加lombok依赖
public class Contact {
private Integer id; // 唯一标识
private String name; // 联系人姓名
private String phone; // 手机号
private String email; // 可选扩展字段(加分项)
}
(2)数据库配置 application.yml
spring:
datasource:
url: jdbc:mysql://你的服务器IP:3306/contact_db?useSSL=false&serverTimezone=Asia/Shanghai
username: root(数据库用户名,默认root)
password: 你的数据库密码
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml
type-aliases-package: com.student.contact.entity
(3)接口层 ContactController.java(核心增删改接口)
package com.student.contact.controller;
import com.student.contact.entity.Contact;
import com.student.contact.service.ContactService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/contact")
@CrossOrigin // 解决前端跨域问题,必须加
public class ContactController {
@Autowired
private ContactService contactService;
// 添加联系人
@PostMapping("/add")
public String addContact(@RequestBody Contact contact) {
boolean success = contactService.addContact(contact);
return success ? "添加成功" : "添加失败";
}
// 修改联系人(禁用缓存,直接查数据库)
@PostMapping("/update")
public String updateContact(@RequestBody Contact contact) {
// 直接查询数据库验证id存在,不使用缓存
Contact exist = contactService.getContactById(contact.getId());
if (exist == null) return "联系人不存在";
boolean success = contactService.updateContact(contact);
return success ? "修改成功" : "修改失败";
}
// 删除联系人
@GetMapping("/delete/{id}")
public String deleteContact(@PathVariable Integer id) {
Contact exist = contactService.getContactById(id);
if (exist == null) return "联系人不存在";
boolean success = contactService.deleteContact(id);
return success ? "删除成功" : "删除失败";
}
// 查询所有联系人(前端展示用)
@GetMapping("/list")
public List<Contact> getContactList() {
return contactService.getContactList();
}
}
(4)SQL 映射 ContactMapper.xml
<?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="com.student.contact.mapper.ContactMapper">
<!-- 添加联系人 -->
<insert id="addContact" parameterType="Contact">
INSERT INTO contact (name, phone, email) VALUES (#{name}, #{phone}, #{email})
</insert>
<!-- 修改联系人 -->
<update id="updateContact" parameterType="Contact">
UPDATE contact SET name=#{name}, phone=#{phone}, email=#{email} WHERE id=#{id}
</update>
<!-- 删除联系人 -->
<delete id="deleteContact" parameterType="Integer">
DELETE FROM contact WHERE id=#{id}
</delete>
<!-- 查询所有联系人 -->
<select id="getContactList" resultType="Contact">
SELECT * FROM contact
</select>
<!-- 根据id查询联系人 -->
<select id="getContactById" parameterType="Integer" resultType="Contact">
SELECT * FROM contact WHERE id=#{id}
</select>
</mapper>
3. 数据库建表 SQL(在 MySQL 中执行)
CREATE DATABASE IF NOT EXISTS contact_db;
USE contact_db;
CREATE TABLE IF NOT EXISTS contact (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
phone VARCHAR(11) NOT NULL UNIQUE,
email VARCHAR(50)
);
1. 项目目录结构(对应 Github 前端仓库)
src/
├── components/
│ └── Contact.vue(核心页面,含增删改功能)
├── main.js(入口文件)
├── App.vue(根组件)
└── assets/(可放CSS样式,暂不要求)
2. 核心文件代码
(1)Contact.vue(核心页面)
<template>
<div class="contact-container">
<h1>通讯录管理</h1>
<!-- 添加联系人表单 -->
<div class="add-form">
<input v-model="newContact.name" placeholder="请输入姓名" />
<input v-model="newContact.phone" placeholder="请输入手机号" />
<input v-model="newContact.email" placeholder="请输入邮箱(可选)" />
<button @click="addContact">添加联系人</button>
</div>
<!-- 联系人列表 -->
<table class="contact-table">
<tr>
<th>ID</th>
<th>姓名</th>
<th>手机号</th>
<th>邮箱</th>
<th>操作</th>
</tr>
<tr v-for="contact in contactList" :key="contact.id">
<td>{{ contact.id }}</td>
<td>{{ contact.name }}</td>
<td>{{ contact.phone }}</td>
<td>{{ contact.email }}</td>
<td>
<button @click="openUpdateDialog(contact)">修改</button>
<button @click="deleteContact(contact.id)">删除</button>
</td>
</tr>
</table>
<!-- 修改联系人弹窗 -->
<div class="dialog" v-if="isUpdateDialogOpen">
<div class="dialog-content">
<h3>修改联系人</h3>
<input v-model="updateContact.name" placeholder="请输入姓名" />
<input v-model="updateContact.phone" placeholder="请输入手机号" />
<input v-model="updateContact.email" placeholder="请输入邮箱(可选)" />
<button @click="updateContactInfo">确认修改</button>
<button @click="closeUpdateDialog">取消</button>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'; // 需安装axios:npm install axios
export default {
data() {
return {
newContact: { name: '', phone: '', email: '' }, // 新增联系人数据
updateContact: { id: '', name: '', phone: '', email: '' }, // 修改联系人数据
contactList: [], // 联系人列表
isUpdateDialogOpen: false // 修改弹窗开关
};
},
mounted() {
this.getContactList(); // 页面加载时查询所有联系人
},
methods: {
// 查询所有联系人
getContactList() {
axios.get('http://你的服务器IP:8080/contact/list')
.then(res => this.contactList = res.data)
.catch(err => alert('查询失败:' + err));
},
// 添加联系人
addContact() {
axios.post('http://你的服务器IP:8080/contact/add', this.newContact)
.then(res => {
alert(res.data);
this.getContactList(); // 刷新列表
this.newContact = { name: '', phone: '', email: '' }; // 清空表单
})
.catch(err => alert('添加失败:' + err));
},
// 打开修改弹窗
openUpdateDialog(contact) {
this.updateContact = { ...contact }; // 复制联系人数据到修改表单
this.isUpdateDialogOpen = true;
},
// 关闭修改弹窗
closeUpdateDialog() {
this.isUpdateDialogOpen = false;
},
// 修改联系人
updateContactInfo() {
axios.post('http://你的服务器IP:8080/contact/update', this.updateContact)
.then(res => {
alert(res.data);
this.getContactList(); // 刷新列表
this.closeUpdateDialog(); // 关闭弹窗
})
.catch(err => alert('修改失败:' + err));
},
// 删除联系人
deleteContact(id) {
if (confirm('确定要删除该联系人吗?')) {
axios.get(`http://你的服务器IP:8080/contact/delete/${id}`)
.then(res => {
alert(res.data);
this.getContactList(); // 刷新列表
})
.catch(err => alert('删除失败:' + err));
}
}
}
};
</script>
<style scoped>
/* 简单样式,可自行修改 */
.contact-container { width: 80%; margin: 0 auto; padding: 20px; }
.add-form { margin: 20px 0; }
.add-form input { margin-right: 10px; padding: 5px; }
.contact-table { width: 100%; border-collapse: collapse; }
.contact-table th, td { border: 1px solid #000; padding: 8px; text-align: center; }
.dialog { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; }
.dialog-content { background: #fff; padding: 20px; border-radius: 5px; }
.dialog-content input { margin: 10px 0; padding: 5px; width: 200px; }
</style>
(2)main.js(入口文件)
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'
Vue.prototype.$axios = axios // 全局挂载axios,方便使用
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')