题目4. 赵斌是一个信管专业的学生,大学四年顺利毕业了。在毕业季,他也像其他学子一样,投身于求职大军,投出一份又一份求职简历,在苦苦地等待之后,他接到了中国移动通信公司广东分司的面试通知书,通知他于本月1号10点到公司面试。当天,晴空万里,艳阳高照,他身着西装,高兴地早早来到公司楼下等待。10点钟整,他和其他新人一起,坐到公司的面试现场。他领取的一一份程序设计题: 假如你是我公司一名客服技术人员,现请你选择自己熟悉的语言,来设计一个程序,管理客户向公司打进来的咨询电话。请事行分析析使用方法和工具,说明自己的思路方法,写一份完整的程序,并实例测试。
客户电话管理系统
一、 题目:
赵斌是一个信管专业的学生,大学四年顺利毕业了。在毕业季,他也像其他学子一样,投身于求职大军,投出一份又一份求职简历,在苦苦地等待之后,他接到了中国移动通信公司广东分司的面试通知书,通知他于本月1号10点到公司面试。当天,晴空万里,艳阳高照,他身着西装,高兴地早早来到公司楼下等待。10点钟整,他和其他新人一起,坐到公司的面试现场。他领取的一一份程序设计题: 假如你是我公司一名客服技术人员,现请你选择自己熟悉的语言,来设计一个程序,管理客户向公司打进来的咨询电话。请事行分析析使用方法和工具,说明自己的思路方法,写一份完整的程序,并实例测试。
二、 功能需求概述:
通过调查分析以及结合案例,系统应该达到以下的要求:
1.实现客户咨询电话的录入
2.实现客户咨询电话的查看
3.实现客户咨询电话的检索
使用工具:My eclipse + sqlserver 使用语言:Java
界面:
四、心得体会:
通过理解题目,最终得出本题仅是要求收录客户咨询电话,设计思路较清晰,题目逻辑也很明了。虽然不知道怎么该题怎么体现数据结构思想,但在设计程序过程中理解到先进先出的队列思想,即先存储进数据库中的数据边优先读取出来。
通过课程设计,学会了java 图形化设计与数据库连接的知识,加深了对队列的理解和数据优化排列查询和检索的理解。
不足之处:虽然程序能稳定运行,但设计得较为简单,代码逻辑不过简明。
主要代码如下:
Run
import javax.swing.JFrame;
public class Run {
public static void main(String[]args){
MainFrame f=new MainFrame("咨询电话管理系统");
f.setSize(300, 250);
f.setLocation(350, 250);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
MainFrame
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import java.awt.Font;
public class MainFrame extends JFrame implements ActionListener{
JButton jb,jb2,jbbb2;
JPanel ja,ja2,ja4;
JTextField land1text,land1text2;
CardLayout clayout;//面板必须放在布局管理器中, 默认的是边界布局, 这里是卡片布局
JLabel jl,jl1;
JMenu jm,jmm,jmmm,jm4;
JMenuItem jm1,jm3,jm41;
JPanel ja1;
Xsglxt xs;
public MainFrame(String s){
super(s);
JMenuBar mb=new JMenuBar();
this.setJMenuBar(mb);//菜单不需要确定方位,自动在上面
jm=new JMenu("退出系统");
jm1=new JMenuItem("退出");
jmmm=new JMenu("号码搜索");
jm3=new JMenuItem("客户号码搜索");
mb.add(jm);
mb.add(jmmm);
jm.add(jm1);
jmmm.add(jm3);
jb=new JButton("存入号码");
clayout=new CardLayout();
ja=new JPanel(clayout);
ja1=new JPanel(new BorderLayout());
//jl=new JLabel(new ImageIcon("image/QQ图片20141029150508.jpg"));
jl=new JLabel("***请输入客户号码***",JLabel.CENTER);//这个center指该标签里面的中间
jl.setFont(new Font("TimesRoman",Font.ITALIC,25));
land1text=new JTextField(20);
JLabel jl1=new JLabel("***请输入客户姓名***",JLabel.CENTER);
jl1.setFont(new Font("TimesRoman",Font.ITALIC,25));
land1text2=new JTextField(20);
ja4=new JPanel(new FlowLayout());
ja4.add(jl);
ja4.add(land1text);
ja4.add(jl1);
ja4.add(land1text2);
ja4.add(jb);
ja1.add(ja4,BorderLayout.CENTER);
// ja1.add(jl,BorderLayout.NORTH);//‘欢迎使用本系统’标签,center会自动填充北边和西,东边
// ja1.add(jb,BorderLayout.SOUTH);//‘进入系统’按钮
this.add(ja1);//ja1 是带有j1 和jb的边界布局面板
ja.add(ja1, "ja1"); //ja是卡片布局的面板 ja=new JPanel(clayout)
add(ja);//这里只是添加 并没有显示出来,这里的add和.add效果是一样的,谁调用就是谁来add
clayout.show(ja, "ja1"); //clayout是new出来cardlayout clayout=new CardLayout();
jb.addActionListener(this);//jb=进入系统
jm1.addActionListener(this);//jm1=退出 this指实现的, 下面的方法,this即是之前学的jtz
jm3.addActionListener(this);//jm3=进入选择类型
//面板ja2
//ja是卡片布局的面板 装进 ja1 (是带有j1 和jb的边界布局面板) 再把ja1用卡片布局显示出来
ja2=new JPanel(new FlowLayout());
jl1=new JLabel("*******请选择您的使用权限*******",JLabel.CENTER);
jl1.setFont(new Font("TimesRoman",Font.ITALIC,20));
jbbb2=new JButton(" 退出系统 ") ;
ja2.add(jl1);//ja2是一个流式布局的面板
ja2.add(jbbb2);
jbbb2.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==jm1)//jam=退出 之前用的是 e.getActionCommand().equals
System.exit(0);
if(e.getSource()==jm3){//jm3=进入选择类型
xs=new Xsglxt();
}
CustomsDb cb=new CustomsDb("customs");
if(e.getSource()==jb){//jb31=确认
if(land1text.getText().trim().length()==11){
Customs cu=new Customs(land1text.getText().trim(),land1text2.getText().trim());
if(cb.insert(cu)){
JOptionPane.showMessageDialog(null,"添加成功!");
land1text.setText("");
land1text2.setText("");
}
else {
JOptionPane.showMessageDialog(null,"添加失败!");
land1text.setText("");
land1text2.setText("");
}
}
else {
JOptionPane.showMessageDialog(null,"对不起,手机长度不正确!");
land1text.setText("");
}
}
if(e.getSource()==jbbb2){
System.exit(0);
}
}
}
DbOperation:
import java.sql.*;//执行数据查询和其他数据库语句, 执行查询的话返回数据库数据,执行其他数据库语句的话返回true或false
public class DbOperation{
protected Connection conn;//=ct
protected Statement stmt;//=sm
protected ResultSet rs;//
protected String dbname;
public DbOperation(){}
public DbOperation(String name){
dbname=name;
}
public void conn()
{
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
conn=DriverManager.getConnection("jdbc:odbc:sql server","sa","yaojianhui");
}
catch(Exception ex)
{
System.out.println("连接数据库失败!\n" +ex.getMessage());
}
}
public ResultSet exQuery(String sql)//查询语句,与下面的执行不同的是这里把执行后的 结果 返回给rs了
{
try
{
conn();
stmt=conn.createStatement();
rs=stmt.executeQuery(sql);
}
catch(Exception ex)
{
System.out.println("在执行查询"+sql+"失败了,异常为:\n" +ex.getMessage());
}
return rs;
}
public boolean exUpdate(String sql)//返回flag 即 true或false
{
boolean flag=true;
try
{
conn();
stmt = conn.createStatement();//把执行陈述的功能赋给stmt
stmt.executeUpdate(sql);
}
catch(SQLException ex)
{
System.out.println("executeUpdate在执行"+sql+"失败了,异常为:\n" +ex.getMessage());
flag=false;
}
finally
{
close();
}
return flag;
}
public void close()
{
try
{
if (rs!=null) rs.close();
stmt.close();
conn.close();
}
catch(Exception e)
{
System.out.println("关闭失败了,异常为:\n" +e.getMessage());
}
}
}
CustomsDb
import java.sql.*;
import java.util.*;
public class CustomsDb extends DbOperation{//用户数据类
public CustomsDb(String dbName)
{
super(dbName);
}
public boolean insert(Customs x)//插入数据,返回true或false,即判断是否删除成功
{
String sql="insert into SC values('"+x.getId()+"','"+x.getName()+"')";
if(exUpdate(sql))
return true;
else return false;
}
public boolean delete(Customs x)//删除数据 返回true或false
{
String sql="delete from SC" +" where id='"+x.getId()+"'";
if(exUpdate(sql))
return true;
else return false;
}
public Vector inQuery(String fie, String cond)//按操作返回相应的数据库里面的内容。返回v, 如果传入的是空,即返回数据库所有内容,如果fie cond是sql命令,则返回所要求的数据库内容
{
Customs x;
Vector v=new Vector();
String sql;
if(fie.equals("")||cond.equals(""))
sql="select * from SC" ;
else
sql="select * from SC" +" where "+fie+cond;
rs=exQuery(sql);//例如当传入的是两个空值时,会把所有的数据给rs,下面语句再把rs里面的内容放入到v中,返回v。
try
{
while(rs.next())//如果新的当前行有效,则返回 true;如果不存在下一行,则返回 false
{ //第一次调用 next 方法使第一行成为当前行;第二次调用使第二行成为当前行,依此类推。
x=new Customs();//new了很多次
x.setId(rs.getString("id"));//"id"为列名,把属于这个列名的第一行数据给取出来,是rs所属类里面的一个方法,rs是计算机识别的形式。
//可以这样取数据是因为上面已经把数据库中的数据给了rs,x再为ID设定数据
x.setName(rs.getString("name"));
v.add(x);//把数据放进v中,x是已经把当前所有数据都已经通过customs设定好了id name code balance 的一个custom 的对象
} //v.add是依靠while循环来一次把rs里面的数据设定好相对应的id name ...的数据
//v是包含了n个customs对象的集合类
}
catch(Exception e)
{
System.out.println("读数据错误!\n" +e.getMessage());
}
close();
return v;
}
}
Customs
//用户类,用于接收从数据库经过customsdb过来的数据。
public class Customs{
private String id,name;
//构造方法
public Customs(){}
public Customs(String id,String name){
this.id=id;
this.name=name;
}
public void print()
{
System.out.println(id+"\t"+name+"\t");
}
//get,set方法
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Xsglxt
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import java.util.*;
import javax.swing.*;
public class Xsglxt extends JFrame implements ActionListener
{
JPanel mb1,mb2;
JLabel bq1;
JTextField wbk1;
JButton an1,an2,an3,an4;
JTable bg1; //表格
JScrollPane gd1;
Xsxx xsxx2;
public Xsglxt()
{
mb1=new JPanel();
bq1=new JLabel("请输入手机号 ");
wbk1=new JTextField(10);
an1=new JButton("查询");
an1.addActionListener(this);
an1.setActionCommand("chaxun");//区别按钮
mb1.add(bq1); mb1.add(wbk1); mb1.add(an1);
mb2=new JPanel();
an2=new JButton("返回");
an2.addActionListener(this);
an2.setActionCommand("fanhui");
mb2.add(an2);
xsxx2=new Xsxx();
bg1=new JTable(xsxx2);
gd1=new JScrollPane(bg1);
//以上三句是把Xsxx中创建ziduan 和jilu 放进表格里,再把表格放进滚动条里
this.add(gd1);
this.add(mb1,"North");
this.add(mb2,"South");
this.setTitle("客户手机查询");
this.setSize(500,400);
this.setLocation(201,181);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("chaxun"))
{
String id=this.wbk1.getText().trim();//把在文本框输入的东西取出来
String sql="select * from SC where id='"+id+"'";//建立搜索条件
xsxx2=new Xsxx(sql);//把条件给父类Xsxx中的构造函数,再把输出结果给xsxx2
bg1.setModel(xsxx2);//在表格1中显示搜出来的信息,setModel,
}
if(e.getActionCommand().equals("fanhui"))
{
this.dispose();
}
}
}
Xsxx
//把读取记录的功能单独放在一个类里,因为有两段代码需要用到这个,把相同的功能放在一个类里
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;//以上全部也可以改为.*
import java.util.Vector;//集合类
import javax.swing.table.*;
class Xsxx extends AbstractTableModel //继承表格的一个类
{
Vector ziduan,jilu;
PreparedStatement ps=null;
Connection ct=null;
ResultSet rs=null;
public int getRowCount()
{
return this.jilu.size();
}
public int getColumnCount()
{
return this.ziduan.size();
}
public Object getValueAt(int hang, int lie)
{
return ((Vector)this.jilu.get(hang)).get(lie);
}
public Xsxx()
{
this.sqlyj("select * from SC");
}
public Xsxx(String ss)
{
this.sqlyj(ss);
}
public String getColumnName(int e)
{
return (String)this.ziduan.get(e);
}
public void sqlyj(String sql)
{
ziduan=new Vector();//字段是放在列表第一排的
ziduan.add("手机");
ziduan.add("姓名");
jilu=new Vector();//记录必须从数据库里读取
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
ct=DriverManager.getConnection("jdbc:odbc:sql server","sa","yaojianhui");
ps=ct.prepareStatement(sql); //sql指的是搜索的条件
rs=ps.executeQuery();
while(rs.next())//re.next 下一条记录的意思, 意思是有下一条记录就继续执行
{
Vector hang=new Vector();
hang.add(rs.getString(1));
hang.add(rs.getString(2));
jilu.add(hang);
}
} catch (Exception e){}
finally
{
try {
if(rs!=null)
{
rs.close();
}
if(ps!=null)
{
ps.close();
}
if(ct!=null)
{
ct.close();
}
} catch (Exception e){}
}
}
}