基于Vue+ElementPlus+Servlet实现前后段分离的学生管理系统
目录
零、系统介绍及其项目全套代码
系统介绍
基于Vue+ElementPlus+Servlet实现前后段分离的学生管理系统
前段所用技术:Vue3+ElementPlus
后端所用技术:mysql+JDBC+Tomcat+Servlet+Druid数据库连接池
实现的功能有:学生的新增、学生的修改、学生数据的回显、学生数据的删除
项目全套代码
链接地址:https://download.csdn.net/download/weixin_46411355/86719910
一、前段
1.搭建vue-cli+axios+ElementPlus脚手架
此处省略,可参考我的另一篇博客——《安装node.js后进行的操作(配置node环境变量、npm镜像加速、安装vue-cli项目脚手架、在IDEA中打开并运行脚手架、安装ElementPlus、新建路由)》
博客链接:https://huanghaoheng.blog.csdn.net/article/details/126821977
2.安装vue-axios依赖,并导入axios和vue-axios,同时修改main.js代码
2.1 安装vue-axios依赖
win+R打开运行框,输入cmd,回车
在DOS窗口输入vue ui
回车
打开浏览器输入地址:localhost:8080
弹出以下界面,点击依赖 => 点击添加依赖
搜索vue-axios依赖–>点击–>点击安装
弹出以下页面说明安装完成
2,2导入axios和vue-axios,同时修改main.js代码
main.js代码如下
import {createApp} from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import axios from 'axios'
import VueAxios from 'vue-axios'
export const app = createApp(App)
app.use(store)
.use(router)
.use(VueAxios, axios)
.use(ElementPlus).mount('#app')
3. 测试请求是否发送成功
在main.js发送请求
import {createApp} from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import axios from 'axios'
import VueAxios from 'vue-axios'
export const app = createApp(App)
app.use(store)
.use(router)
.use(VueAxios, axios)
.use(ElementPlus).mount('#app')
/*
*then是回调 后台返回的数据 就会被response对象接收
*/
app.axios.get("http://localhost:9090/student").then((response) => {
console.log(response.data)
})
npm install
后npm run serve
启动项目,具体如何操作可参考我的另一篇博客(博客链接:https://huanghaoheng.blog.csdn.net/article/details/126821977
打开浏览器按F12访问,localhost:8080,如果在Network中有student则发送的测试请求成功
4.解决前后段跨域问题
将以下代码复制到Servlet中的service方法里面
// resp.addHeader("Access-Control-Allow-Origin", "*");
resp.addHeader("Access-Control-Allow-Origin", "http://localhost:8080");//只允许localhost:8080访问我
resp.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
// resp.addHeader("Access-Control-Allow-Headers", "Content-Type");
resp.addHeader("Access-Control-Allow-Headers", "*");//所有的格式
resp.addHeader("Access-Control-Max-Age", "3600");//访问的超时时间多少毫秒
再次在浏览器中访问localhost:8080
看到student不飘红,预览有数据,则证明跨域问题解决成功
5.新建一个Student的路由
可以参考我之前分享的链接博客中的“六、新建路由”创建。博客链接:https://huanghaoheng.blog.csdn.net/article/details/126821977
也可以跟着笔者的下述步骤创建
5.1 在App.vue中注册Student路由组件
供读者复制粘贴的代码
App.vue文件
<template>
<nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/student">Student</router-link> |
</nav>
<router-view/>
</template>
<style lang="stylus">
#app
font-family Avenir, Helvetica, Arial, sans-serif
-webkit-font-smoothing antialiased
-moz-osx-font-smoothing grayscale
text-align center
color #2c3e50
margin-top 60px
</style>
5.2在router文件夹下的index,js里面配置路由表中路由和其对应的组件View视图
供读者复制粘贴的代码
router下的index,js文件
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
},
{
path: '/student',
name: 'student',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import( '../views/StudentView.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
5.3在views里面创建StudentView
供读者复制粘贴的代码
StudentView.vue文件
<template>
<div class="student">
<Student/>
</div>
</template>
<script>
// @ is an alias to /src
import Student from '@/components/Student.vue'
export default {
name: 'StudentView',
components: {
Student
}
}
</script>
5.4.在components中创建Student组件
供读者复制粘贴的代码
Student.Vue文件(页面的测试数据,后期对接Servlet后会做修改)
<template>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="Date" width="150" />
<el-table-column prop="name" label="Name" width="120" />
<el-table-column prop="state" label="State" width="120" />
<el-table-column prop="city" label="City" width="120" />
<el-table-column prop="address" label="Address" width="600" />
<el-table-column prop="zip" label="Zip" width="120" />
<el-table-column fixed="right" label="Operations" width="120">
<template #default>
<el-button link type="primary" size="small" @click="handleClick"
>Detail</el-button
>
<el-button link type="primary" size="small">Edit</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script>
export default {
data(){
return{
tableData:[
{
date: '2016-05-03',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
tag: 'Home',
},
{
date: '2016-05-02',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
tag: 'Office',
},
{
date: '2016-05-04',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
tag: 'Home',
},
{
date: '2016-05-01',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
tag: 'Office',
},
]
}
}
}
</script>
看后端到步骤5项目目录结构创建*
此时,后端 应该做到 步骤5项目目录结构创建
此时npm install
和npm run serve
运行前段程序,同时后段运行tomcat服务器,再浏览中访问localhost:8080
,点击Student路由,展示效果如下
6.前端发送axios请求,并渲染数据
结果
6.1 创建并封装前段请求
zho
HttpRequest.js文件
供读者复制粘贴的代码
import axios from 'axios'
import Qs from 'qs'
export function request(requestConfig) {
// axios 实例
const instance = axios.create({
baseURL: 'http://localhost:9090/',
timeout: 2000,
transformRequest: [function (data) {
// 对 data 进行任意对转换
return Qs.stringify(data);
}],
});
// 请求拦截器
instance.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
// 响应拦截器
instance.interceptors.response.use(function (response) {
// Do something with response data
return response.data;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
return instance(requestConfig);
}
StudentHttpRequest.js文件
供读者复制粘贴的代码
import {request} from '@/request/HttpRequest';
//查询学生列表信息
export function selectStudentList() {
var requestConfig = {
url:"/student",
method:"get"
}
return request(requestConfig);
}
6.2.页面学生表格数据渲染
Student.vue文件
供读者复制粘贴的代码
<!-- 展示的学生信息列表 -->
<el-table :data="tableData" style="width: 100%" stripe>
<el-table-column prop="name" label="姓名" width="250"/>
<el-table-column prop="age" label="年龄" width="250"/>
<el-table-column prop="gender" label="性别" width="250">
<template #default="scope">{{scope.row.gender?'男':'女'}}</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" width="250"/>
<el-table-column fixed="right" label="操作" width="250">
<template #default="scope">
<el-button link type="primary" size="small" @click="editById(scope.row)">编辑</el-button>
<el-button link type="primary" size="small" @click="deleteById(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script >
import {selectStudentList} from '@/request/studentHttpRequest'
export default {
data() {
return {
tableData:[]
}
},
created(){
this.showStudentList();
},
methods:{
// 自定义一个查询方法
showStudentList(){
selectStudentList().then(response=>{
this.tableData = response;
}).catch(function (error) {
console.log(error);
})
}
}
}
</script>
过程:由简单到难
在created()方法里面
// 方案一
// 报错解决方法一
axios.get('http://localhost:9090/student') // url 请求后台的地址
/*
* .then(function (response) 这样写前端会报错
* 报错信息:TypeError: Cannot set properties of undefined (setting 'tableData')at eval (Student.vue?401d:59:1)
* 这样写是匿名函数,无法取到tableData的值,所以tableData的值为undefined,不能给undefined的变量赋值
* 解决办法:1.改为箭头函数 2.将this重新赋值给新的变量
*/
// .then(function (response) { //成功回调方法(访问后台成功,后台有数据返回,则进入该方法)
.then(response=> { //成功回调方法(访问后台成功,后台有数据返回,则进入该方法)
console.log(response);
console.log(response.data)
this.tableData = response.data;
})
.catch(function (error) {//失败回调方法(访问后台失败,返回失败的信息,则进入该方法)
console.log(error);
});
// 方案二
//报错解决办法二
var th = this;
axios.get('http://localhost:9090/student') // url 请求后台的地址
.then(function (response) { //成功回调方法(访问后台成功,后台有数据返回,则进入该方法)
console.log(response);
console.log(response.data)
th.tableData = response.data;
})
.catch(function (error) {//失败回调方法(访问后台失败,返回失败的信息,则进入该方法)
console.log(error);
});
方案一和方案二是为了解决报错:TypeError: Cannot set properties of undefined (setting 'tableData')at eval (Student.vue?401d:59:1)
,详情请看我的另一篇博客(博客链接:https://huanghaoheng.blog.csdn.net/article/details/126956987)
方案三:在前端项目结构搭建util
HttpRequest.js文件
供读者复制粘贴的代码
import axios from 'axios';
export function requestHttp(config) {
const instance = axios.create({
baseURL: 'http://localhost:9090',
timeout: 1000,
headers: {'token': 'foobar'}
});
// 拼接 请求的信息 /student
return instance(config)
}
修改Student.vue代码 在script中导入requestHttp
import {requestHttp} from "@/util/HttpRequest";
//方案三
const config = {
url:"/student",
method:'get'
}
requestHttp(config) // url 请求后台的地址
.then(response=> { //成功回调方法(访问后台成功,后台有数据返回,则进入该方法)
console.log(response);
console.log(response.data)
this.tableData = response.data;
})
.catch(function (error) {//失败回调方法(访问后台失败,返回失败的信息,则进入该方法)
console.log(error);
});
方案四 利用axios的拦截器
HttpRequest.js
import axios from 'axios';
export function requestHttp(config) {
const instance = axios.create({
baseURL: 'http://localhost:9090',
timeout: 1000,
headers: {'token': 'foobar'}
});
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
instance.interceptors.response.use(function (response) {
// 对响应数据做点什么
if(response.status==200){
return response.data;
}
return null;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
// 拼接 请求的信息 /student
return instance(config)
}
Student.vue
script 导入
import {requestHttp} from "@/util/HttpRequest";
created()方法里面
// 方案四
const config = {
url:"/student",
method:'get'
}
requestHttp(config) // url 请求后台的地址
.then(response=> { //成功回调方法(访问后台成功,后台有数据返回,则进入该方法)
console.log(response);
console.log(response.data)
// 以下代码封装到响应拦截器中
// if(response.status==200){
// this.tableData = response.data;
// }
this.tableData = response;
})
.catch(function (error) {//失败回调方法(访问后台失败,返回失败的信息,则进入该方法)
console.log(error);
});
方案五:util中封装学生请求增删改查
StudentCRUD.js文件
// 封装查询方法,暴露查询方法
import {requestHttp} from "@/util/HttpRequest";
export function selectStudentList() {
const config = {
url:"/student",
method:'get'
}
return requestHttp(config) // url 请求后台的地址
}
在Student,vue里面
import {selectStudentList} from "@/util/StudentCRUD"
//方案五
selectStudentList()
.then(response=> { //成功回调方法(访问后台成功,后台有数据返回,则进入该方法)
console.log(response);
console.log(response.data)
// 以下代码封装到响应拦截器中
// if(response.status==200){
// this.tableData = response.data;
// }
this.tableData = response;
})
.catch(function (error) {//失败回调方法(访问后台失败,返回失败的信息,则进入该方法)
console.log(error);
});
方案六:
util中封装学生请求增删改查
StudentCRUD.js文件
// 封装查询方法,暴露查询方法
import {requestHttp} from "@/util/HttpRequest";
export function selectStudentList() {
const config = {
url:"/student",
method:'get'
}
return requestHttp(config) // url 请求后台的地址
}
在Student,vue里面
import {selectStudentList} from "@/util/StudentCRUD"
created()里面
// 方案六
this.showStudentList();
methods里面
methods:{
//自定义查询方法
showStudentList(){
selectStudentList()
.then(response=> { //成功回调方法(访问后台成功,后台有数据返回,则进入该方法)
console.log(response);
console.log(response.data)
// 以下代码封装到响应拦截器中
// if(response.status==200){
// this.tableData = response.data;
// }
this.tableData = response;
})
.catch(function (error) {//失败回调方法(访问后台失败,返回失败的信息,则进入该方法)
console.log(error);
});
}
}
看后端到步骤9项目目录结构创建*
此时,后端 应该做到 步骤9StudentServlet.java文件
此时npm install
和npm run serve
运行前段程序,同时后段运行tomcat服务器,再浏览中访问localhost:8080
,点击Student路由,数据已经变成了数据库中的数据。展示效果如下:
7.新增学生信息
Student.vue里面
template标签里面
新增学生信息按钮
<!-- 新增学生信息对话框 按钮部分 -->
<el-button type="primary" @click="dialogVisible = true">新增学生信息</el-button>
新增学生信息对话框
<!-- 新增学生信息对话框 对话框部分 -->
<!--center是否让 Dialog 的 header 和 footer 部分居中排列-->
<!--destroy-on-close 关闭 Dialog 时,销毁其中的元素-->
<el-dialog
v-model="dialogVisible"
:title="title"
center
width="60%"
destroy-on-close>
<!-- 新增学生信息对话框 表单部分 -->
<el-form :model="studentForm" label-width="120px">
<el-form-item label="姓名" prop="name">
<el-input v-model="studentForm.name" type="text"/>
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input v-model="studentForm.age" type="text"/>
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="studentForm.gender">
<el-radio label="1">男</el-radio>
<el-radio label="0">女</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="更新时间" prop="createTime">
<el-date-picker
v-model="studentForm.createTime"
type="date"
placeholder="请选择日期"
/>
</el-form-item>
</el-form>
<!-- 新增学生信息对话框 底部按钮部分 -->
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitBtn">保存</el-button>
</span>
</template>
</el-dialog>
scripts里面
import { ElMessage } from 'element-plus'
import {insertStudent, selectStudentList} from "@/util/StudentCRUD";
data里面
export default {
data() {
return {
tableData:[],
dialogVisible:false,
//学生信息对话框
studentForm:{
id:undefined,
name:undefined,
age:undefined,
gender:"0",
createTime:undefined
},
//新增学生信息对话框 标题
title:"学生信息添加"
}
},
methods里面
methods:{
submitBtn(){//保存事件(新增,修改)
if(this.studentForm.id){
// 修改
}else {
// 新增
//JSON.stringify(js对象):把js对象转换成JSON格式的字符串
// alert(1);
// alert(JSON.stringify(this.studentForm));
//Qs.stringify()封装到HttpRequest里面
// insertStudent(Qs.stringify(this.studentForm))
insertStudent(this.studentForm)
.then(resp=>{
console.log(resp);
if(resp.success){
//保存成功,刷新列表
this.showStudentList();
// dialog消失
this.dialogVisible = false;
}else{
ElMessage.error(resp.tip);
}
})
.catch(resp=>{
ElMessage.error("保存失败");
});
}
},
StudentCRUD.js里面新增如下代码
// 封装新增方法,暴露新增方法
export function insertStudent(student) {
const config = {
url:"/student?cmd=insert",
method:'post',
data:student
}
return requestHttp(config) // url 请求后台的地址
}
修改HttpRquest.js
导入Qs
将前段发送的数据转成JSON
import axios from 'axios';
import Qs from 'qs'
export function requestHttp(config) {
const instance = axios.create({
baseURL: 'http://localhost:9090',
timeout: 1000,
headers: {'token': 'foobar'},
// 将前段发送的数据转成JSON
transformRequest: [function (data) {
return Qs.stringify(data);
}]
});
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
instance.interceptors.response.use(function (response) {
// 对响应数据做点什么
if(response.status==200){
return response.data;
}
return null;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
// 拼接 请求的信息 /student
return instance(config)
}
新增按钮重置数据
<!-- 新增学生信息对话框 按钮部分 -->
<el-button type="primary" @click="insertClick">新增学生信息</el-button>
insertClick() {//新增弹框,重置数据
this.studentForm = {
id: undefined,
name: undefined,
age: undefined,
gender: 0,
createTime: undefined
},
this.dialogVisible = true;
this.title="学生信息添加";
},
8. 更新学生信息
数据的回显
Student.vue
<template #default="scope">
<el-button link type="primary" size="small" @click="editById(scope.row)">编辑</el-button>
<el-button link type="primary" size="small">删除</el-button>
</template>
Student.vue methods里面
editById(student) {//编辑弹框,回显数据
// alert(student);
// alert(JSON.stringify(student))
this.studentForm = {
id: student.id,
name: student.name,
age: student.age,
gender: student.gender,
createTime: student.createTime
},
this.dialogVisible = true;
this.title="学生信息修改";
},
StudentCRUD.js
// 封装修改方法,暴露修改方法
export function updateStudent(student) {
const config = {
url:"/student?cmd=update",
method:'post',
data:student
}
return requestHttp(config) // url 请求后台的地址
}
在Student.vue
import {insertStudent, selectStudentList,updateStudent} from "@/util/StudentCRUD";
submitBtn() {//保存事件(新增,修改)
if (this.studentForm.id) {
// 修改
updateStudent(this.studentForm)
.then(resp => {
console.log(resp);
if (resp.success) {
// 保存成功,刷新列表
this.showStudentList();
// dialog消失
this.dialogVisible = false;
} else {
ElMessage.error(resp.tip)
}
})
.catch(resp => {
ElMessage.error('保存失败')
});
9.删除学生信息
导入
import { ElMessage, ElMessageBox } from 'element-plus'
按钮
<template #default="scope">
<el-button link type="primary" size="small" @click="editById(scope.row)">编辑</el-button>
<el-button link type="primary" size="small" @click="deleteById(scope.row)">删除</el-button>
</template>
methods: {
deleteById(row){//删除 事件
ElMessageBox.confirm(
'您确定不要我了吗?',
'Warning',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
// 点击确定按钮
deleteById(row.id)
.then(resp=>{
if(resp.success){
// 刷新列表
this.showStudentList();
}else{
ElMessage.info(resp.tip);
}
})
})
},
StudentCRUD.js
// 封装删除方法,暴露删除方法
export function deleteById(id) {
const config = {
url:"/student?cmd=delete",
method:'get',
params:{
"id":id
}
}
return requestHttp(config) // url 请求后台的地址
}
Student.vue
import {insertStudent, selectStudentList, updateStudent,deleteById} from "@/util/StudentCRUD";
二、后端
1.建数据库、建表、导入项目数据
因为是学生管理系统,所以笔者建的数据库名为student-mannage
,表名为student
,建议和笔者保持一致
供读者复制粘贴的代码
数据库脚本
/*
Navicat Premium Data Transfer
Source Server : mysql57
Source Server Type : MySQL
Source Server Version : 50738
Source Host : localhost:13306
Source Schema : student-manage
Target Server Type : MySQL
Target Server Version : 50738
File Encoding : 65001
Date: 23/09/2022 20:17:13
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(12) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`age` int(10) UNSIGNED NULL DEFAULT NULL,
`gender` bit(1) NULL DEFAULT NULL,
`create_time` date NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `index_name`(`name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '张三丰', 23, b'1', '2022-03-01');
INSERT INTO `student` VALUES (2, '李四民', 11, b'0', '2022-03-30');
INSERT INTO `student` VALUES (3, '结衣', 12, b'1', '2022-08-08');
INSERT INTO `student` VALUES (4, 'Lisa', 26, b'1', '2022-03-30');
INSERT INTO `student` VALUES (5, 'tony', 32, b'1', '2022-08-07');
INSERT INTO `student` VALUES (6, '露露', 2, b'1', '2022-08-07');
INSERT INTO `student` VALUES (7, '丽丽', 13, b'1', '2022-08-12');
INSERT INTO `student` VALUES (8, '花花', 14, b'1', '2022-08-12');
INSERT INTO `student` VALUES (9, '猫咪', 15, b'1', '2022-08-12');
INSERT INTO `student` VALUES (10, '如花', 17, b'1', '2022-08-12');
INSERT INTO `student` VALUES (12, 'hhh', 23, b'1', '2022-09-17');
SET FOREIGN_KEY_CHECKS = 1;
2.在IDEA中搭建JavaWeb项目
步骤可参考我的另一篇博客《IDEA2020创建JavaWeb项目并配置tomcat》
博客链接: https://huanghaoheng.blog.csdn.net/article/details/126632499
3.Tomcat配置
4.导入jar包
jar包下载地址如下:
https://download.csdn.net/download/weixin_46411355/86720742
5.项目目录结构搭建
6.Druid数据库连接池工具类的撰写
util包下MyDruidUtil.java文件
供读者复制粘贴的代码
package com.bjpowernode.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class MyDruidUtil {
private MyDruidUtil(){
}
private static DataSource dataSource;
static {
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
try {
properties.load(inputStream);
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
public static void releaseSource(ResultSet resultSet, PreparedStatement preparedStatement, Connection connection) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static void releaseSource(PreparedStatement preparedStatement, Connection connection) {
releaseSource(null,preparedStatement,connection);
}
}
7.module层 Student类的创建
domain或者pojo包下Student.java文件
供读者复制粘贴的代码
package com.bjpowernode.domain;
import java.util.Date;
import java.util.Objects;
public class Student {
private Long id;
private String name;
private Integer age;
private int gender;
private Date createTime;
public Student() {
}
public Student(Long id, String name, Integer age, int gender, Date createTime) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
this.createTime = createTime;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", gender=" + gender +
", createTime=" + createTime +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return gender == student.gender &&
Objects.equals(id, student.id) &&
Objects.equals(name, student.name) &&
Objects.equals(age, student.age) &&
Objects.equals(createTime, student.createTime);
}
@Override
public int hashCode() {
return Objects.hash(id, name, age, gender, createTime);
}
}
8.dao层(StudentDAO)及其实现类(StudentDAOImpl)
dao包下的StudentDAO文件
供读者复制粘贴的代码
package com.bjpowernode.dao;
import com.bjpowernode.domain.Student;
import java.util.*;
public interface StudentDAO {
int insert(Student student);
int deleteById(Long id);
int update(Student student);
List<Student> listAll();
Student selectById(Long id);
}
dao包下的impl包下的StudentDAOImpl文件(目前实现了listAll查询全部学生列表的方法)
供读者复制粘贴的代码
package com.bjpowernode.dao.impl;
import com.bjpowernode.dao.StudentDAO;
import com.bjpowernode.domain.Student;
import com.bjpowernode.util.MyDruidUtil;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class StudentDAOImpl implements StudentDAO {
@Override
public int insert(Student student) {
return 0;
}
@Override
public int deleteById(Long id) {
return 0;
}
@Override
public int update(Student student) {
return 0;
}
@Override
public List<Student> listAll() {
List<Student> studentList = new ArrayList<>();
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = MyDruidUtil.getConnection();
String sql = "select * from student";
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
Student student = new Student();
student.setId(resultSet.getLong("id"));
student.setAge(resultSet.getInt("age"));
student.setGender(resultSet.getInt("gender"));
student.setCreateTime(resultSet.getDate("create_time"));
student.setName(resultSet.getString("name"));
studentList.add(student);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
MyDruidUtil.releaseSource(resultSet, preparedStatement, connection);
}
return studentList;
}
@Override
public Student selectById(Long id) {
return null;
}
}
9.JSONResult类
package com.bjpowernode.result;
import com.alibaba.fastjson.JSONObject;
public class JSONResult {
private boolean success = true;
private String tip;
// 操作失败 调用这个 方法
public JSONResult mark(String tip){
this.tip = tip;
this.success = false;
return this;
}
public boolean isSuccess() {
return success;
}
public String getTip() {
return tip;
}
}
11.StudentServlet.java文件
servlet包下StudentServlet.java文件
供读者复制粘贴的代码
package com.bjpowernode.servlet;
import com.alibaba.fastjson.JSON;
import com.bjpowernode.dao.StudentDAO;
import com.bjpowernode.dao.impl.StudentDAOImpl;
import com.bjpowernode.domain.Student;
import com.bjpowernode.result.JSONResult;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@WebServlet("/student")
public class StudentServlet extends HttpServlet {
private StudentDAO studentDAO = new StudentDAOImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 处理post请求乱码
req.setCharacterEncoding("utf-8");
//告知前端(vue),返回给vue的数据格式是json,内容使用utf-8编码解析
resp.setContentType("application/json;charset=utf-8");
// 解决跨域的问题
// resp.addHeader("Access-Control-Allow-Origin", "*");//任意协议、IP、端口都接收
resp.addHeader("Access-Control-Allow-Origin", "http://localhost:8080");//只允许localhost:8080访问我
resp.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
// resp.addHeader("Access-Control-Allow-Headers", "Content-Type");
resp.addHeader("Access-Control-Allow-Headers", "*");//所有的格式
resp.addHeader("Access-Control-Max-Age", "3600");//访问的超时时间多少毫秒
String method = req.getMethod();
if(method.equals("OPTIONS")){
PrintWriter writer = resp.getWriter();
writer.write("允许访问");
return;
}
// 因为所有的请求都会进入service方法中,
// 那么crud地址不同,如何在一个Servlet中进行区分
// 解决方案:在地址栏后面拼接参数。然后在后台根据参数区分操作
//接收参数cmd,为了区分是什么请求
String cmd = req.getParameter("cmd");
//使用一个三元运算符把cmd为null的情况 改成字符串
cmd = cmd == null ? "" : cmd;
switch (cmd) {
case "insert":
insertMethod(req,resp);
break;
default:
selectStudentList(req,resp);
}
}
private void selectStudentList(HttpServletRequest req, HttpServletResponse resp) throws IOException {
List<Student> studentList = studentDAO.listAll();
studentList.forEach(System.out::println);
//把数据转成JSON格式的字符串
String studentListJsonString = JSON.toJSONString(studentList);
//通过响应对象,给到vue
PrintWriter writer = resp.getWriter();
writer.write(studentListJsonString);
writer.flush();
}
12. CORSFilter类
解决前后段跨域问题 将 StudentServlet中的这部分代码封装到CORSFilter类中
package com.bjpowernode.filter;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebFilter("/*")
public class CORSFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain)
throws IOException, ServletException {
System.out.println("come in ");
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.addHeader("Access-Control-Allow-Origin", "http://localhost:8080");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.addHeader("Access-Control-Allow-Headers", "*");
response.addHeader("Access-Control-Max-Age", "1800");//30 min
filterChain.doFilter(request, response);
}
}
13.新增学生
StudentDAOImpl类中
@Override
public int insert(Student student) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = MyDruidUtil.getConnection();
// 获取预编译语句对象
String sql = "insert into student(name,age,gender,create_time) values(?,?,?,?)";
preparedStatement = connection.prepareStatement(sql);
// 设置参数
preparedStatement.setString(1,student.getName());
preparedStatement.setInt(2,student.getAge());
preparedStatement.setInt(3,student.getGender());
preparedStatement.setDate(4,new Date(student.getCreateTime().getTime()));
// 执行sql
return preparedStatement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
MyDruidUtil.releaseSource(preparedStatement,connection);
}
return 0;
}
StudentServlet文件中
private void insertMethod(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 接收参数
String name = req.getParameter("name");
String age = req.getParameter("age");
String gender = req.getParameter("gender");
String createTime = req.getParameter("createTime");
// 封装对象
Student student = new Student();
student.setName(name);
if(age!=null&&!age.equals("")){
student.setAge(Integer.valueOf(age));
}
if(gender!=null&&!gender.equals("")){
student.setGender(Integer.valueOf(gender));
}
if(createTime!=null&&!createTime.equals("")){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = simpleDateFormat.parse(createTime);
student.setCreateTime(date);
} catch (ParseException e) {
e.printStackTrace();
}
}
// 调用dao方法,保存数据
int result = studentDAO.insert(student);
JSONResult jsonResult = new JSONResult();
PrintWriter writer = resp.getWriter();
if(result>0){
// 保存成功
String jsonString = JSON.toJSONString(jsonResult);
writer.write(jsonString);
}else{
// 保存失败
String jsonString = JSON.toJSONString(jsonResult.mark("保存失败,请稍后重试"));
writer.write(jsonString);
}
}
14.修改学生信息
StudentServlet文件中
cmd = cmd == null ? "" : cmd;
switch (cmd) {
case "insert":
insertMethod(req,resp);
break;
case "update":
updateMethod(req,resp);
break;
default:
selectStudentList(req,resp);
}
private void updateMethod(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//接收参数
String id = req.getParameter("id");
String name = req.getParameter("name");
String age = req.getParameter("age");
String gender = req.getParameter("gender");
String createTime = req.getParameter("createTime");
//封装对象
Student student = new Student();
student.setName(name);
if(id!=null&&!id.equals("")){
student.setId(Long.valueOf(id));
}
if (age != null && !age.equals("")) {
student.setAge(Integer.valueOf(age));
}
if (gender != null && !gender.equals("")) {
student.setGender(Integer.valueOf(gender));
}
if (createTime != null && !createTime.equals("")) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = simpleDateFormat.parse(createTime);
student.setCreateTime(date);
} catch (ParseException e) {
e.printStackTrace();
}
}
// 调用dao 方法 保存数据
int result = studentDAO.update(student);
JSONResult jsonResult = new JSONResult();
PrintWriter writer = resp.getWriter();
if (result > 0) {
//保存成功
String jsonString = JSON.toJSONString(jsonResult);
writer.write(jsonString);
} else {
//保存失败
String jsonString = JSON.toJSONString(jsonResult.mark("保存失败,请稍后重试"));
writer.write(jsonString);
}
}
StudentDAOImpl文件
@Override
public int update(Student student) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = MyDruidUtil.getConnection();
// 获取预编译语句对象
String sql = "update student set name = ?,age=?,gender=?,create_time=? where id = ?";
preparedStatement = connection.prepareStatement(sql);
// 设置参数
preparedStatement.setString(1,student.getName());
preparedStatement.setInt(2,student.getAge());
preparedStatement.setInt(3,student.getGender());
preparedStatement.setDate(4,new Date(student.getCreateTime().getTime()));
preparedStatement.setLong(5,student.getId());
// 执行sql
return preparedStatement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
MyDruidUtil.releaseSource(preparedStatement,connection);
}
return 0;
}
15.删除学生信息
StudentServlet
case "delete":
deleteMethod(req,resp);
break;
private void deleteMethod(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String id = req.getParameter("id");
System.out.println("id = " + id);
if (id!=null&&!id.equals("")){
int result = studentDAO.deleteById(Long.valueOf(id));
JSONResult jsonResult = new JSONResult();
PrintWriter writer = resp.getWriter();
if (result > 0) {
//删除成功
String jsonString = JSON.toJSONString(jsonResult);
writer.write(jsonString);
} else {
//删除失败
String jsonString = JSON.toJSONString(jsonResult.mark("删除失败,请稍后重试"));
writer.write(jsonString);
}
}
StudentDAOImpl
@Override
public int deleteById(Long id) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = MyDruidUtil.getConnection();
// 获取预编译语句对象
String sql = "delete from student where id = ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setLong(1,id);
// 执行sql
return preparedStatement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
MyDruidUtil.releaseSource(preparedStatement,connection);
}
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/85581.html