1、2018/9/3,1,第5章 JavaBean编程技术,2,内容提要,常用控件的综合应用 菜单制作 连接数据库 嵌入SQL语句实现数据库编程 数据的查询 数据的更新(添加、删除、修改),3,常用控件综合应用,实现登录界面-Java建议使用swing组件替代AWT组件,称为轻型组件。 增加难度:对用户名和密码为空时的判断,4,登录窗体编程要点,public class Login extends JFrame implements ActionListenerprivate JTextField jt1;private JPasswordField jt2;private JButton jb1
2、,jb2;private ImageJPanel ip2;private JRadioButton jr;public static String u,p; public Login()super(“登录“);this.setBounds(310,210,400,335);this.setResizable(false);this.setDefaultCloseOperation(EXIT_ON_CLOSE);ip2=new ImageJPanel();ip2.setBounds(0,0,this.getWidth(),this.getHeight();this.add(ip2);jb1.ad
3、dActionListener(this);jb2.addActionListener(this);this.setVisible(true);此处省略了其他控件的添加,5,单击登录事件的关键代码,public void actionPerformed(ActionEvent e)if(e.getSource()=jb1)/如果点击登录按钮Connection conn=null;/数据库连接部分的初始化ResultSet rs;Statement st;if(jt1.getText().equals(“)JOptionPane.showMessageDialog(this,“用户名不能为空“
4、);return;if(jt2.getText().equals(“)JOptionPane.showMessageDialog(this,“密码不能为空“);return; try /数据库连接 Class.forName( “com.microsoft.jdbc.sqlserver.SQLServerDriver“).newInstance(); String url=“jdbc:microsoft:sqlserver:/127.0.0.1:1433;DatabaseName=warehourse“;String user=“sa“;String password=“sa“;conn=Dr
5、iverManager.getConnection(url,user,password);st=conn.createStatement();,6,登录后查询数据库表login,u=jt1.getText();p=jt2.getText();String z=null;for(int i=0;i0) JOptionPane.showMessageDialog(this,“登录成功!“);if(z.equals(“管理员“)new MainFrame(); elsenew MainFrame2();this.dispose(); elseJOptionPane.showMessageDialog
6、(this,“登录失败,用户名或密码正确!“); ,7,菜单和多文档界面,8,菜单制作要点,主要内容请参加Java教材6.3.7菜单组件 下面介绍上例核心代码,public class MainFrame extends JFrame implements ActionListener public ImageJPanel ip;/图像面板可加载背景图片public MainFrame()super(“主界面“);this.setBounds(210,170,605,470);this.setResizable(false);this.setDefaultCloseOperation(EXIT
7、_ON_CLOSE);this.addmyMenu();/调用自定义方法,添加菜单 public void addmyMenu() /添加主菜单和各级子菜单JMenuBar jmb=new JMenuBar();this.setJMenuBar(jmb); /框架上添加菜单栏,9,菜单制作要点,主菜单和子菜单中的菜单项的添加,String menu_1=“添加信息“,“订单信息“,“查询信息“,“修改信息“,“执行“,“帮助“;JMenu menu=new JMenumenu_1.length;/生成菜单数组munufor(int i=0;imenu.length;i+)menui=new J
8、Menu(menu_1i);/生成菜单,标题为对应的字符串jmb.add(menui);/在菜单栏中添加菜单String addxx=“添加仓库信息”,“添加设备信息”,“添加部门信息”,“添加 职工信息“,“添加供应商信息“; JMenuItem add=new JMenuItemaddxx.length;/生成菜单项数组add for(int i=0;ia.length;i+)addi=new JMenuItem(addxxi);addi.setIcon(new ImageIcon(“icon/3.jpg”);/添加图标addi.addActionListener(this);/添加单击事
9、件监听器menu0.add(ai);,10,菜单制作,添加分隔符以及单击事件处理方法,menu0.addSeparator();/添加分隔符 JMenuItem ext=new JMenuItem(“退出“); ext.setIcon(new ImageIcon(“icon/3.jpg“); ext.addActionListener(this); menu0.add(ext); /省略其他菜单项的添加public void actionPerformed(ActionEvent e)if(e.getActionCommand()=“退出“)if(JOptionPane.showConfirm
10、Dialog(this,“是否要退出工程“)=0)System.exit(0); if(e.getActionCommand()=“添加用户信息“)new yonghuxx();/打开添加用户窗体 . /省略其他菜单项单击事件类似,11,JDBC的作用和功能,什么是JDBC (Java DataBase Connectivity,Java数据库连接)是基于Java的、用于访问关系数据库的应用程序编程接口。 JDBC驱动程序类型 JDBC-ODBC桥驱动程序: 不易于移植,速度慢 本地库Java实现驱动程序:不具有跨平台性 网络协议驱动程序:适于分布式应用,涉及安全性 数据库协议驱动程序:纯ja
11、va,跨平台,速度快,是首选方式,12,JDBC驱动程序类型及其工作原理,13,JDBC的基本功能、组成和工作原理,14,指定JDBC驱动程序,第一步:选择和安装JDBC驱动程序 首选是纯java的数据库协议驱动程序 如果是Access数据库只能用JDBC-ODBC桥驱动 JDBC-ODBC桥驱动方式 JDBC-ODBC桥驱动程序类是sun.jdbc.odbc.JdbcOdcDriver,JDK默认安装 需要在配置ODBC数据源 纯java的数据库协议驱动方式 需要在MyEclipse中添加相应的DBMS的JDBC驱动程序包,15,指定JDBC驱动程序,第二步:在应用程序中指定JDBC驱动程序
12、 public static Class forName(String className) throws classNotFoundException 举例如下: Class.forName(“sun.jdbc.odbc.JdbcOdcDriver”); Class.forName(“com.mysql.jdbc.Driver“); String driver=“com.microsoft.jdbc.sqlserver.SQLServerDriver“; Class.forName(driver);/指定SQL Server2000 的JDBC驱动程序 请注意sql server 2005
13、中加载驱动的语句则为 “com.microsoft.sqlserver.jdbc.SQLServerDriver“;,16,数据库的连接和使用,常用的接口和类包括: DriverManager类 Connection类 Statement类 ResultSet类,17,DriverManager类,DriverManager类创建与指定数据库连接 getConnection()方法装载驱动程序,并与数据源连接public static Connection getConnection(String url) throws SQLException public static Connectio
14、n getConnection(String url,String user,String password) throws SQLException 使用url表示JDBC驱动程序和数据源的位置,格式为jdbc:子协议:数据源 Connection conn = DriverManager.getConnection(“jdbc:odbc:student_access”);/jdbc-odbc方式 Connection conn=DriverManager.getConnection(“jdbc:mysql:/localhost/student?user=root/MySQL,18,Driv
15、erManager类,SQL Server2000数据库的连接 String url=“jdbc:microsoft:sqlserver:/127.0.0.1:1433;DatabaseName=warehourse“;String user=“sa“;String password=“sa“; conn=DriverManager.getConnection(url,user,password); SQL Server2005数据库的连接URL = “jdbc:sqlserver:/localhost:1433,19,Connection接口管理连接对象,public interface C
16、onnection Statement createStatement() throws SQLException; /创建执行SQL的语句对象StatementStatement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException;/参数指定结果集属性void close() throws SQLException; /关闭数据库连接boolean isClosed() throws SQLException; /判断数据库连接是否已关闭DatabaseMetaData getMet
17、aData() throws SQLException; /获取所连接数据库的元数据 ,20,DatabaseMetaData接口获得数据库元数据,public interface DatabaseMetaData String getURL() throws SQLException; /返回连接数据库的URLString getUserName() throws SQLException; /返回数据库的用户名String getDatabaseProductName() throws SQLException; /返回数据库名称String getDatabaseProductVersi
18、on() throws SQLException; /返回数据库版本号String getDriverName() throws SQLException; /返回驱动程序名称String getDriverVersion() throws SQLException; /返回驱动程序版本号 【例11.3】 连接指定数据库并获得数据库属性信息。,21,执行SQL语句,Statement接口及其方法声明如下: public interface Statement int executeUpdate(String sql) throws SQLException; /执行数据定义和数据更新SQL语句
19、ResultSet executeQuery(String sql) throws SQLException; /执行数据查询SQL语句boolean execute(String sql) throws SQLException; /执行SQL语句int getUpdateCount() throws SQLException; /获得数据更新所影响的行数ResultSet getResultSet() throws SQLException; /获得数据查询结果集void close() throws SQLException; /关闭语句 ,Statement接口管理和执行SQL语句Re
20、sultSet接口存储数据查询返回的结果集,22,执行SQL语句,执行数据定义和数据更新SQL语句 Statement stmt = conn.createStatement(); String sql = “ INSERT INTO stuinfo (stu_id, stu_name) VALUES (98111041, 李伟)“; int result = stmt.executeUpdate(sql); /返回影响的行数1 执行数据查询SQL语句 String sql = “SELECT * FROM stuinfo “; ResultSet rset = stmt.executeQue
21、ry(sql); 执行SQL语句 一般用上述两种方法 当不能确定SQL语句的类别,调用execute()方法,返回布尔型; 调用getResultSet()方法获得数据查询结果集 调用getUpdateCount()方法获得数据更新所影响的行数。,23,处理数据查询的结果集,ResultSet接口存储结果集 int getRow() throws SQLException; /当前行位置 boolean first() throws SQLException; /第一行为当前行 boolean previous() throws SQLException; /向上一行 boolean next
22、() throws SQLException; /向下一行 由于ResultSet接口没有获得结果集总行数的方法,所以需要采用循环语句处理每行数据或者统计行数 int rows=0; while(rset.next()rows+; /获得结果集总行数 需要再次处理该结果集,则可以调用previous() 反向迭代,或者用beforeFirst()将指针指向第一行之前;,24,获得当前行指定列的数据项值,Object getObject(int columnIndex) throws SQLException; Object getObject(String columnName) throws
23、 SQLException; String getString(int columnIndex) throws SQLException; String getString(String columnName) throws SQLException; 例如,获得结果集rset第1列的全部数据项 while(rset.next()System.out.println(rset.getString(1);,25,ResultSetMetaData接口获得结果集元数据,public interface ResultSetMetaData int getColumnCount() throws SQ
24、LException; /返回列数String getColumnName(int column) throws SQLException; /返回列名String getColumnTypeName(int column) throws SQLException; /返回列数据类型名int getColumnDisplaySize(int column) throws SQLException; /返回列所占的最大字符宽度 ResultSetMetaData rsmd = resultset.getMetaData(); int columnCount = rsmd.getColumnCou
25、nt(); /获得列数【例11.5】 使用JTable显示数据查询的结果集。 注意,这里的查询比较简单,即输出所有数据。如果按照条件查询呢?,26,使用JTable显示数据查询的结果集。,private JTable query(String table) throws SQLException, ClassNotFoundException String driver=“com.microsoft.jdbc.sqlserver.SQLServerDriver“; String url=“jdbc:microsoft:sqlserver:/127.0.0.1:1433;DatabaseName
26、=warehourse“; Class.forName(driver);/指定JDBC驱动程序,27,使用JTable显示数据查询的结果集,String user=“sa“; String password=“sa“;this.conn=DriverManager.getConnection(url,user,password); String sql=“select user1 as 用户名,passwrd as 密码,zz as 登录身份 from ”+table;/通过取别名实现中文列名 Statement stmt=this.conn.createStatement(1005,1007
27、);/创建语句对象,1005表示结果集可滚动,对数据更新敏感,1007表示数据只读 ResultSet rset=stmt.executeQuery(sql);/执行数据查询SELECT语句 ResultSetMetaData rsmd=rset.getMetaData();/返回元数据对象 int columns=rsmd.getColumnCount();/获得列数 String columnties=new Stringcolumns;/创建列名数组 for(int j=1;j=columns;j+) columntiesj-1=rsmd.getColumnLabel(j);/获得列名
28、int rows=0; while(rset.next() /迭代遍历结果集,获得结果集总行 rows+;rset.beforeFirst();/移动指针到第一行之前,28,使用JTable显示数据查询的结果集,String results=new Stringrowscolumns;/创建二维数组保存数据结果集 for(int i=0;rset.next();i+) /从前向后访问,获得每行数据 for(int j=1;j=columns;j+) resultsij-1=rset.getString(j);/获得当前行指定列的值 rset.close(); stmt.close(); ret
29、urn new JTable(results,columnties); ,29,使用JTable显示条件查询的关键代码,public void actionPerformed(ActionEvent e)if(e.getSource()=jb )/单击查询按钮执行查找 String str=jtUser.getText(); /输入的用户名if(str.equals(“)JOptionPane.showMessageDialog(null, “查询内容不能为空!“);return;Connection conn;try/数据库连接省略conn=DriverManager.getConnecti
30、on(url,user,password);String sql;sql=“select user1 as 用户名,passwrd as 密码,zz as 登录身份 from Login where user1 like %“+str+“%“;/查询的实现并且显示在表格中参照前面的例子,此处省略return new JTable(results,columnties);catch(SQLException SQLe)System.out.println(SQLe.getStackTrace(); 或者JOptionPane.showMessageDialog(this,SQLe.toStrin
31、g(); ,30,通过ResultSet结果集更新表,通过结果集更新表,必须在创建Statement对象时指定结果集的属性即创建带参数的statement Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException; 参数resultSetType表示结果集是否可滚动,取值为 int TYPE_FORWARD_ONLY=1003/默认值,只能向后 int TYPE_SCROLL_INSENSITIVE=1004/可滚动,更新不敏感 就是如果数据库里的数据修改过,并不在Res
32、ultSet中反应出来 int TYPE_SCROLL_SENSITIVE=1005/可滚动,更新敏感 参数resultSetConcurrency表示结果集能否更新表 Int CONCUR_READ_ONLY=1007 /只读,默认值 Int CONCUR_UPDATABLE=1008/可更新 用Jtable显示数据必须用带参数的statement TYPE_SCROLL_SENSITIVE=1005/可滚动,更新敏感 例如: Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.C
33、ONCUR_READ_ONLY);,31,ResultSet接口数据敏感和可更新功能的方法,void updateRow() throws SQLException; void insertRow() throws SQLException; void deleteRow() throws SQLException;,32,添加数据的关键代码,33,添加数据的关键代码,public void actionPerformed(ActionEvent e) if (e.getSource() = jb1) if (jt1.getText().equals(“) JOptionPane.showMe
34、ssageDialog(this, “用户号不能为空“);return; if(!jt4.getText().equals(jt2.getText()JOptionPane.showMessageDialog(this,“两次密码不一致,请重新输入确认密码!“);jt4.setText(“); try /连接数据库代码省略conn = DriverManager.getConnection(url, user, password);String u = jt1.getText();String p = jt2.getText();String x = (String)jcb1.getSelec
35、tedItem();String sql = “INSERT INTO Login VALUES(“ + u + “,“ + p+ “,“ + x+ “) “;stmt = conn.createStatement();int rest = stmt.executeUpdate(sql);JOptionPane.showMessageDialog(this, “添加成功!“);jt1.setText(“);conn.close(); catch (Exception eF) JOptionPane.showMessageDialog(this, “添加失败n用户号:”+jt1.getText(
36、)+“ (已存在)”); /或者JOptionPane.showMessageDialog(this,eF.toString(); if (e.getSource() = jb2) this.dispose(); ,34,添加数据的关键代码,变量名格式为“+maxku+“ INSERT INTO Device VALUES(“ + u + ”,“ + p+ ”,0,0,“+maxku+”,“+minku+”,getDate() 字符型前后再加单引号,数值型不用加 注意完整性规则,出错后如何提示用户 JOptionPane.showMessageDialog(this, “添加失败n用户号:”+
37、jt1.getText()+“ (已存在)”); JOptionPane.showMessageDialog(this,eF.toString(); ,35,修改和删除数据,36,修改和删除数据的关键代码,修改数据的关键代码删除数据的关键代码同样需要注意参照完整性,String sql = “UPDATE Login SET passwrd=“ + p+ “ WHERE user1=“ + u + “ “; stmt = conn.createStatement(); int rest = stmt.executeUpdate(sql);,String sql = “DELETE FROM Login WHERE user1=“ + u + “ “; stmt = conn.createStatement(); int rest = stmt.executeUpdate(sql);,