Socket 多线程 JDBC综合编程一服务器端编程
2016-11-13 15:13
190 查看
这部分程序与上一篇是配套的,实现后台对数据库的管理操作和客户端对数据库的请求响应。
1:实现对Derby数据库的增,删,查,改管理.
2:实现服务器端对客户端请求的监听,对数据库进行操作,返回结果信息给客户端。
实现服务器端界面如下:
查询操作结果显示如下:
具体代码如下:
import java.sql.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import java.io.*;
public class Server
{
public static void main(String args[])
{
JFrame server = new ConnectFrame();
server.show();
}
}
class ConnectFrame extends JFrame implements ActionListener
{
private String st1=null;
private String st2=null;
private String st3=null;
private String st4=null;
private String st5=null;
private String stt1=null;
private String stt2=null;
private String stt3=null;
private String stt4=null;
private String stt5=null;
// 定义驱动加载和数据库所需要使用的一些东西
// 加载驱动,连接到数据库,利用SQL生成Statement,操作数据库(若为查找:生成结果集,在结果集里面操作)
private final String URL = "jdbc:derby:MyDbTest;create=true";
private String SQL = "";
private JLabel user = new JLabel("服务器端",SwingConstants.CENTER);
private Connection con = null;
private Statement sm = null;
private ResultSet rs = null;
/*
输入向数据库待输入学生的信息,用于扩增数据库
*/
private JLabel namelabel = new JLabel("姓名:",SwingConstants.RIGHT);
private JTextField name = new JTextField(5);
private JLabel numlabel = new JLabel("学号:",SwingConstants.RIGHT);
private JTextField num = new JTextField(10);
private JLabel sexlabel = new JLabel("性别:",SwingConstants.RIGHT);
private JTextField sex = new JTextField(5);
private JLabel gradelabel = new JLabel("平均分:",SwingConstants.RIGHT);
private JTextField grade = new JTextField(5);
private JLabel majorlabel = new JLabel("专业:",SwingConstants.RIGHT);
private JTextField major = new JTextField(10);
private JButton submit = new JButton("提交信息");
/*
输入对数据库可操作所需要的信息
*/
private JLabel operation = new JLabel("对数据库进行操作",SwingConstants.CENTER);
//这里SwingConstants.CENTER 表示文本在单行输入文本中的初始位置
private JLabel namelabel2 = new JLabel("姓名:",SwingConstants.RIGHT);
private JTextField name2 = new JTextField(5);
private JLabel numlabel2 = new JLabel("学号:",SwingConstants.RIGHT);
private JTextField num2 = new JTextField(10);
private JLabel sexlabel2 = new JLabel("性别:",SwingConstants.RIGHT);
private JTextField sex2 = new JTextField(5);
private JLabel gradelabel2 = new JLabel("平均分:",SwingConstants.RIGHT);
private JTextField grade2 = new JTextField(5);
private JLabel majorlabel2 = new JLabel("专业:",SwingConstants.RIGHT);
private JTextField major2 = new JTextField(10);
// 执行操作的各个按钮
private JButton select = new JButton("查询");
private JButton delete = new JButton("删除");
private JButton update = new JButton("更新");
/*
用于显示操作的结果
*/
private JLabel resultlabel = new JLabel("操作数据库的结果如下",SwingConstants.CENTER);
private JTextArea resultarea = new JTextArea(20,80);
// 初始化各项操作,包括界面布局以及信息传送,接收和数据库操作。
public ConnectFrame()
{
setTitle("数据库管理程序");
setSize(580,500);
// 与数据库建立联系,不能在点击事件中执行
try{ // 加载Derby数据库驱动类
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
}catch(Exception ex)
{
System.out.println("加载驱动类,实现连接失败");
}
// 在启动数据库时,应该先建立一个表
try
{ // 注意:这里定义的长度,即为表中列属性的长度,不够的会用空格补,直接从数据库获得的字符串会含有空格,最好进行trim()处理
SQL = "CREATE TABLE Student(name char(15),num char(15),sex char(2),grade double,major char(10))";
con = DriverManager.getConnection(URL); //利用URL与本地数据库建立连接
sm = con.createStatement(); // 生成Statement对象,用于对数据库进行操作
sm.executeUpdate(SQL); // executeUpdate() 执行SQL更新语句,主要包括update,delete,insert语句
sm.close();
}catch(SQLException e)
{
System.out.println("初次建立数据库表失败: "+e);
}
addWindowListener(new WindowAdapter(){ /
17dce
/ 创建关闭窗口的事件监听器
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
CreateView();
// 开启服务器子线程,进行客户端的监听相应,而服务器是直接操作本地数据库的
new Thread(new Runnable(){ // 这采用匿名内部类的方式进行,也可以自定义Thread子类,实现run()方法重载,然后利用子类对象开启子线程
ServerSocket serversocket = null;
Socket socket = null;
DataInputStream in = null;
DataOutputStream out = null;
public void run() //这里 客户端只能实现对数据库的:查询和注册
{
// 根据嵌入的信息,判断客户端要进行的操作
try
{ // 子线程中操作数据库,需要自定义相关对象,加载驱动(这是为了避免与服务器自己操作产生冲突)
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
serversocket = new ServerSocket(8850); // 服务器绑定8850端口,作为与客户端交互窗口
while(true) // 死循环等待客户端请求
{
socket = serversocket.accept();
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
String line = new String("");
line = in.readUTF(); // 读取流中的内容,如果没有消息,该线程会在此陷入死等的阻塞状态
// 客户端根据操作,发送给服务器的是完整的SQL语句,服务器端获取后直接对数据库进行操作(这里根据SQL语句首字母,判断是哪种操作)
if(line.charAt(0)== 'I')
{
Connection con = DriverManager.getConnection(URL);
Statement sm = con.createStatement();
sm.executeUpdate(line);
resultarea.setText(" 客户端插入数据成功");
sm.close();con.close();
}else if(line.charAt(0)== 'S')
{
Connection con = DriverManager.getConnection(URL);
Statement sm = con.createStatement();
ResultSet rs = sm.executeQuery(line); //executeQuery():SQL查询语句执行后,返回结果集
String result = GetServerString(rs); // 自定义函数,实现对结果集的操作
out.writeUTF(result); // 将返回的结果,通过流返回给客户端
resultarea.setText(" 客户端查询数据成功");
rs.close();sm.close();con.close();
}else
{
System.out.println("数据传输有误!");
}
/*
数据传输,服务器做出的相应处理,要分类型操作。
*/
in.close();out.close();socket.close(); // 最好先释放由Socket对象创建的流对象
}
}catch(Exception e)
{
System.out.println("服务器接受客户端数据处理失误!");
}
}
public String GetServerString(ResultSet rs)
{
String result = new String("");
try{
if(!rs.next()) // 如果结果集为空(rs.next()返回false)不发送信息给客户端
{
System.out.println("该表中无该同学信息!");
resultarea.setText("该表中客户端请求同学信息!");
}else
{
do
{
String getname= rs.getString("name").trim(); // 利用数据库的列属性名,获得某一行某列的数据。
result += getname; // 注意这里由于定时数据结构大小的问题,结果中可能含有空格,采用trim()除去空格影响
for(int i=1;i<=15-getname.length();++i)
result += " ";
result += rs.getString("num").trim();
for(int i=1;i<=8;++i)
result += " ";
// 直接getString()获得的字符串,如果原始指定太大,会有空格填充
result += rs.getString("sex").trim();
for(int i=1;i<=8;++i)
result += " ";
String getgrade = rs.getString("grade").trim();
result += getgrade;
for(int i=1;i<=15-getgrade.length();++i)
result += " ";
// 表中最后一个元素,后面有换行和空格符(trim()函数可以将其清除掉)
String getmajor = rs.getString("major").trim();
result += getmajor;
result += "\n"; // 获得一个元组数据后,换行获得下面的数据
}while(rs.next());
}
}catch(SQLException e)
{
System.out.println("封装的查询操作失败 : "+e);
}
return result ;
}
}).start();
}
public void CreateView() // 创建视图界面
{
resultarea.setEditable(false);
resultarea.setLineWrap(false); // 不可以自动换行
Container layout = getContentPane();
layout.setLayout(null);
// 添加用于创建新成员相关信息的控件
layout.add(user);
user.setBounds(150,5,200,25);
layout.add(namelabel);
namelabel.setBounds(5,40,40,22);
layout.add(name);
name.setBounds(50,40,60,22);
layout.add(numlabel);
numlabel.setBounds(110,40,40,22);
layout.add(num);
num.setBounds(155,40,80,22);
layout.add(sexlabel);
sexlabel.setBounds(240,40,40,22);
layout.add(sex);
sex.setBounds(285,40,30,22);
layout.add(gradelabel);
gradelabel.setBounds(320,40,55,22);
layout.add(grade);
grade.setBounds(385,40,40,22);
layout.add(majorlabel);
majorlabel.setBounds(425,40,40,22);
layout.add(major);
major.setBounds(470,40,60,22);
layout.add(submit);
submit.setBounds(200,80,100,25);
// 添加修改数据库需要输入的信息
layout.add(operation);
operation.setBounds(175,135,150,25);
layout.add(namelabel2);
namelabel2.setBounds(5,180,40,22);
layout.add(name2);
name2.setBounds(50,180,60,22);
layout.add(numlabel2);
numlabel2.setBounds(110,180,40,22);
layout.add(num2);
num2.setBounds(155,180,80,22);
layout.add(sexlabel2);
sexlabel2.setBounds(240,180,40,22);
layout.add(sex2);
sex2.setBounds(285,180,30,22);
layout.add(gradelabel2);
gradelabel2.setBounds(320,180,55,22);
layout.add(grade2);
grade2.setBounds(385,180,40,22);
layout.add(majorlabel2);
majorlabel2.setBounds(425,180,40,22);
layout.add(major2);
major2.setBounds(470,180,60,22);
// 数据库执行操作的按钮
layout.add(select);
select.setBounds(100,225,60,25);
layout.add(delete);
delete.setBounds(220,225,60,25);
layout.add(update);
update.setBounds(340,225,60,25);
// 显示操作结果,这里操作都要分情况进行
layout.add(resultlabel);
resultlabel.setBounds(175,270,150,25);
JScrollPane scrollpane = new JScrollPane(resultarea);
layout.add(scrollpane);
scrollpane.setBounds(80,300,360,150);
// 设置监听事件 获取焦点先后
submit.addActionListener(this);
select.addActionListener(this);
delete.addActionListener(this);
update.addActionListener(this);
}
public void GetString()
{ // 获得服务器端操作数据库的信息
stt1 = name2.getText().trim();
stt2 = num2.getText().trim();
stt3 = sex2.getText().trim();
stt4 = grade2.getText().trim();
stt5 = major2.getText().trim();
}
public void Select(ResultSet rs)
{ // append()是在当前行后面添加字符串,setText()则是将全部设置为啥字符串显示
// append是后续添加,setText()是全盘修改为当下
try{
do
{ // 考虑如何排列整齐
String getname = rs.getString("name").trim();
resultarea.append(getname);
for(int i=1;i<=15-getname.length();++i)
resultarea.append(" ");
resultarea.append(rs.getString("num").trim());
for(int i=1;i<=8;++i)
resultarea.append(" ");
// 直接getString()获得的字符串,如果原始指定太大,会有空格填充
resultarea.append(rs.getString("sex").trim());
for(int i=1;i<=8;++i)
resultarea.append(" ");
String getgrade = rs.getString("grade").trim();
resultarea.append(getgrade);
for(int i=1;i<=15-getgrade.length();++i)
resultarea.append(" ");
// 表中最后一个元素,后面有换行和空格符(trim()函数可以将其清除掉)
String getmajor = rs.getString("major").trim();
resultarea.append(getmajor+"\n");
}while(rs.next()); // 这里不能用while,会导致第一个无法输出,因为前面if判断
}catch(SQLException e)
{
System.out.println("封装的查询操作失败 : "+e);
}
}
public void Delete(String SQL)
{
try
{
sm = con.createStatement();
sm.executeUpdate(SQL);
resultarea.setText(" 已成功删除相关信息");
System.out.println("删除学生信息成功");
sm.close();
}catch(SQLException e)
{
System.out.println("封装的删除操作失败 : "+e);
}
}
public void actionPerformed(ActionEvent evt)
{
resultarea.setText("");
// 规定删除和更新必要的数据输入,减少判断情况!
if(evt.getSource()==submit)
{
st1 = name.getText().trim();
st2 = num.getText().trim();
st3 = sex.getText().trim();
st4 = grade.getText().trim();
st5 = major.getText().trim();
if(st1.length()==0||st2.length()==0||st3.length()==0||st4.length()==0||st5.length()==0)
{
resultarea.append(" 请填入完整的数据!"+"\n");
return;
}else{
//获得输入信息,在数据库插入一个元组(判断是否漏项)
// 这里数字对应的字符串是否应该加上单引号,不应该
String line = "('"+st1+"','"+st2+"','"+st3+"',"+st4+",'"+st5+"')";
try{
SQL = "INSERT INTO Student VALUES"+line;
sm = con.createStatement();
sm.executeUpdate(SQL); //执行SQL的更新语句,包括update,delete和insert语句
System.out.println("插入学生信息成功!");
sm.close();
}catch(Exception e)
{
System.out.println("插入学生信息失败 : "+e);
}
}
}else if(evt.getSource()==select)
{
GetString();
// 查询,如果没有输入信息,全部打印,否则按输入查询
if(stt1.length()==0 && stt2.length()==0 && stt3.length()==0 && stt4.length()==0 && stt5.length()==0)
{
try
{
SQL = "SELECT * FROM Student";
sm = con.createStatement();
rs = sm.executeQuery(SQL);
/* setText()与append()的区别,append()是在已有文本后面添加 */
resultarea.setText("");
if(!rs.next())
{
resultarea.append(" 该表为空表!");
}else{
Select(rs);
}
rs.close();
sm.close();
}catch(Exception e)
{
System.out.println(" 查找全表失败 : "+e);
}
}else if(stt2.length()!=0)
{
// 可以依据唯一码(主码),学号进行查询
try{
// SQL语句中:字符串都要用单引号括起来
// 这个语句是有问题的:'stt2'字符串值是stt2而不是文本框中的 : String SQL = "SELECT * FROM Student WHERE num LIKE 'stt2'";
/*
注意属性值空格符的填充,以及SQL语句字符串值
*/
SQL = "SELECT * FROM Student WHERE num LIKE '"+stt2+"%'";
sm = con.createStatement();
rs = sm.executeQuery(SQL);
resultarea.setText("");
if(!rs.next())
{
resultarea.append(" !!该表为空表!");
}else{
Select(rs);
}
rs.close();
sm.close();
}catch(Exception e)
{ // 这里抛出异常,说明SQL语句出现问题
System.out.println("查询该名学生失败 : "+e);
}
}else if(stt1.length()!=0 && stt5.length()!=0)
{
// 依据姓名和专业同时查询
try
{ // SQL语句,多个条件WHERE下同时满足,不能并列处理,需要用AND连接.
SQL = "SELECT * FROM Student WHERE name LIKE '"+stt1+"%'"+"AND major LIKE '"+stt5+"%'";
sm = con.createStatement();
rs = sm.executeQuery(SQL);
resultarea.setText("");
if(!rs.next())
{
resultarea.append(" !该表为空表!");
}else{
Select(rs);
}
rs.close();
sm.close();
}catch(SQLException e)
{
System.out.println("查询失败"+e);
}
}else if(stt1.length()!=0)
{
if(stt5.length()==0)
{
// 依据姓名查询
try
{
SQL = "SELECT * FROM Student WHERE name LIKE '"+stt1+"%'";
sm = con.createStatement();
rs = sm.executeQuery(SQL);
resultarea.setText("");
if(!rs.next())
{
resultarea.append(" !该表为空表!");
}else{
Select(rs);
}
rs.close();
sm.close();
}catch(SQLException e)
{
System.out.println(e.toString());
}
}
}else if(stt5.length()!=0)
{
if(stt1.length()==0)
{
// 依据专业查询
try
{
SQL = "SELECT * FROM Student WHERE major LIKE '"+stt5+"%'";
sm = con.createStatement();
rs = sm.executeQuery(SQL);
resultarea.setText("");
if(!rs.next())
{
resultarea.append(" !该表为空表!");
}else{
Select(rs);
}
rs.close();
sm.close();
}catch(SQLException e)
{
System.out.println(e.toString());
}
}
}else
{
resultarea.append("查询操作,至少要输入:姓名,学号,专业中的一项");
}
}else if(evt.getSource()==delete)
{
GetString();
if(stt2.length()!=0)
{
// 依据唯一码:学号删除
SQL = "DELETE FROM Student WHERE num LIKE '"+stt2+"%'";
Delete(SQL);
}else if(stt1.length()!=0)
{
if(stt5.length()!=0)
{
// 依据姓名和专业删除
SQL = "DELETE FROM Student WHERE name LIKE '"+stt1+"%'"+"AND major LIKE '"+stt5+"%'";
Delete(SQL);
}else{
// 依据姓名删除
SQL = "DELETE FROM Student WHERE name LIKE '"+stt1+"%'";
Delete(SQL);
}
}else if(stt5.length()!=0)
{
// 依据专业删除
SQL = "DELETE FROM Student WHERE major LIKE '"+stt5+"%'";
Delete(SQL);
}else
{
resultarea.append("删除操作,至少要输入:姓名,学号,专业中的一项");
}
}else if(evt.getSource()==update)
{
GetString();
if(stt1.length()==0||stt2.length()==0||stt3.length()==0||stt4.length()==0||stt5.length()==0)
{
resultarea.append("更新操作,必须输入完整信息");
}else
{ // 对表进行更新
try
{
SQL = "UPDATE Student SET name='"+stt1+"',num='"+stt2+"',sex='"+stt3+"',grade="+stt4+",major='"+stt5+"'"+
" WHERE num LIKE '"+stt2+"%'";
sm = con.createStatement();
sm.executeUpdate(SQL);
resultarea.setText(" 已完成数据更新");
System.out.println("更新学生信息成功");
sm.close();
}catch(SQLException e)
{
System.out.println(e.toString());
}
}
}
}
}
其实这里主要:实现客户端与服务器信息交互,判断客户端意图,执行相关操作,返回信息给客户端。 同时服务器自身实现对数据库的管理。
要运行上述程序,需要下载安装Derby数据库对应的jar包!
1:实现对Derby数据库的增,删,查,改管理.
2:实现服务器端对客户端请求的监听,对数据库进行操作,返回结果信息给客户端。
实现服务器端界面如下:
查询操作结果显示如下:
具体代码如下:
import java.sql.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import java.io.*;
public class Server
{
public static void main(String args[])
{
JFrame server = new ConnectFrame();
server.show();
}
}
class ConnectFrame extends JFrame implements ActionListener
{
private String st1=null;
private String st2=null;
private String st3=null;
private String st4=null;
private String st5=null;
private String stt1=null;
private String stt2=null;
private String stt3=null;
private String stt4=null;
private String stt5=null;
// 定义驱动加载和数据库所需要使用的一些东西
// 加载驱动,连接到数据库,利用SQL生成Statement,操作数据库(若为查找:生成结果集,在结果集里面操作)
private final String URL = "jdbc:derby:MyDbTest;create=true";
private String SQL = "";
private JLabel user = new JLabel("服务器端",SwingConstants.CENTER);
private Connection con = null;
private Statement sm = null;
private ResultSet rs = null;
/*
输入向数据库待输入学生的信息,用于扩增数据库
*/
private JLabel namelabel = new JLabel("姓名:",SwingConstants.RIGHT);
private JTextField name = new JTextField(5);
private JLabel numlabel = new JLabel("学号:",SwingConstants.RIGHT);
private JTextField num = new JTextField(10);
private JLabel sexlabel = new JLabel("性别:",SwingConstants.RIGHT);
private JTextField sex = new JTextField(5);
private JLabel gradelabel = new JLabel("平均分:",SwingConstants.RIGHT);
private JTextField grade = new JTextField(5);
private JLabel majorlabel = new JLabel("专业:",SwingConstants.RIGHT);
private JTextField major = new JTextField(10);
private JButton submit = new JButton("提交信息");
/*
输入对数据库可操作所需要的信息
*/
private JLabel operation = new JLabel("对数据库进行操作",SwingConstants.CENTER);
//这里SwingConstants.CENTER 表示文本在单行输入文本中的初始位置
private JLabel namelabel2 = new JLabel("姓名:",SwingConstants.RIGHT);
private JTextField name2 = new JTextField(5);
private JLabel numlabel2 = new JLabel("学号:",SwingConstants.RIGHT);
private JTextField num2 = new JTextField(10);
private JLabel sexlabel2 = new JLabel("性别:",SwingConstants.RIGHT);
private JTextField sex2 = new JTextField(5);
private JLabel gradelabel2 = new JLabel("平均分:",SwingConstants.RIGHT);
private JTextField grade2 = new JTextField(5);
private JLabel majorlabel2 = new JLabel("专业:",SwingConstants.RIGHT);
private JTextField major2 = new JTextField(10);
// 执行操作的各个按钮
private JButton select = new JButton("查询");
private JButton delete = new JButton("删除");
private JButton update = new JButton("更新");
/*
用于显示操作的结果
*/
private JLabel resultlabel = new JLabel("操作数据库的结果如下",SwingConstants.CENTER);
private JTextArea resultarea = new JTextArea(20,80);
// 初始化各项操作,包括界面布局以及信息传送,接收和数据库操作。
public ConnectFrame()
{
setTitle("数据库管理程序");
setSize(580,500);
// 与数据库建立联系,不能在点击事件中执行
try{ // 加载Derby数据库驱动类
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
}catch(Exception ex)
{
System.out.println("加载驱动类,实现连接失败");
}
// 在启动数据库时,应该先建立一个表
try
{ // 注意:这里定义的长度,即为表中列属性的长度,不够的会用空格补,直接从数据库获得的字符串会含有空格,最好进行trim()处理
SQL = "CREATE TABLE Student(name char(15),num char(15),sex char(2),grade double,major char(10))";
con = DriverManager.getConnection(URL); //利用URL与本地数据库建立连接
sm = con.createStatement(); // 生成Statement对象,用于对数据库进行操作
sm.executeUpdate(SQL); // executeUpdate() 执行SQL更新语句,主要包括update,delete,insert语句
sm.close();
}catch(SQLException e)
{
System.out.println("初次建立数据库表失败: "+e);
}
addWindowListener(new WindowAdapter(){ /
17dce
/ 创建关闭窗口的事件监听器
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
CreateView();
// 开启服务器子线程,进行客户端的监听相应,而服务器是直接操作本地数据库的
new Thread(new Runnable(){ // 这采用匿名内部类的方式进行,也可以自定义Thread子类,实现run()方法重载,然后利用子类对象开启子线程
ServerSocket serversocket = null;
Socket socket = null;
DataInputStream in = null;
DataOutputStream out = null;
public void run() //这里 客户端只能实现对数据库的:查询和注册
{
// 根据嵌入的信息,判断客户端要进行的操作
try
{ // 子线程中操作数据库,需要自定义相关对象,加载驱动(这是为了避免与服务器自己操作产生冲突)
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
serversocket = new ServerSocket(8850); // 服务器绑定8850端口,作为与客户端交互窗口
while(true) // 死循环等待客户端请求
{
socket = serversocket.accept();
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
String line = new String("");
line = in.readUTF(); // 读取流中的内容,如果没有消息,该线程会在此陷入死等的阻塞状态
// 客户端根据操作,发送给服务器的是完整的SQL语句,服务器端获取后直接对数据库进行操作(这里根据SQL语句首字母,判断是哪种操作)
if(line.charAt(0)== 'I')
{
Connection con = DriverManager.getConnection(URL);
Statement sm = con.createStatement();
sm.executeUpdate(line);
resultarea.setText(" 客户端插入数据成功");
sm.close();con.close();
}else if(line.charAt(0)== 'S')
{
Connection con = DriverManager.getConnection(URL);
Statement sm = con.createStatement();
ResultSet rs = sm.executeQuery(line); //executeQuery():SQL查询语句执行后,返回结果集
String result = GetServerString(rs); // 自定义函数,实现对结果集的操作
out.writeUTF(result); // 将返回的结果,通过流返回给客户端
resultarea.setText(" 客户端查询数据成功");
rs.close();sm.close();con.close();
}else
{
System.out.println("数据传输有误!");
}
/*
数据传输,服务器做出的相应处理,要分类型操作。
*/
in.close();out.close();socket.close(); // 最好先释放由Socket对象创建的流对象
}
}catch(Exception e)
{
System.out.println("服务器接受客户端数据处理失误!");
}
}
public String GetServerString(ResultSet rs)
{
String result = new String("");
try{
if(!rs.next()) // 如果结果集为空(rs.next()返回false)不发送信息给客户端
{
System.out.println("该表中无该同学信息!");
resultarea.setText("该表中客户端请求同学信息!");
}else
{
do
{
String getname= rs.getString("name").trim(); // 利用数据库的列属性名,获得某一行某列的数据。
result += getname; // 注意这里由于定时数据结构大小的问题,结果中可能含有空格,采用trim()除去空格影响
for(int i=1;i<=15-getname.length();++i)
result += " ";
result += rs.getString("num").trim();
for(int i=1;i<=8;++i)
result += " ";
// 直接getString()获得的字符串,如果原始指定太大,会有空格填充
result += rs.getString("sex").trim();
for(int i=1;i<=8;++i)
result += " ";
String getgrade = rs.getString("grade").trim();
result += getgrade;
for(int i=1;i<=15-getgrade.length();++i)
result += " ";
// 表中最后一个元素,后面有换行和空格符(trim()函数可以将其清除掉)
String getmajor = rs.getString("major").trim();
result += getmajor;
result += "\n"; // 获得一个元组数据后,换行获得下面的数据
}while(rs.next());
}
}catch(SQLException e)
{
System.out.println("封装的查询操作失败 : "+e);
}
return result ;
}
}).start();
}
public void CreateView() // 创建视图界面
{
resultarea.setEditable(false);
resultarea.setLineWrap(false); // 不可以自动换行
Container layout = getContentPane();
layout.setLayout(null);
// 添加用于创建新成员相关信息的控件
layout.add(user);
user.setBounds(150,5,200,25);
layout.add(namelabel);
namelabel.setBounds(5,40,40,22);
layout.add(name);
name.setBounds(50,40,60,22);
layout.add(numlabel);
numlabel.setBounds(110,40,40,22);
layout.add(num);
num.setBounds(155,40,80,22);
layout.add(sexlabel);
sexlabel.setBounds(240,40,40,22);
layout.add(sex);
sex.setBounds(285,40,30,22);
layout.add(gradelabel);
gradelabel.setBounds(320,40,55,22);
layout.add(grade);
grade.setBounds(385,40,40,22);
layout.add(majorlabel);
majorlabel.setBounds(425,40,40,22);
layout.add(major);
major.setBounds(470,40,60,22);
layout.add(submit);
submit.setBounds(200,80,100,25);
// 添加修改数据库需要输入的信息
layout.add(operation);
operation.setBounds(175,135,150,25);
layout.add(namelabel2);
namelabel2.setBounds(5,180,40,22);
layout.add(name2);
name2.setBounds(50,180,60,22);
layout.add(numlabel2);
numlabel2.setBounds(110,180,40,22);
layout.add(num2);
num2.setBounds(155,180,80,22);
layout.add(sexlabel2);
sexlabel2.setBounds(240,180,40,22);
layout.add(sex2);
sex2.setBounds(285,180,30,22);
layout.add(gradelabel2);
gradelabel2.setBounds(320,180,55,22);
layout.add(grade2);
grade2.setBounds(385,180,40,22);
layout.add(majorlabel2);
majorlabel2.setBounds(425,180,40,22);
layout.add(major2);
major2.setBounds(470,180,60,22);
// 数据库执行操作的按钮
layout.add(select);
select.setBounds(100,225,60,25);
layout.add(delete);
delete.setBounds(220,225,60,25);
layout.add(update);
update.setBounds(340,225,60,25);
// 显示操作结果,这里操作都要分情况进行
layout.add(resultlabel);
resultlabel.setBounds(175,270,150,25);
JScrollPane scrollpane = new JScrollPane(resultarea);
layout.add(scrollpane);
scrollpane.setBounds(80,300,360,150);
// 设置监听事件 获取焦点先后
submit.addActionListener(this);
select.addActionListener(this);
delete.addActionListener(this);
update.addActionListener(this);
}
public void GetString()
{ // 获得服务器端操作数据库的信息
stt1 = name2.getText().trim();
stt2 = num2.getText().trim();
stt3 = sex2.getText().trim();
stt4 = grade2.getText().trim();
stt5 = major2.getText().trim();
}
public void Select(ResultSet rs)
{ // append()是在当前行后面添加字符串,setText()则是将全部设置为啥字符串显示
// append是后续添加,setText()是全盘修改为当下
try{
do
{ // 考虑如何排列整齐
String getname = rs.getString("name").trim();
resultarea.append(getname);
for(int i=1;i<=15-getname.length();++i)
resultarea.append(" ");
resultarea.append(rs.getString("num").trim());
for(int i=1;i<=8;++i)
resultarea.append(" ");
// 直接getString()获得的字符串,如果原始指定太大,会有空格填充
resultarea.append(rs.getString("sex").trim());
for(int i=1;i<=8;++i)
resultarea.append(" ");
String getgrade = rs.getString("grade").trim();
resultarea.append(getgrade);
for(int i=1;i<=15-getgrade.length();++i)
resultarea.append(" ");
// 表中最后一个元素,后面有换行和空格符(trim()函数可以将其清除掉)
String getmajor = rs.getString("major").trim();
resultarea.append(getmajor+"\n");
}while(rs.next()); // 这里不能用while,会导致第一个无法输出,因为前面if判断
}catch(SQLException e)
{
System.out.println("封装的查询操作失败 : "+e);
}
}
public void Delete(String SQL)
{
try
{
sm = con.createStatement();
sm.executeUpdate(SQL);
resultarea.setText(" 已成功删除相关信息");
System.out.println("删除学生信息成功");
sm.close();
}catch(SQLException e)
{
System.out.println("封装的删除操作失败 : "+e);
}
}
public void actionPerformed(ActionEvent evt)
{
resultarea.setText("");
// 规定删除和更新必要的数据输入,减少判断情况!
if(evt.getSource()==submit)
{
st1 = name.getText().trim();
st2 = num.getText().trim();
st3 = sex.getText().trim();
st4 = grade.getText().trim();
st5 = major.getText().trim();
if(st1.length()==0||st2.length()==0||st3.length()==0||st4.length()==0||st5.length()==0)
{
resultarea.append(" 请填入完整的数据!"+"\n");
return;
}else{
//获得输入信息,在数据库插入一个元组(判断是否漏项)
// 这里数字对应的字符串是否应该加上单引号,不应该
String line = "('"+st1+"','"+st2+"','"+st3+"',"+st4+",'"+st5+"')";
try{
SQL = "INSERT INTO Student VALUES"+line;
sm = con.createStatement();
sm.executeUpdate(SQL); //执行SQL的更新语句,包括update,delete和insert语句
System.out.println("插入学生信息成功!");
sm.close();
}catch(Exception e)
{
System.out.println("插入学生信息失败 : "+e);
}
}
}else if(evt.getSource()==select)
{
GetString();
// 查询,如果没有输入信息,全部打印,否则按输入查询
if(stt1.length()==0 && stt2.length()==0 && stt3.length()==0 && stt4.length()==0 && stt5.length()==0)
{
try
{
SQL = "SELECT * FROM Student";
sm = con.createStatement();
rs = sm.executeQuery(SQL);
/* setText()与append()的区别,append()是在已有文本后面添加 */
resultarea.setText("");
if(!rs.next())
{
resultarea.append(" 该表为空表!");
}else{
Select(rs);
}
rs.close();
sm.close();
}catch(Exception e)
{
System.out.println(" 查找全表失败 : "+e);
}
}else if(stt2.length()!=0)
{
// 可以依据唯一码(主码),学号进行查询
try{
// SQL语句中:字符串都要用单引号括起来
// 这个语句是有问题的:'stt2'字符串值是stt2而不是文本框中的 : String SQL = "SELECT * FROM Student WHERE num LIKE 'stt2'";
/*
注意属性值空格符的填充,以及SQL语句字符串值
*/
SQL = "SELECT * FROM Student WHERE num LIKE '"+stt2+"%'";
sm = con.createStatement();
rs = sm.executeQuery(SQL);
resultarea.setText("");
if(!rs.next())
{
resultarea.append(" !!该表为空表!");
}else{
Select(rs);
}
rs.close();
sm.close();
}catch(Exception e)
{ // 这里抛出异常,说明SQL语句出现问题
System.out.println("查询该名学生失败 : "+e);
}
}else if(stt1.length()!=0 && stt5.length()!=0)
{
// 依据姓名和专业同时查询
try
{ // SQL语句,多个条件WHERE下同时满足,不能并列处理,需要用AND连接.
SQL = "SELECT * FROM Student WHERE name LIKE '"+stt1+"%'"+"AND major LIKE '"+stt5+"%'";
sm = con.createStatement();
rs = sm.executeQuery(SQL);
resultarea.setText("");
if(!rs.next())
{
resultarea.append(" !该表为空表!");
}else{
Select(rs);
}
rs.close();
sm.close();
}catch(SQLException e)
{
System.out.println("查询失败"+e);
}
}else if(stt1.length()!=0)
{
if(stt5.length()==0)
{
// 依据姓名查询
try
{
SQL = "SELECT * FROM Student WHERE name LIKE '"+stt1+"%'";
sm = con.createStatement();
rs = sm.executeQuery(SQL);
resultarea.setText("");
if(!rs.next())
{
resultarea.append(" !该表为空表!");
}else{
Select(rs);
}
rs.close();
sm.close();
}catch(SQLException e)
{
System.out.println(e.toString());
}
}
}else if(stt5.length()!=0)
{
if(stt1.length()==0)
{
// 依据专业查询
try
{
SQL = "SELECT * FROM Student WHERE major LIKE '"+stt5+"%'";
sm = con.createStatement();
rs = sm.executeQuery(SQL);
resultarea.setText("");
if(!rs.next())
{
resultarea.append(" !该表为空表!");
}else{
Select(rs);
}
rs.close();
sm.close();
}catch(SQLException e)
{
System.out.println(e.toString());
}
}
}else
{
resultarea.append("查询操作,至少要输入:姓名,学号,专业中的一项");
}
}else if(evt.getSource()==delete)
{
GetString();
if(stt2.length()!=0)
{
// 依据唯一码:学号删除
SQL = "DELETE FROM Student WHERE num LIKE '"+stt2+"%'";
Delete(SQL);
}else if(stt1.length()!=0)
{
if(stt5.length()!=0)
{
// 依据姓名和专业删除
SQL = "DELETE FROM Student WHERE name LIKE '"+stt1+"%'"+"AND major LIKE '"+stt5+"%'";
Delete(SQL);
}else{
// 依据姓名删除
SQL = "DELETE FROM Student WHERE name LIKE '"+stt1+"%'";
Delete(SQL);
}
}else if(stt5.length()!=0)
{
// 依据专业删除
SQL = "DELETE FROM Student WHERE major LIKE '"+stt5+"%'";
Delete(SQL);
}else
{
resultarea.append("删除操作,至少要输入:姓名,学号,专业中的一项");
}
}else if(evt.getSource()==update)
{
GetString();
if(stt1.length()==0||stt2.length()==0||stt3.length()==0||stt4.length()==0||stt5.length()==0)
{
resultarea.append("更新操作,必须输入完整信息");
}else
{ // 对表进行更新
try
{
SQL = "UPDATE Student SET name='"+stt1+"',num='"+stt2+"',sex='"+stt3+"',grade="+stt4+",major='"+stt5+"'"+
" WHERE num LIKE '"+stt2+"%'";
sm = con.createStatement();
sm.executeUpdate(SQL);
resultarea.setText(" 已完成数据更新");
System.out.println("更新学生信息成功");
sm.close();
}catch(SQLException e)
{
System.out.println(e.toString());
}
}
}
}
}
其实这里主要:实现客户端与服务器信息交互,判断客户端意图,执行相关操作,返回信息给客户端。 同时服务器自身实现对数据库的管理。
要运行上述程序,需要下载安装Derby数据库对应的jar包!
相关文章推荐
- linux基础编程 套接字socket 完整的服务器端多线程socket程序
- linux基础编程 套接字socket 完整的服务器端多线程socket程序【转】
- linux基础编程 套接字socket 完整的服务器端多线程socket程序
- [零散篇]Java学习笔记---Java的Socket网络编程以及多线程
- 实现服务器端的多线程SOCKET Server(转)
- Socket 编程经验谈---如何处理socket连接后服务器端或客户端的断开
- C#中SOCKET多线程编程实例(转)
- C#中SOCKET多线程编程实例
- 浅谈C# Socket编程及C#如何使用多线程
- C# Socket多线程编程实例
- C#中Socket多线程编程实例 (转)
- Linux Socket 网络编程 基于GTK+ 的多线程实现的局域网通信软件
- C#中Socket多线程编程实例 [转载]
- C# Socket多线程编程实例
- C#中Socket多线程编程实例(转载)
- C# Socket多线程编程实例
- 服务器端的多线程SOCKET Server
- Java套接字Socket编程-----服务器端和客户端
- (转载)C# Socket多线程编程实例
- socket和多线程可移植性编程基础(转)