目录
- 学员管理系统(服务器—客户端模式)
- 1. 项目演示
- a. 打开项目
- b. 运行项目
- 2. 项目说明
- a. 所采用的知识点
- b. 业务交互模式图示
- 3. 案例代码
- a. 客户端
- i. 创建实体类 Student
- ii. 创建主类 MainApp
- b. 服务器端
- i. 创建实体类 Student
- ii. 创建服务器端线程类 ServerThread
- iii. 创建服务器端主类 MainApp:
- iv. 服务器端对象操作类 StudentDAO
- c. 测试类
学员管理系统(服务器—客户端模式)
1. 项目演示
a. 打开项目
- 将演示程序 Student_Net 复制到本地磁盘;
- 启动 IDEA,选择 File >> open,在 “打开对话框” 中选择这个项目目录。目录结构如下图:

pojo:简单的 Java 对象(Plain Old Java Object);
DAO:数据访问对象(Data Access Object)。
b. 运行项目
- 运行服务器端:Student_Server/com/itheima/server/MainApp,服务器使用端口 8888;

- 运行客户端:Student_Client/com/itheima/client/MainApp;

- 执行添加功能;


- 执行修改功能;


- 执行删除功能;


- 执行查询功能;

- 退出系统;

注:文件保存在
%项目目录%\out\production\Student_Server\student.txt。
2. 项目说明
a. 所采用的知识点
- 本系统采用了以下几个核心知识点:
(1)IO流技术
(2)网络编程技术
(3)序列化
(4)多线程
b. 业务交互模式图示

