实验七 数据库应用
一、实验目的:
了解数据库系统、关系模型、客户-服务器模式等基本概念,掌握 SQL 的数据定义、数据操纵和数据查询等语句的语法;了解 JDBC 各种数据库驱动程序类型,熟悉 JDBC 提供的接口和类,掌握指定驱动类型、连接数据库、执行 SQL 语句、处理结果集等操作方法。
二、实验内容:
数据库应用程序
1)首先在数据库应用程序中创建数据库 Studentinfo,按照下表的结构在数据库中建立"student"表。
字段名 | Java 数据类型 | 宽度 | SQL 数据类型 |
Name | String | 10 | Char(10) |
Sex | String | 2 | Char(2) |
Age | Int | 3 | Integer |
2)编写程序,a)向"student"表中填入若干数据记录;b)在"student"表中分别查询所有记录以及满足条件"age>18"的记录。c)编程创建学生成绩表,并
进行数据插入、修改、删除、查询和成绩统计等操作。
注:不限定数据库类型,
三、实验结果
1、创建数据库Studentinfo,建立student表。
建表SQL语句:
create table student(
Name char(10),
Sex char(2),
Age Integer(3));
2、a)源程序
import java.sql.*;
import java.util.Scanner;
import java.io.*;
public class Test7 {
public static void main(String[] args) {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3306/Studentinfo?serverTimezone=GMT";
String username="root";
String password="123456";
Connection c=DriverManager.getConnection(url,username,password);
if(!c.isClosed()) {
System.out.println("数据库已连接");
}
File f=new File("student.txt");//用文件输入数据
Scanner s=new Scanner(new FileInputStream(f));
String line;
line=s.nextLine();
String stu[]=line.split(" ");//设置空格为分割符
String name,sex;int age;
String insert="insert into Student values(?,?,?)";//添加成员的sql语句
PreparedStatement statement = null;
//将数据三个三个的导入数据库
for(int i=0;i<stu.length;i=i+3) {
name=stu[i];sex=stu[i+1];age=Integer.parseInt(stu[i+2]);
statement= c.prepareStatement(insert);
statement.setString(1,name);//第一个字段是姓名
statement.setString(2,sex);//第二个字段是性别
statement.setInt(3,age);//第三个字段是年龄
int a=statement.executeUpdate();//返回录入结果,如果录入成功返回1
System.out.println("a="+ a);
}
statement.close();
c.close();
}catch(ClassNotFoundException e) {
e.printStackTrace();
}catch(SQLException throwables) {
throwables.printStackTrace();
}catch(IOException e) {
System.out.println(e);
}
}
}
b)源程序
import java.sql.*;
import java.util.Scanner;
import java.io.*;
public class Test7 {
public static void main(String[] args) {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3306/Studentinfo?serverTimezone=GMT";
String username="root";
String password="123456";
Connection c=DriverManager.getConnection(url,username,password);
if(!c.isClosed()) {
System.out.println("数据库已连接");
}
//String select="select * from student";//查询全部信息
String select="select * from student where age>=18";//查询年纪大于18岁的人的信息
PreparedStatement Statement= c.prepareStatement(select);
ResultSet resultSet =Statement.executeQuery();//select 此处使用的是executeQuery,返回的是一个ResultSet
int count=0;//记录结果集行数
//遍历集合
while(resultSet.next()){
String n= resultSet.getString("name");
String se=resultSet.getString("sex");
int a=resultSet.getInt("age");
System.out.println("name:"+n+",sex:"+se+",age:"+a);
count++;
}
System.out.println("共查询到:"+count+"个结果");
resultSet.close();
Statement.close();
c.close();
}catch(ClassNotFoundException e) {
e.printStackTrace();
}catch(SQLException throwables) {
throwables.printStackTrace();
}
}
}
结果:
查询所有结果:
查询年龄大于18岁:
c)源程序
package Test7_3;
/**
*抽象操作类
*/
abstract class Work{
public abstract void work();//声明操作方法
}
package Test7_3;
/**
*增添学生信息的操作类
*主要负责增添学生的信息
*/
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;
public class input extends Work {
private Connection c;
public input(Connection c) {
this.c=c;
}
public void work() {
System.out.println("请输入学生的学号,姓名,课程,成绩:");
Scanner s=new Scanner(System.in);
int id=s.nextInt();
String name=s.next();
String course=s.next();
double grade=s.nextDouble();
String insert="insert into grade values(?,?,?,?)";//添加成员
PreparedStatement statement;
try {
statement = c.prepareStatement(insert);
statement.setInt(1,id);
statement.setString(2, name);
statement.setString(3,course);
statement.setDouble(4, grade);
statement.executeUpdate();
System.out.println("该学生信息已添加!");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package Test7_3;
/**
*查询学生信息的操作类
*负责查询学生的信息,可以按学号,姓名,成绩,课程来查
*输入查询条件即可查询
*/
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
public class search extends Work{
private Connection c;//Connection属性
public search(Connection c) {
this.c=c;
}
public void work() {
System.out.println("请选择你要查询的条件:1、学号 2、姓名 3、成绩 4、课程");
String shuju=null;
String search="select * from grade where ";
Scanner s=new Scanner(System.in);
int m=s.nextInt();
//按不同的查询条件分
if(m==1) {System.out.println("请输入要查询的学号:");search+=" id=";shuju=s.next(); search+=shuju;}
if(m==2) {System.out.println("请输入要查询的姓名:");search+="name='";shuju=s.next(); search+=shuju+"'";}
if(m==3) {System.out.println("请输入要查询的成绩:");search+="gr1ade=";shuju=s.next(); search+=shuju;}
if(m==4) {System.out.println("请输入要查询的课程:");search+="course='";shuju=s.next(); search+=shuju+"'";}
PreparedStatement statement;
try {
statement = c.prepareStatement(search);
ResultSet resultSet =statement.executeQuery();//得到结果集
int count=0;//记录结果集行数
//结果遍历集合
while(resultSet.next()){
String n= resultSet.getString("name");
String co=resultSet.getString("course");
int a=resultSet.getInt("id");
Double g=resultSet.getDouble("grade");
System.out.println("id:"+a+", name:"+n+", course:"+co+", grade:"+g);
count++;
}
System.out.println("共查询到:"+count+"个结果");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package Test7_3;
/**删除学生信息的操作类
*负责删除学生的信息,输入学号,即可删除学生的信息
*/
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
public class delete extends Work{
private Connection c;//Connection属性
public delete(Connection c) {
this.c=c;
}
public void work() {
System.out.println("请输入你要删除的信息的学号:");
Scanner s=new Scanner(System.in);
String shuju=s.next();
String delete="delete from grade where id="+shuju;
Statement stmt;
try {
stmt = c.createStatement();
stmt.executeUpdate(delete);
System.out.println("学生信息删除成功!");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package Test7_3;
/**
*更新学生成绩信息的操作类
*主要负责更新学生成绩信息
*输入学号,成绩以及更改后的成绩,即可修改
*/
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
public class update extends Work{
private Connection c;//Connection属性
public update(Connection c) {
this.c=c;
}
public void work() {
//只允许修改成绩,按学号和课程查
System.out.println("请输入要修改的成绩的学号以及要修改的课程和成绩:");
Scanner s=new Scanner(System.in);
String shuju=s.next();//输入的修改信息
String co=s.next();
double g=s.nextDouble();
String update="update grade set grade ="+g+" where id="+shuju+" and course="+"'"+co+"'";
Statement stmt;
try {
stmt = c.createStatement();
stmt.executeUpdate(update);
System.out.println("学生信息修改成功!");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package Test7_3;
/**
*统计学生成绩的操作类
*主要负责按学号统计学生的平均成绩
*选择这个操作,就会出来统计结果
*/
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class sum extends Work{
private Connection c;//Connection属性
public sum(Connection c) {
this.c=c;
}
//查询每位同学的平均成绩
public void work() {
String select="select id,name,avg(grade) as avg from grade group by id,name ";
PreparedStatement statement;
try {
statement = c.prepareStatement(select);
ResultSet resultSet =statement.executeQuery();
while(resultSet.next()) {
//按规定格式输出查询到的信息
System.out.println("学号:"+resultSet.getInt("id")+" 姓名:"+resultSet.getNString("name")+" 平均成绩:"+String.format("%.2f",resultSet.getDouble("avg")));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package Test7_3;
import java.util.*;
import java.io.*;
import java.sql.*;
/**
*测试类
*/
public class Test {
public static void main(String[] args) {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3306/Studentinfo?serverTimezone=GMT";
String username="root";
String password="123456";
Connection c=DriverManager.getConnection(url,username,password);
if(!c.isClosed()) {
System.out.println("数据库已连接");
}
//创建学生成绩表
String createtable="create table grade(id int,name varchar(20),course varchar(20), grade double)";
Statement state= c.createStatement();
state.executeUpdate(createtable);
System.out.println("成绩表已创建");
//用文件输入数据
File f=new File("grade.txt");
Scanner input=new Scanner(new FileInputStream(f));
String line;
line=input.nextLine();
String stu[]=line.split(" ");//设置空格为分割符
String name,course;int id;double grade;
String insert="insert into grade values(?,?,?,?)";//添加成员
PreparedStatement statement=null;
//四个为一组读数据,导入数据
for(int i=0;i<stu.length;i=i+4) {
id=Integer.parseInt(stu[i]);
name=stu[i+1];course=stu[i+2];
grade=Double.parseDouble(stu[i+3]);
statement= c.prepareStatement(insert);
statement.setInt(1,id);
statement.setString(2, name);
statement.setString(3,course);
statement.setDouble(4, grade);
statement.executeUpdate();
}
System.out.println("数据已输入表中");
//对成绩表进行相关操作
int t;
while(true) {
System.out.println("请选择操作:1、查询 2、删除 3、修改 4、录入 5、统计成绩 6、exit");
Scanner s=new Scanner(System.in);
t=s.nextInt();
Work w;
if(t==1) {
w=new search(c);
w.work();
}
if(t==2) {
w=new delete(c);
w.work();
}
if(t==3) {
w=new update(c);
w.work();
}
if(t==4) {
w=new input(c);
w.work();
}
if(t==5) {
w=new sum(c);
w.work();
}
if(t==6) {
break;
}
}
c.close();
}catch(ClassNotFoundException e) {
e.printStackTrace();
}catch(SQLException e2) {
e2.printStackTrace();
} catch (FileNotFoundException e3) {
e3.printStackTrace();
}
}
}
实验结果:
数据入库:
查询:分别按学号,姓名,和课程进行查询
删除:
修改成绩:将10001的java成绩修改为96,可看到修改后的结果
录入:
统计成绩:
四、实验分析与总结
(1)实验分析:
首先在数据库应用程序中通过sql语句创建数据库 Studentinfo和表student,我用的数据库应用程序是Navicat,然后按照要求创建了相关库和表格。
然后编写程序,向“student”中插入数据记录。我选择通过文件导入数据,先与数据库建立连接,然后读取”student.txt”文件,文件里是一行学生的数据,每个字段由空格分割,然后以三个为一组导入表中,并返回导入的结果。导入数据后,要分别查询学生表中所有信息和年龄大于18的学生信息,另写了一份程序,与数据库连接,然后根据sql查询语句去查询,一定要注意sql语句的格式规范,我因为语句的一些细节问题出了不少错。
最后是编写一个具有创建表,可以进行数据录入、查询、删除、更新和统计功能的程序。程序中先连接Studentinfo数据库,编写创建表格的语言创建学生成绩表,成绩表包括学号、姓名、课程和成绩四个字段,建表成功后依然选用用文件导入学生的成绩数据,导入成功后便可对学生成绩表进行操作。
起初我是将所有的操作和main放在一个类里面,导致这个类很长,功能很多;后来将操作这一部分单拿出来做了一个类,减轻了测试类的负担,但还是觉得操作类责任有点多;于是最后,我将每个操作单做一个类,Connection作为属性,都继承Work这个抽象类,这样每个类都是单一职责,负担小点,也方便后续扩展新的功能。另外,我实现了插入学生成绩信息,按学号、姓名、班级和成绩查询信息,按学号删除,添加学生成绩信息,更新学生成绩和按学号统计成绩的功能。之后程序还可以再细化一点,比如按班级或者课程统计信息。
(2)实验总结:
1、prepareStatement是预编译处理的,也叫jdbc存储过程,对于批量处理可以大大提高效率;同时对象的开销比createStatement大,对于一次性操作并不会带来额外的好处;但是能避免SQL注入的安全问题;
2、createStatement对象,适用于在对数据库只执行一次性存取需求,可能造成SQL注入,不安全;
通过本次实验我了解了数据库系统、关系模型、客户-服务器模式等基本概念,掌握 SQL 的数据定义、数据操纵和数据查询等语句的语法;了解 JDBC 各种数据库驱动程序类型,熟悉 JDBC 提供的接口和类,掌握指定驱动类型、连接数据库、执行 SQL 语句、处理结果集等操作方法。
PS:第二个实验需要一个txt文件,文件里是一行数据(为了省事数据就整了一行,也没去分行),放在项目目录里就行。我这个实验可能还存在繁琐的地方。