基于Vue+ElementPlus+Servlet实现前后段分离的学生管理系统

导读:本篇文章讲解 基于Vue+ElementPlus+Servlet实现前后段分离的学生管理系统,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

基于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 installnpm 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 installnpm 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 installnpm 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

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!