系列文章目录
目录
实验描述
实验目的
安装配置好Tomcat应用服务器,使用Java进行JSP、Servlet的编写web应用并将其部署到Tomcat上。
实验对应知识点
结合HTML进行JavaEE框架中的JSP、Servlet编程。
实验前任务
学习Java的基本语法以及Java数据库编程。
实验内容
一、配置bulabula
二、编写web页面,完成对实验一数据库的操作
1、编写页面如图2.6所示
2、分别对应于2个表单编写后台处理逻辑(可以用JSP或Servlet进行处理),然后返回一个页面处理结果的页面,告知用户成功完成什么操作(如是进行了删除操作则信息相应改变),页面内有链接进行数据库数据的查询,如图2.7所示。
3、点击”查看数据库数据”则跳转到如图2.8所示页面,将数据库数据在页面中呈现出来,页面内有返回数据库操作页面的链接,点击即可跳转到数据库操作页面。
4、编码要求:重用实验一的JDBC封装类,通过该封装类来进行数据库的增删改查。
提示:以下是本篇文章正文内容,下面案例可供参考
实验步骤
!!!重要说明!!!
2020-12-03更:
很多小伙伴反应配置环境出了问题,其实不需要那么复杂
从github下zip代码解压后,在IDEA 左上角
File -> New -> Project From Existing Sources 然后
选择我项目中的pom.xml 文件打开,会自动配置好环境~~~~~~
本次实验我用的springboot框架,使用的是IDEA。
主要页面的实现没有用jsp(框架不推荐),而是用的js实现动态,并且没有用第一次实验的代码(如果想接着第一次实验继续做的小伙伴不用往下看了,如果想试点新东西的小伙伴可以翻一翻看看)。
springboot这个框架我也是现学现卖,加了一些自己的理解,如有错误,敬请谅解。
一、创建和配置springboot框架(准备步骤)
1.下载安装IDEA
官网地址:IDEA
可以使用30天试用,也可以申请学生试用(我就是这么搞得,可以用到毕业,这个公司下的所有产品都可以用,比如pycharm),也可以百度你懂得
下载完后安装登录账号即可
2.新建配置springboot项目
新建项目
右上角File -> New -> Project
如图选择右侧Spring Initializr
设置如图
在左侧选择如图,最终结果如图右侧
建好后,项目结构如图
连接数据库
IDE右侧选择database
连接MySQL数据库
在1处选择数据库,2处选择数据库驱动
右键数据库,选择属性
输入数据库的账号密码,然后测试连接,当出现绿色对勾时,连接成功
准备工作到此结束~~~~~
二、代码详情
1.我的代码结构
代码结构如下:
其中红框框起来的东西可以不要,其他文件可以参考我创建
代码各部分详细说明
最初看到这个代码可能是一脸懵逼的,没关系,我们一部分一部分说明其作用。
java文件夹下
TestApplication 是程序的入口,主函数。
我们在最初创建项目的基础上新建了四个文件夹,注意这四个文件夹的名字并不是任意取得,每个都代表了其作用。
其中:
bean:实体类是属性对象,用于供给其他层引用,该层的属性往往和数据库的表结构各个字段相同
mapper:mapper层往往要写上@mapper注解,告诉springboot这个是mapper接口。mapper层所定义的接口要实现对数据的操作可以采用两种方式:一个是加上@mapper注解之后,采用sql语句。另一种是继承mapper接口
service:service层负责功能的编写。将所需要的功能都定义在一个service层的接口当中,再创建一个包,该包中定义实现类,用来实现方法,编写功能实现的代码。之前springboot启动成功后,localhost没有返回数据是因为再service层的实现类里面没有添加@service注解。
controller:controller往往定义一个service接口的对象,然后调用里面的方法。接着将结果输出即可。一般要加@RestController,该注解的作用将结果以json 的格式返回。RequestMapping用来和http请求进行交互。将http所相应的请求添加到该Rest控制器里面的方法中。在controller层定义service对象的时候要加@Autowired自动注入。
我的理解就是(如有错误,敬请指正):
当我们接受到一个网页请求时,我们用controller文件夹下的代码去处理这个请求,然后controller调用service层的代码。
service主要功能是为不同的需求提供丰富的接口,其中关于数据库的操作需要调用mapper层
mapper层封装好了关于数据库的各种操作,供service调用,其中数据库操作的实体在bean层
bean层主要放了实体,一般来说实体和数据库表一一对应,实体中的成员变量和表中的字段一一对应
层层调用,在每一层做不同的操作
resources 文件夹下
其中static文件夹下保存静态资源,例如 js 代码和 css 样式文件
templates文件夹下保存html页面
application.yml 保存项目配置文件
(这个文件也可以用实验一的.properties文件,注意
1.配置的语法不同
2.yml配置更好,因为结构看上去比较清晰)
2.代码详情
主函数入口文件
TestApplication
package com.example.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
bean层
实体类
@Entity注解:声明为实体类
@Table注解:将实体映射到数据库表
@GeneratedValue注解:为一个实体生成一个唯一标识的主键
Person类
package com.example.test.bean;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "person")
public class Person {
@Id
@GeneratedValue
private String username;
private String name;
private String teleno ;
private int age;
{
age = -1;
}
public Person() {
}
public String getUsername(){return username;}
public void setUsername(String username){this.username = username;}
public String getName(){return name;}
public void setName(String name){this.name = name;}
public String getTeleno(){return teleno;}
public void setTeleno(String teleno){this.teleno = teleno;}
public int getAge(){return age;}
public void setAge(String age){
if (age != "")
this.age = Integer.parseInt(age);
}
}
Users类
package com.example.test.bean;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "users")
public class Users {
@Id
@GeneratedValue
private String username;
private String pass;
public Users() {
}
public String getUsername(){return username;}
public void setUsername(String username){this.username = username;}
public String getPass(){return pass;}
public void setPass(String pass){this.pass = pass;}
}
mapper层
数据库进行数据持久化操作
@Mapper注解:把mapper交给spring管理
PersonMapper类
package com.example.test.mapper;
import com.example.test.bean.Person;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface PersonMapper {
/**
* 全部用户查询
* @return
*/
@Select("SELECT username,name,age,teleno FROM person")
List<Person> findAll();
/**
* 新增用户,提供四个值
*/
@Insert("INSERT INTO person(username,name,age,teleno)VALUES(#{username}, #{name}, #{age}, #{teleno})")
void addPersonFourParams(Person person);
/**
* 新增用户,提供三个值,age
*/
@Insert("INSERT INTO person(username,name,age)VALUES(#{username}, #{name}, #{age})")
void addPersonThreeParamsWithAge(Person person);
/**
* 新增用户,提供三个值,teleno
*/
@Insert("INSERT INTO person(username,name,teleno)VALUES(#{username}, #{name}, #{teleno})")
void addPersonThreeParamsWithTeleno(Person person);
/**
* 新增用户,提供两个值
*/
@Insert("INSERT INTO person(username,name)VALUES(#{username}, #{name})")
void addPersonTwoParams(Person person);
/**
* 修改用户
*/
@Update("UPDATE person SET username=#{username}, name=#{name}, age=#{age}, teleno=#{teleno} WHERE username=#{username}")
void updatePerson(Person person);
/**
* 删除用户
*/
@Delete("DELETE FROM person WHERE username=#{username}")
void deletePerson(String username);
@Select("SELECT username,name,age,teleno FROM person WHERE username=#{username}")
Person findByUsername(@Param("username")String username);
}
UsersMapper类
package com.example.test.mapper;
import com.example.test.bean.Users;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface UsersMapper {
/**
* 全部用户查询
* @return List
*/
@Select("SELECT username,pass FROM users")
List<Users> findAll();
/**
* 新增用户,提供四个值
*/
@Insert("INSERT INTO users(username,pass)VALUES(#{username}, #{pass})")
void addUsers(Users users);
/**
* 修改用户
*/
@Update("UPDATE users SET username=#{username}, pass=#{pass} WHERE username=#{username}")
void updateUsers(Users users);
/**
* 删除用户
*/
@Delete("DELETE FROM users WHERE username=#{username}")
void deleteUsers(String username);
@Select("SELECT username,pass FROM users WHERE username=#{username}")
Users findByUsername(@Param("username")String username);
}
service层
服务层,将操作封装起来
@Autowired注解:它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作
@Transactional注解:我们在需要对一个service方法添加事务时,加上这个注解,如果发生unchecked exception,就会发生rollback
PersonService类
package com.example.test.service;
import com.example.test.bean.Person;
import com.example.test.bean.Users;
import com.example.test.mapper.PersonMapper;
import com.example.test.mapper.UsersMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class PersonService {
@Autowired(required = false)
private PersonMapper personMapper;
@Autowired(required = false)
private UsersService usersService;
/**
* 获取全部的用户
*
* @return List
*/
public List<Person> findAll() {
return personMapper.findAll();
}
/**
* 添加或者更新用户,添加的时候还会在users表中添加
*
* @param person
*
*/
@Transactional
public void addOrUpdatePerson(Person person) {
Person p;
p = personMapper.findByUsername(person.getUsername());
if (p == null){
// person表中没有这个username,在person和users表中都执行添加
System.out.println("数据库:Person表新增数据");
System.out.printf("username: %s\t",person.getUsername());
System.out.printf("name: %s\t",person.getName());
if (person.getAge() == -1){
System.out.print("age: \t");
}else{
System.out.printf("age: %d\t",person.getAge());
}
System.out.printf("teleno: %s\n",person.getTeleno());
// 针对不同数据调用不同函数
if (!person.getTeleno().equals("") && person.getAge() != -1){
// 四个值都有
personMapper.addPersonFourParams(person);
}
else if(!person.getTeleno().equals("") && person.getAge() == -1){
personMapper.addPersonThreeParamsWithTeleno(person);
}
else if(person.getTeleno().equals("") && person.getAge() != -1){
personMapper.addPersonThreeParamsWithAge(person);
}
else{
personMapper.addPersonTwoParams(person);
}
//添加的时候需要在users表中也添加数据,下面的修改则不需要,耦合问题
System.out.println("数据库:Users表新增数据");
System.out.printf("username: %s\t",person.getUsername());
System.out.println("pass: 88888888");
Users users = new Users();
users.setPass("88888888");
users.setUsername(person.getUsername());
usersService.addUsers(users);
}
else{
// person表中有这个username,执行修改
System.out.println("数据库:Person表修改数据");
System.out.printf("username: %s\t",person.getUsername());
System.out.printf("name: %s\t",person.getName());
if (person.getAge() == -1){
System.out.print("age: \t");
}else{
System.out.printf("age: %d\t",person.getAge());
}
System.out.printf("teleno: %s\n",person.getTeleno());
personMapper.updatePerson(person);
}
}
/**
* 修改用户
*
* @param person
*/
@Transactional
public void updatePerson(Person person) {
personMapper.updatePerson(person);
}
/**
* 删除用户
*
* @param username
*/
@Transactional
public void deletePerson(String username) {
personMapper.deletePerson(username);
}
/**
* 查询指定用户
*
* @param username
* @return
*/
public Person findByUsername(String username) {
return personMapper.findByUsername(username);
}
}
UsersService类
package com.example.test.service;
import com.example.test.bean.Users;
import com.example.test.mapper.UsersMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class UsersService {
@Autowired(required = false)
private UsersMapper usersMapper;
@Autowired(required = false)
private PersonService personService;
/**
* 获取全部的用户
*
* @return
*/
public List<Users> findAll() {
return usersMapper.findAll();
}
/**
* 添加用户
*
* @param users
*/
@Transactional
public void addUsers(Users users) {
usersMapper.addUsers(users);
}
/**
* 修改用户
*
* @param users
*/
@Transactional
public void updateUsers(Users users) {
usersMapper.updateUsers(users);
}
/**
* 在user和person中删除数据
*
* @param username
*/
@Transactional
public void deleteUsers(String username) {
System.out.println("数据库:users表删除数据 "+username);
usersMapper.deleteUsers(username);
System.out.println("数据库:person表删除数据 "+username);
personService.deletePerson(username);
}
/**
* 查询指定用户
*
* @param username
* @return
*/
public Users findByUsername(String username) {
return usersMapper.findByUsername(username);
}
}
controller层
控制层,处理访问请求
@RequestMapping注解:是一个用来处理请求地址映射的注解,可用于类或方法上。
WebController类
package com.example.test.controller;
import com.example.test.service.PersonService;
import com.example.test.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.example.test.bean.Person;
import com.example.test.bean.Users;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller
public class WebController {
@Autowired
private PersonService personService;
@Autowired
private UsersService usersService;
@RequestMapping(value = "/index")
public String startPage() {
return "index";
}
@RequestMapping(value = "/databaseDetail")
public String queryDatabase(Model model){
List<Person> databasePerson = personService.findAll();
List<Users> databaseUsers = usersService.findAll();
Map<String,List> database = new HashMap<>();
database.put("person",databasePerson);
database.put("users",databaseUsers);
model.addAttribute("data", database);
return "database";
}
}
PersonController类
package com.example.test.controller;
import com.example.test.bean.Person;
import com.example.test.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
import java.util.Map;
@Controller
public class PersonController {
@Autowired
private PersonService personService;
@RequestMapping("/listPerson")
public String listUser(Model model) {
List<Person> persons = personService.findAll();
model.addAttribute("persons", persons);
return "listPerson";
}
@RequestMapping("/toAdd")
public String toAdd() {
return "/addPersonFourParams";
}
// 这次实验主要用这个函数
@RequestMapping(value = "/addOrUpdatePerson")
public String add(Person person, Map<String,Object> map) {
personService.addOrUpdatePerson(person);
map.put("person",person);
return "addOperationResult";
//return "redirect:/listPerson";
}
@RequestMapping("/toUpdate")
public String toUpdate(Model model, String username) {
Person person = personService.findByUsername(username);
model.addAttribute("person", person);
return "/updatePerson";
}
@RequestMapping("/update")
public String updatePerson(Person person) {
personService.updatePerson(person);
return "redirect:/listPerson";
}
@RequestMapping("/delete")
public String deletePerson(String username) {
personService.deletePerson(username);
return "redirect:/listPerson";
}
}
UserController类
package com.example.test.controller;
import com.example.test.bean.Users;
import com.example.test.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Map;
@Controller
public class UserController {
@Autowired
private UsersService usersService;
@RequestMapping("/deletePersonAndUser")
public String delete(Users users, Map<String,Object> map) {
map.put("user",users);
usersService.deleteUsers(users.getUsername());
return "deleteOperationResult";
}
}
resources 文件夹下
各文件放置位置如代码结构描述
static静态文件
allCSS.css
这里说明一下:
1.我css真的写的不好。。前端没太学完有点赶,有时间一定认真学
2.我把好多样式写到html的style属性里了,偷懒了。。
#link{
text-align: center;
}
showDatabase.js
function showDatabase(_data, databaseName, tableHeader) {
const data = _data
const table = document.createElement('table');
const h1 = document.createElement('h1')
h1.appendChild(document.createTextNode("数据库" + databaseName + "信息"))
h1.align = "center"
table.border = "1"
table.align = "center"
const tableBody = document.createElement('tbody')
table.appendChild(tableBody)
tableBody.insertRow(0)
//const tableHeader = ["username", "name", "age", "teleno"]
const tableHeaderLength = tableHeader.length
for (let i = 0; i < tableHeaderLength; i++) {
tableBody.rows[0].insertCell(i)
tableBody.rows[0].cells[i].appendChild(document.createTextNode(tableHeader[i]))
}
const dataLength = data.length
for (let row = 1; row <= dataLength; row++) {
tableBody.insertRow(row)
for (let column = 0; column < tableHeaderLength; column++) {
tableBody.rows[row].insertCell(column)
switch (column) {
case 0:
tableBody.rows[row].cells[column].appendChild(document.createTextNode(data[row - 1].username))
break
case 1:
if (tableHeaderLength === 4) {
// 代表是person,需要用name
//console.log(11)
//console.log(data[row - 1].name)
tableBody.rows[row].cells[column].appendChild(document.createTextNode(data[row - 1].name))
} else {
// 代表是user,需要用pass
//console.log(22)
//console.log(data[row - 1].pass)
tableBody.rows[row].cells[column].appendChild(document.createTextNode(data[row - 1].pass))
}
break
case 2:
tableBody.rows[row].cells[column].appendChild(document.createTextNode(data[row - 1].age))
break
case 3:
tableBody.rows[row].cells[column].appendChild(document.createTextNode(data[row - 1].teleno))
break
}
}
}
document.body.appendChild(h1)
document.body.appendChild(table)
}
function getMapping() {
getPersonMapping()
getUsersMapping()
}
templates模板文件
index.html
初始页面
加了点js代码实现:提交确认、判断电话号是否正确、判断username和name是否超过最大长度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>人员管理</title>
</head>
<body>
<form align="center" action="/addOrUpdatePerson" method="post" onsubmit="return addCheck()">
<table border="1" align="center" width="600px">
<caption>数据库表person插入信息:(如果username已经存在, 执行更新数据,不存在则同时在users中插入新数据,默认密码888888</caption><!-- 表头 -->
<tr>
<td>username</td>
<td><input type="text" name="username" id="inputUsername"></td>
</tr>
<tr>
<td>name</td>
<td><input type="text" name="name" id="inputName"></td>
</tr>
<tr>
<td>age</td>
<td><input type="number" name="age" min="0" max="150" id="inputAge"></td>
</tr>
<tr>
<td>teleno</td>
<td><input type="tel" name="teleno" id="inputTeleno"></td>
</tr>
</table>
<input style="margin: 10px 0 10px 0" type="submit" value="插入/修改">
</form>
<form align="center" action="/deletePersonAndUser" method="post" onsubmit="return deleteCheck()">
<table border="1" align="center" width="600px">
<caption>数据库表依据username删除信息:</caption><!-- 表头 -->
<tr>
<td>username</td>
<td><input type="text" name="username"></td>
</tr>
</table>
<input style="margin-top: 10px" type="submit" value="删除">
</form>
<script type="text/javascript">
function deleteCheck(){
return confirm("确认删除?");
}
function addCheck(){
var teleReg = /^[1][3,4,5,7,8,9][0-9]{9}$/;
const checkTeleno = teleReg.test(document.getElementById("inputTeleno").value)
const usernameCheck = (document.getElementById("inputUsername").value.length <= 10)
const nameCheck = (document.getElementById("inputName").value.length <= 20)
if(!checkTeleno){
alert("手机号不符合规范")
return false
}
if(!usernameCheck){
alert("username太长")
return false
}
if(!nameCheck){
alert("name太长")
return false
}
const check = confirm("确认新增/修改?");
return (check && checkTeleno && usernameCheck && nameCheck)
}
</script>
</body>
</html>
addOperationResult.html
新增的结果页面
<!DOCTYPE html>
<html xmlns:th="www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>数据库操作结果</title>
<!--script th:inline="javascript">
/*function showMessage() {
document.getElementById("person").innerHTML = "Thymeleaf String by JS: " + [[${username}]];
}*/
</script-->
</head>
<body>
<div align="center">
<text style="size: 20px;font-weight: bolder" >操作结果</text>
<div>
<span>username: </span>
<text th:text="${person.username}"></text>
<!--p id="username"></p-->
</div>
<div>
<span>name: </span>
<text th:text="${person.name}"></text>
</div>
<div>
<span>age: </span>
<text th:text="${person.age}"></text>
</div>
<div>
<span>teleno: </span>
<text th:text="${person.teleno}"></text>
</div>
<a href="/databaseDetail">查看数据库数据</a>
</div>
</body>
</html>
deleteOperationResult.html
删除的结果页面
<!DOCTYPE html>
<html xmlns:th="www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>数据库操作结果</title>
<!--script th:inline="javascript">
/*function showMessage() {
document.getElementById("person").innerHTML = "Thymeleaf String by JS: " + [[${username}]];
}*/
</script-->
</head>
<body>
<div align="center">
<text style="size: 20px;font-weight: bolder" >操作结果</text>
<div>
<span>username: </span>
<text th:text="${user.username}"></text>
<!--p id="username"></p-->
</div>
<a href="/databaseDetail">查看数据库数据</a>
</div>
</body>
</html>
database.html
查看数据库的数据的页面,这个文件中引用了上文提到的JS 和 CSS 文件
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>数据库详情</title>
</head>
<link rel="stylesheet" type="text/css" href="css/allCSS.css">
<script src="js/showDatabase.js"></script>
<body onload="getMapping()">
<script th:inline="javascript">
function getPersonMapping() {
const tableHeader = ["username", "name", "age", "teleno"]
showDatabase([[${data.person}]], "person", tableHeader)
}
//document.getElementById("demo").innerHTML = getPersonMapping();
function getUsersMapping() {
const tableHeader = ["username", "pass"]
showDatabase([[${data.users}]], "users", tableHeader)
}
</script>
<div id="link">
<a th:href="@{/index}">返回主页面</a>
</div>
</body>
</html>
application.yml
配置文件
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
pom.xml 依赖文件
依赖文件
<?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.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</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-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.37</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.项目github地址
实验结果截图
新增数据
新增结果
查看数据库
删除数据
删除结果
查看数据库
总结
一些问题
- 因为初学,这个代码的问题可能有点多,但是结果还行。。
- java后端:
- 为了写题目有些地方写的太具体,不够抽象
- 有很多没有用到的接口,但是可能以后会用到
- 代码命名不是很规范
- 还有很多自己没有意识到的问题
- 前端:
- 显示数据库数据的那个表我使用js动态生成的,我也不知道这样对不对,有没有很好的方法
- html不是很熟练(只会写微信小程序用的wxml,好家伙换成正版还不会用了,emm)
- css水平有点emm,很多样式写到了style属性里(懒了)
- 没有用框架
没时间做好看一点。。有了再传上来- 还有很多自己没有意识到的问题
- 框架学的不完善,不透彻,只摸到皮毛,可能有诸多错误或者不合适的地方
好像忘了加热启动了,我等会看看加上
运行不起来可能存在的错误
- 数据库连接失败检查自己的驱动和数据库是否对应,可参考前面连接数据库的部分(有时候可能需要在依赖文件pom.xml文件中加入数据库版本,我就加了。。)
- 依赖文件缺失,仿照我的写就ok,有啥问题搜一搜基本都能解决
- 网页不显示,各种404/500错误:首先检查文件的结构,然后检查依赖,然后从controller开始层层排查错误,bug总是可以de出来的!
- 待评论区补充,有了再写