- 说明:
(1)客户端和服务器端采用 TCP 连接;
(2)数据保存在服务器端;
(3)客户端增删改查发送数据格式:- 添加:"[1]数据"。例如 “[1]张三,男,22”,没有提供 id 字段,由服务器端在写入数据前自动添加;
- 根据 id 查询一条数据:"[2]id"。例如 “[2]1” 的意思是查询 id 为 1 的学员信息;
- 修改一条数据:"[3]新数据"。例如 “[3]1,张三2,女,19” 的意思是将 id = 1 的学员改为后面的新数据;
- 查询所有数据:"[4]"。例如 “[4]”,后面不用带任何数据;
- 删除一条数据:"[5]id"。例如 “[5]1” 的意思是删除 id 为 1 的记录。
3. 案例代码
a. 客户端
i. 创建实体类 Student
package com.regino.pojo;import java.io.Serializable;public class Student implements Serializable {private int id;private String name;private String sex;private int age;public Student() {}public Student(int id, String name, String sex, int age) {this.id = id;this.name = name;this.sex = sex;this.age = age;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", sex='" + sex + '\'' +", age=" + age +'}';}
}
ii. 创建主类 MainApp
package com.regino.client;import com.regino.pojo.Student;import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Scanner;/*学员管理系统(C/S版)——客户端一. 业务功能:1.添加学员2.修改学员3.删除学员4.查询学员二. 代码流程说明:1.本客户端与服务器端实现"短连接"——每个功能当需要与服务器连接时,才建立连接,功能完毕,连接立即断开;*/
public class MainApp {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (true) {System.out.println("***************************************************");System.out.println("*\t1.添加学员\t2.修改学员\t3.删除学员\t4.查询学员\t5.退出\t*");System.out.println("***************************************************");int op = sc.nextInt();switch (op) {case 1://添加addStudent(sc);break;case 2://修改updateStudent(sc);break;case 3://删除deleteStudent(sc);break;case 4://查询findStudent(sc);break;case 5://退出System.out.println("谢谢使用,再见!");System.exit(0);}}}//1.添加学员private static void addStudent(Scanner sc) {//1.接收用户数据System.out.println("请输入学员信息:");System.out.println("姓名:");String name = sc.next();System.out.println("性別:");String sex = sc.next();System.out.println("年龄:");int age = sc.nextInt();//2.获取连接后的输出流Socket socket = getSocket();if (socket == null) {System.out.println("【错误】无法连接服务器!");return;}//3.创建输出流try (OutputStream netOut = socket.getOutputStream();InputStream netIn = socket.getInputStream();) {//发送数据netOut.write(("[1]" + name + "," + sex + "," + age).getBytes());//接收反馈int b = netIn.read();//4.关闭连接socket.close();//判断反馈if (b == 0) {//5.完毕System.out.println("【成功】数据已保存!");} else {System.out.println("【失败】数据保存失败,请重试!");}return;} catch (IOException e) {System.out.println("【错误】保存失败,请重试!");return;}}//2.修改学员private static void updateStudent(Scanner sc) {//1.接收idSystem.out.println("请输入要修改的学员ID:");int id = sc.nextInt();//2.获取连接Socket socket = getSocket();//3.发送"查询"请求try {OutputStream netOut = socket.getOutputStream();InputStream netIn = socket.getInputStream();//标记:"2"根据ID查询一条记录netOut.write(("[2]" + id).getBytes());//接收结果ObjectInputStream objIn = new ObjectInputStream(netIn);Object obj = objIn.readObject();objIn.close();if (obj == null) {System.out.println("【失败】无查询结果!");return;}if (!(obj instanceof Student)) {System.out.println("【失败】返回数据错误,请重试!");return;}//关闭此次连接socket.close();//向下转型Student stu = (Student) obj;System.out.println("【查询结果】");printStudent(stu);//打印//接收新数据System.out.println("请输入新姓名(保留原值请输入0):");String newName = sc.next();System.out.println("请输入新性别(保留原值请输入0):");String newSex = sc.next();System.out.println("请输入新年龄(保留原值请输入0):");int newAge = sc.nextInt();if (!"0".equals(newName)) {stu.setName(newName);}if (!"0".equals(newSex)) {stu.setSex(newSex);}if (newAge != 0) {stu.setAge(newAge);}//再次连接socket = getSocket();//发送修改数据,格式:[3]....netOut = socket.getOutputStream();netOut.write(("[3]" + stu.getId() + "," +stu.getName() + "," +stu.getSex() + "," +stu.getAge()).getBytes());//接收反馈netIn = socket.getInputStream();int b = netIn.read();if (b == 0) {System.out.println("【成功】数据已修改!");} else {System.out.println("【失败】数据修改失败,请重试!");}return;} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}//3.删除学员private static void deleteStudent(Scanner sc) {System.out.println("请输入要删除的学员ID:");int id = sc.nextInt();//2.获取连接Socket socket = getSocket();//3.发送"查询"请求try {OutputStream netOut = socket.getOutputStream();InputStream netIn = socket.getInputStream();//标记:"2"根据ID查询一条记录netOut.write(("[2]" + id).getBytes());ObjectInputStream objIn = new ObjectInputStream(netIn);//接收结果Object obj = objIn.readObject();if (obj == null) {System.out.println("【失败】无查询结果!");return;}if (!(obj instanceof Student)) {System.out.println("【失败】返回数据错误,请重试!");return;}//向下转型Student stu = (Student) obj;System.out.println("【查询结果】");printStudent(stu);//打印//关闭连接socket.close();//确认删除System.out.println("【确认】你确定删除这条记录吗?(y/n):");String op = sc.next();if (!"y".equals(op)) {System.out.println("【取消】操作被取消!");return;}//再次连接socket = getSocket();//发送删除数据,格式:[5]id值....netOut = socket.getOutputStream();netOut.write(("[5]" + stu.getId()).getBytes());//接收反馈netIn = socket.getInputStream();int b = netIn.read();if (b == 0) {System.out.println("【成功】数据已删除!");} else {System.out.println("【失败】数据删除失败,请重试!");}return;} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}//4.查询学员private static void findStudent(Scanner sc) {////1.获取连接Socket socket = getSocket();try {OutputStream netOut = socket.getOutputStream();//2.发送请求,格式:[4]netOut.write(("[4]").getBytes());ObjectInputStream objIn = new ObjectInputStream(socket.getInputStream());//3.接收结果,一个序列化的ArrayList<Student>Object o = objIn.readObject();if (o == null) {System.out.println("【失败】查询失败,请重试!");return;}if (!(o instanceof ArrayList)) {System.out.println("【错误】返回数据错误,请重试!");return;}System.out.println("【查询结果】");ArrayList<Student> list = (ArrayList<Student>) o;printStudentList(list);//关闭连接socket.close();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}//连接服务器private static Socket getSocket() {String ip = "127.0.0.1";int port = 8888;try {Socket socket = new Socket(ip, port);return socket;} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return null;}//打印ArrayList<Student>的方法public static void printStudentList(ArrayList<Student> stuList) {System.out.println("--------------------------------------------------");System.out.println("编号\t\t姓名\t\t\t性别\t\t年龄");for (int i = 0; i < stuList.size(); i++) {Student p = stuList.get(i);System.out.println(p.getId() + "\t\t" +p.getName() + "\t\t\t" +p.getSex() + "\t\t" +p.getAge());}System.out.println("--------------------------------------------------");}//打印Person的方法public static void printStudent(Student stu) {System.out.println("--------------------------------------------------");System.out.println("编号\t\t姓名\t\t性别\t\t\t年龄");System.out.println(stu.getId() + "\t\t" +stu.getName() + "\t\t\t" +stu.getSex() + "\t\t" +stu.getAge());System.out.println("--------------------------------------------------");}
}
b. 服务器端
i. 创建实体类 Student
package com.regino.pojo;import java.io.Serializable;public class Student implements Serializable {private int id;private String name;private String sex;private int age;public Student() {}public Student(int id, String name, String sex, int age) {this.id = id;this.name = name;this.sex = sex;this.age = age;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", sex='" + sex + '\'' +", age=" + age +'}';}
}
ii. 创建服务器端线程类 ServerThread
package com.regino.server;import com.regino.pojo.Student;import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;/*服务器端线程:一.业务功能:1).接收客户端增、删、改、查的请求;2).调用StudentDAO处理增、删、改、查的业务;3).为客户端返回处理结果*/
public class ServerThread extends Thread {private Socket socket;//与客户端连接的Socket对象public ServerThread(Socket socket) {this.socket = socket;}@Overridepublic void run() {try (InputStream netIn = this.socket.getInputStream();OutputStream netOut = this.socket.getOutputStream();) {//接收客户端数据byte[] bytes = new byte[1024];int len = netIn.read(bytes);//只接收一次,最多1KString msg = new String(bytes, 0, len);if (msg.charAt(0) != '[' ||msg.indexOf("]") == -1) {//关闭连接System.out.println("未知数据格式,线程结束!");socket.close();return;}//解析标记位String flag = msg.substring(0 + 1, msg.indexOf("]"));//判断switch (flag) {case "1"://添加addStudent(msg);break;case "2"://根据id查询一条System.out.println("查询一条");findById(msg);break;case "3"://修改一条updateStudent(msg);break;case "4"://查询所有findAll(msg);break;case "5"://删除一条deleteById(msg);break;default:System.out.println("未知数据格式!");socket.close();break;}} catch (IOException e) {e.printStackTrace();}}//删除一条private void deleteById(String msg) {msg = msg.substring(msg.indexOf("]") + 1);int id = Integer.parseInt(msg);boolean b = StudentDAO.deleteById(id);try {OutputStream netOut = socket.getOutputStream();if (b) {netOut.write(0);} else {netOut.write(1);}socket.close();} catch (IOException e) {e.printStackTrace();}}private void findAll(String msg) {ArrayList<Student> all = StudentDAO.findAll();//直接序列化集合给客户端try {ObjectOutputStream objOut = new ObjectOutputStream(socket.getOutputStream());objOut.writeObject(all);//关闭连接socket.close();} catch (IOException e) {e.printStackTrace();}}//处理根据ID查询private void findById(String msg) {msg = msg.substring(msg.indexOf("]") + 1);int id = Integer.parseInt(msg);Student stu = StudentDAO.findById(id);try {OutputStream netOut = socket.getOutputStream();//直接序列化给客户端ObjectOutputStream objOut = new ObjectOutputStream(socket.getOutputStream());System.out.println("序列化");objOut.writeObject(stu);System.out.println("序列化完毕");//关闭连接socket.close();} catch (IOException e) {e.printStackTrace();}}//处理修改private void updateStudent(String msg) {msg = msg.substring(msg.indexOf("]") + 1);//"1,张三,男,22"String[] arr = msg.split(",");Student stu = new Student();stu.setId(Integer.parseInt(arr[0]));stu.setName(arr[1]);stu.setSex(arr[2]);stu.setAge(Integer.parseInt(arr[3]));boolean b = StudentDAO.updateStudent(stu);try (OutputStream netOut = socket.getOutputStream()) {if (b) {netOut.write(0);} else {netOut.write(1);}socket.close();} catch (IOException e) {e.printStackTrace();}}//处理添加private void addStudent(String msg) {msg = msg.substring(msg.indexOf("]") + 1);//"张三,男,22"String[] arr = msg.split(",");Student stu = new Student();stu.setName(arr[0]);stu.setSex(arr[1]);stu.setAge(Integer.parseInt(arr[2]));boolean b = StudentDAO.addStudent(stu);//返回给客户端处理结果try {OutputStream netOut = socket.getOutputStream();if (b) {netOut.write(0);} else {netOut.write(1);}socket.close();} catch (IOException e) {e.printStackTrace();}}
}
iii. 创建服务器端主类 MainApp:
package com.regino.server;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;/*学员管理系统(C/S版)——服务器端一.业务功能:1).接收客户端连接;2).开启线程(见ServerThread类)*/
public class MainApp {public static void main(String[] args) {try (ServerSocket server = new ServerSocket(8888)) {while (true) {System.out.println("等待客户端连接...");Socket socket = server.accept();//开启线程new ServerThread(socket).start();}} catch (IOException e) {e.printStackTrace();}}
}
iv. 服务器端对象操作类 StudentDAO
package com.regino.server;import com.regino.pojo.Student;import java.io.*;
import java.util.ArrayList;public class StudentDAO {// 相对路径从src开始private static File destPath = new File("Student_Server\\src\\com\\regino\\student.txt");private static File tempPath = new File("Student_Server\\src\\com\\regino\\temp.txt");public static synchronized void rewrite() throws IOException {BufferedReader br = new BufferedReader(new FileReader(tempPath));BufferedWriter bw = new BufferedWriter(new FileWriter(destPath));// 进行文件读取String row = null;while ((row = br.readLine()) != null) {bw.write(row);bw.flush();bw.newLine();}// 释放资源bw.close();br.close();// 删除temp文件tempPath.delete();}public static synchronized boolean deleteById(int id) {try {// 判断文本文件是否为空if (new FileInputStream(destPath).available() == 0) {return false;}// 修改后写入temp.txtBufferedReader br = new BufferedReader(new FileReader(destPath));BufferedWriter bw = new BufferedWriter(new FileWriter(tempPath));// 重新排idint newId = -2;// 进行文件读取String row = null;while ((row = br.readLine()) != null) {newId++;String[] rowArray = row.split("\t");// 跳过首行if (rowArray[0].equals("ID")) {bw.write(row);bw.flush();bw.newLine();continue;}// 跳过匹配IDif (id == Integer.valueOf(rowArray[0])) {newId --;continue;}// 覆盖其他的行bw.write(newId + "\t" + rowArray[1] + "\t" + rowArray[2] + "\t" + rowArray[3]);bw.flush();bw.newLine();}// 释放资源bw.close();br.close();// 从temp.txt写回来rewrite();} catch (IOException e) {e.printStackTrace();return false;}return true;}public static synchronized ArrayList<Student> findAll() {ArrayList<Student> arr = new ArrayList<Student>();try {// 判断文本文件是否为空if (new FileInputStream(destPath).available() == 0) {return arr;}BufferedReader br = new BufferedReader(new FileReader(destPath));// 进行文件读取String row = null;while ((row = br.readLine()) != null) {String[] rowArray = row.split("\t");String id = rowArray[0];String name = rowArray[1];String sex = rowArray[2];String age = rowArray[3];// 跳过首行if (id.equals("ID")) {continue;}arr.add(new Student(Integer.valueOf(id), name, sex, Integer.valueOf(age)));}// 释放资源br.close();} catch (IOException e) {e.printStackTrace();}return arr;}public static synchronized Student findById(int id) {Student s = new Student();try {// 判断文本文件是否为空if (new FileInputStream(destPath).available() == 0) {return s;}BufferedReader br = new BufferedReader(new FileReader(destPath));// 进行文件读取String row = null;while ((row = br.readLine()) != null) {String[] rowArray = row.split("\t");// 跳过首行if (rowArray[0].equals("ID")) {continue;}// 匹配IDif (id == Integer.valueOf(rowArray[0])) {s.setId(Integer.valueOf(rowArray[0]));s.setName(rowArray[1]);s.setSex(rowArray[2]);s.setAge(Integer.valueOf(rowArray[3]));}}// 释放资源br.close();} catch (IOException e) {e.printStackTrace();}return s;}public static synchronized boolean updateStudent(Student stu) {try {// 判断文本文件是否为空if (new FileInputStream(destPath).available() == 0) {return false;}// 修改后写入temp.txtBufferedReader br = new BufferedReader(new FileReader(destPath));BufferedWriter bw = new BufferedWriter(new FileWriter(tempPath));// 进行文件读取String row = null;while ((row = br.readLine()) != null) {String[] rowArray = row.split("\t");// 跳过首行if (rowArray[0].equals("ID")) {bw.write(row);bw.flush();bw.newLine();continue;}// 替换ID匹配的行if (stu.getId() == Integer.valueOf(rowArray[0])) {bw.write(stu.getId() + "\t" +stu.getName() + "\t" +stu.getSex() + "\t" +stu.getAge());bw.flush();bw.newLine();continue;}// 直接覆盖其他的行bw.write(row);bw.flush();bw.newLine();}// 释放资源bw.close();br.close();// 从temp.txt写回来rewrite();} catch (IOException e) {e.printStackTrace();return false;}return true;}public static synchronized boolean addStudent(Student stu) {try {// 获取集合中的每一个Student对象BufferedWriter bw = new BufferedWriter(new FileWriter(destPath, true));// 判断文本文件是否为空if (new FileInputStream(destPath).available() == 0) {bw.write("ID\t");bw.write("学生姓名\t");bw.write("学生性别\t");bw.write("学生年龄\t");bw.newLine();bw.flush();}// 找到相应的idstu.setId(findAll().size());// 把Student信息存储到文本文件中int id = stu.getId();String name = stu.getName();String sex = stu.getSex();int age = stu.getAge();bw.write(id + "\t");bw.write(name + "\t");bw.write(sex + "\t");bw.write(age + "\t");bw.newLine();bw.flush();//释放资源bw.close();} catch (IOException e) {e.printStackTrace();return false;}return true;}
}
- 优化:新建方法 writeAll(),并将所有的写入文件操作放到此方法;将所有读取文件的方法放到 readAll() 方法中,并取消 synchronized 标识;其他方法在调用 readAll() 方法后将数据放到 ArrayList 中,直接操作 ArrayList。这样可以提高运行效率,方便以后维护。
public class StudentDao {//将集合中所有学生对象,写入到文件中public static synchronized void writeAll(ArrayList<Student> stuList) {try (FileWriter out = new FileWriter("student.txt")) {for (Student stu : stuList) {//格式: id,姓名,性别,年龄out.write(stu.getId() + "," + stu.getName() + "," + stu.getSex() + "," + stu.getAge());//换行out.write("\r\n");}} catch (IOException e) {e.printStackTrace();}}//从文件中读取所有学生的信息,返回学生集合public static ArrayList<Student> readAll() {ArrayList<Student> stuList = new ArrayList<>();//1.创建File对象File file = new File("student.txt");if (!file.exists()) {try {//2.如果不存在,则创建,否则读取会抛异常file.createNewFile();} catch (IOException e) {e.printStackTrace();}}//3.读数据,一次一行 格式: id,姓名,性别,年龄try (BufferedReader bufIn = new BufferedReader(new FileReader("student.txt"))) {String line = null;while ((line = bufIn.readLine()) != null) {//4.一行切割成一个数组,[id,姓名,性别,年龄]String[] rowArray = line.split(",");//5.创建学生对象,封装数据Student stu = new Student();stu.setId(Integer.parseInt(rowArray[0]));stu.setName(rowArray[1]);stu.setSex(rowArray[2]);stu.setAge(Integer.parseInt(rowArray[3]));//6.添加到集合中stuList.add(stu);}} catch (IOException e) {return null;}//7.返回整个集合return stuList;}//添加一个学生,返回boolean代表是否添加成功public static synchronized boolean addStudent(Student student) {//1.先读取所有学生ArrayList<Student> stuList = readAll();if (stuList == null) {//说明读取文件出错return false;}//2.获取最后一个学生的id,加1后作为新学生的idif (stuList.size() != 0) {student.setId(stuList.get(stuList.size() - 1).getId() + 1);//取最后一个对象的id + 1} else {//3.如果没有学生,说明是第一个,则id设置为1student.setId(1);//第一次添加,文件中没有内容}//4.添加到集合中stuList.add(student);//5.把集合重写写入到文件中writeAll(stuList);//6.返回添加成功return true;}//根据id删除一个学生,返回boolean代表是否删除成功public static synchronized boolean deleteById(int id) {//1.先读取所有学生ArrayList<Student> stuList = readAll();if (stuList == null) {//说明读取文件出错return false;}//2.遍历集合for (int i = 0; i < stuList.size(); i++) {Student stu = stuList.get(i);//3.判断学生的id是否和要删除的id相等if (stu.getId() == id) {//4.从集合中删除学生stuList.remove(i);//5.重写写入到文件中writeAll(stuList);//6.返回成功return true;}}//7.如果没找到学生返回失败return false;}//修改学生,返回boolean代表是否修改成功public static synchronized boolean updateStudent(Student student) {//1.先读取所有学生ArrayList<Student> stuList = readAll();if (stuList == null) {//说明读取文件出错return false;}System.out.println("修改的数据:" + student);//2.遍历集合for (int i = 0; i < stuList.size(); i++) {Student stu = stuList.get(i);//3.判断哪个学生id和要修改的学生id相同if (stu.getId() == student.getId()) {//4.将学生改为新的学生stuList.set(i, student);//5.重写将集合写入到文集中writeAll(stuList);//写回文件//6.返回成功return true;}}//7.返回失败return false;//没找到}//根据id查询学生,返回查询到的学生public static Student findById(int id) {//1.先读取所有学生ArrayList<Student> stuList = readAll();if (stuList == null) {//说明读取文件出错return null;}//2.遍历集合for (int i = 0; i < stuList.size(); i++) {Student stu = stuList.get(i);//3.比较idif (stu.getId() == id) {//4.找到返回学生对象return stu;}}//5.找不到返回nullreturn null;}
}
c. 测试类
package com.regino.server;import com.regino.pojo.Student;
import com.regino.server.StudentDAO;
import org.junit.Test;public class TestStudentDAO {@Testpublic void add() {System.out.println(StudentDAO.addStudent(new Student(0, "测试1", "测试2", 10)));System.out.println(StudentDAO.addStudent(new Student(1, "测试1", "测试2", 10)));}@Testpublic void findAll() {System.out.println(StudentDAO.findAll());}@Testpublic void findByID() {System.out.println(StudentDAO.findById(0));System.out.println(StudentDAO.findById(2));System.out.println(StudentDAO.findById(1));}@Testpublic void updateStudent() {System.out.println(StudentDAO.updateStudent(new Student(0, "修改1", "修改2", 10)));}@Testpublic void delete(){System.out.println(StudentDAO.deleteById(0));System.out.println(StudentDAO.deleteById(1));}
}
原文链接:https://blog.csdn.net/Regino/article/details/105214832


















