Java数据库编程

应数据库课程作业要求,用Java编写了一个简单的图形界面化数据库查询程序,实际用于数据库编程的时间并不多,大部分时间都在做界面开发了。下面就分享一下开发经历和其中的一些坑。

环境配置

1. 数据库服务器操作系统:      Windows10(把自己的笔记本当做数据库服务器,然后用数据库客户端连接localhost)

2. 数据库服务器:                    MySQL 8.0.13

3. 图形界面框架:                    Java Swing(jdk1.8)

4. JDBC:                                 mysql-connector-java-8.0.12.jar

环境配置中的坑主要在于MySQL的安装。安装过程我主要参考的是菜鸟教程 | MySQL 安装。

  • 首先要注意的是安装需要以管理员身份运行命令行工具。
  • 然后要特别注意MySQL 5.7以后的版本下载下来如果有data目录的话,要删掉原来的data目录(如果没有data目录就不用删了),然后在命令行工具中执行下面的命令,该命令会自动生成data目录以及其中的文件。
mysqld --initialize-inseure

 

  • 安装完成后,可以为mysql配置环境变量,这样任何地方的cmd都能进入mysql,进入命令为
mysql -u  -p

然后按要求输入密码即可。

  • 以管理员身份运行CMD命令提示符中输入net start mysql开启mysql服务,输入net stop mysql关闭mysql服务
  • 进入mysql后,作为测试,可以输入"SELECT Version();"查看mysql版本(注意SQL命令后面都需要跟分号;)

Java数据库编程_第1张图片

 

数据库编程

以下例子比较完整的展示了Java数据库编程的要点:

package testsql;

import java.sql.*;

public class Test {
	
    static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";  // jdbc driver name
    static final String DB_URL = 
    		"jdbc:mysql://localhost:3306/DATABASE_HOMEWORK?useSSL=false&serverTimezone=UTC";
    // url = jdbc:mysql://$IP:$PORT/$DATABASENAME?useSSL=false&serverTimezone=UTC (for connector-java-8.0)
 
    static final String USER = "root";	// mysql username
    static final String PASS = "";		// mysql password
 
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try{
            // register jdbc driver
            Class.forName(JDBC_DRIVER);
        
            // open connection
            System.out.println("Connecting database...");
            conn = DriverManager.getConnection(DB_URL,USER,PASS);
        
            // execute query
            System.out.println(" create statement object...");
            stmt = conn.createStatement();
            String sql;
            sql = "SELECT SNO, SNAME, SADDRESS FROM SUPPLIER";
            ResultSet rs = stmt.executeQuery(sql);
        
            // show query response
            while(rs.next()){
                // fetch by field
                int sno  = rs.getInt("SNO");
                String sname = rs.getString("SNAME");
                String saddress = rs.getString("SADDRESS");
    
                // print data
                System.out.print("SNO: " + sno);
                System.out.print(", Name: " + sname);
                System.out.print(", Address: " + saddress);
                System.out.print("\n");
            }
            // close
            rs.close();
            stmt.close();
            conn.close();
        }catch(SQLException se){
            // handle jdbc error
            se.printStackTrace();
        }catch(Exception e){
            // handle Class.forName error
            e.printStackTrace();
        }finally{
            // free resource
            try{
                if(stmt!=null) stmt.close();
            }catch(SQLException se2){
            }// do nothing
            try{
                if(conn!=null) conn.close();
            }catch(SQLException se){
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }
}

其中的坑点在于mysql-connector-java-8.0以上版本在DB_URL中需要指定useSSL和serverTimezone,即代码中的

static final String DB_URL = "jdbc:mysql://localhost:3306/DATABASE_HOMEWORK?useSSL=false&serverTimezone=UTC";

图形界面编程

      图形界面编程使用Java Swing。目前Java已有一些工具支持图形化界面编程,但本文仍然通过调用Swing库的各个控件类和布局类编写界面。为控件添加事件监听器(ActionListener)可以实现事件响应。

       整体思路是用两个下拉菜单控件(JComboBox)控制查询的类型和查询条件,组合成SQL语句通过JDBC得到查询结果,用表格(JTable)展示查询结果。将JTable绑定到DefaultTableModel类的实例dataModel,当dataModel发生变化时,表格(JTable)会自动刷新显示。

源代码

package gui;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class DBGUI extends JFrame {

	private static final long serialVersionUID = 1L;	// default serial version UID
	private Vector t_title = new Vector();		// data title for dataModel
	private Vector> t_data = new Vector>();	// data list for dataModel
	DefaultTableModel dataModel = new DefaultTableModel(); 		// dataModel for table_viewer
	private JLabel label_query_item = new JLabel("Query item: ");
	private JLabel label_query_content = new JLabel("Query content: ");
	private final String[] str_query_item = {"查询1", "查询2", "查询3", "查询4", "查询5"};
	private JComboBox combo_query_item = new JComboBox(str_query_item);
	private JComboBox combo_query_content = new JComboBox();
	private JButton btn_query = new JButton("Query!");
	private JTable table_viewer = new JTable(dataModel);
	private Connection conn = null;
	
	public static void main(String args[])
	{
		DBGUI myapp = new DBGUI();
        myapp.setMinimumSize(new Dimension(750, 500));
        myapp.setVisible(true);
        myapp.setResizable(false);
	}
	
	public DBGUI()
	{
		super("Database Query GUI by weiyuxuan");
		
		// top: ComboBoxes and button
		JPanel control_panel = new JPanel();
		control_panel.setLayout(new FlowLayout());
		control_panel.add(label_query_item);
		control_panel.add(combo_query_item);
		control_panel.add(label_query_content);
		control_panel.add(combo_query_content);
		control_panel.add(btn_query);
		
		// Medium: Static text field
		JPanel text_panel = new JPanel();
		String[] texts = {"查询1:给出为工程(Query content)提供零件的全部供应商名",
						  "查询2:给出使用供应商(Query content)所供零件的全部工程名",
						  "查询3:给出使用颜色(Query content)零件的工程名",
						  "查询4:给出住在某地(Query content)而为不在该地、且不使用红色零件的工程提供零件的供应商名",
						  "查询5:给出使用供应商(Query content)供应的全部零件的工程名"	
		};
		StringBuilder sb = new StringBuilder();	// use StringBuilder to concatenate strings
		sb.append("");				// use html in JLabel
		for (String text : texts)
		{
			sb.append(text);
			sb.append("
"); } sb.append(""); text_panel.add(new JLabel(sb.toString())); // Bottom: Table viewer JPanel table_panel = new JPanel(); table_panel.add(table_viewer.getTableHeader()); table_panel.add(new JScrollPane(table_viewer)); // Whole JPanel container = new JPanel(); container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS)); container.add(control_panel); container.add(text_panel); container.add(table_panel); this.add(container); connectDB(); // close sql connection when window closed this.addWindowListener(new WindowAdapter( ) { public void windowClosing(WindowEvent e) { try { if (conn != null) { conn.close(); } } catch (SQLException se) { se.printStackTrace(); } System.exit(0); } }); setActionListener(); } private void connectDB() { final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver"; // jdbc driver name final String DB_URL = "jdbc:mysql://localhost:3306/DATABASE_HOMEWORK?useSSL=false&serverTimezone=UTC"; final String USER = "root"; final String PASSWORD = ""; try { Class.forName(JDBC_DRIVER); conn = DriverManager.getConnection(DB_URL,USER, PASSWORD); } catch (SQLException se) { System.out.println("SQLException encountered when creating connection"); se.printStackTrace(); } catch (ClassNotFoundException cnfe) { cnfe.printStackTrace(); } } private void setActionListener() { combo_query_item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String sql = "SELECT PNO FROM PROJECT"; String key; combo_query_content.removeAllItems(); switch(combo_query_item.getSelectedIndex()) { case 0: System.out.println("查询1"); sql = "SELECT DISTINCT PNO FROM PROJECT"; break; case 1: System.out.println("查询2"); sql = "SELECT DISTINCT SNO FROM SUPPLIER"; break; case 2: System.out.println("查询3"); sql = "SELECT DISTINCT COLOR FROM COMPONENT"; break; case 3: System.out.println("查询4"); sql = "SELECT DISTINCT SADDRESS FROM SUPPLIER"; break; case 4: System.out.println("查询5"); sql = "SELECT DISTINCT SNO FROM SUPPLIER"; break; default: System.out.println("查询1"); sql = "SELECT DISTINCT PNO FROM PROJECT"; break; } try { Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { key = rs.getString(1); // 1 refers to the first column combo_query_content.addItem(key); } rs.close(); stmt.close(); } catch (SQLException e_stmt) { System.out.println("SQLException encountered when using SQL Statement"); e_stmt.printStackTrace(); } } }); btn_query.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int line = 0; String sql = "SELECT PNO FROM PROJECT"; String key = (String) combo_query_content.getSelectedItem(); switch(combo_query_item.getSelectedIndex()) { case 0: sql = "SELECT DISTINCT SNAME " + "FROM SUPPLIER, SUPPLY " + "WHERE SUPPLIER.SNO=SUPPLY.SNO AND SUPPLY.PNO=" + key; break; case 1: sql = " SELECT DISTINCT PNAME " + "FROM PROJECT,SUPPLY " + "WHERE PROJECT.PNO=SUPPLY.PNO AND SUPPLY.SNO=" + key; break; case 2: sql = "SELECT DISTINCT PNAME " + "FROM PROJECT,SUPPLY,COMPONENT " + "WHERE PROJECT.PNO=SUPPLY.PNO AND COMPONENT.CNO=SUPPLY.CNO AND COLOR=" + "\"" + key + "\""; break; case 3: sql = "SELECT SNAME FROM SUPPLIER WHERE SADDRESS=" + "\"" + key + "\"" + " AND SNO IN " + "(SELECT SNO FROM SUPPLY WHERE PNO IN " + "(SELECT PNO FROM PROJECT WHERE PADDRESS!=" + "\"" + key + "\"" + " AND NOT EXISTS " + "(SELECT * FROM SUPPLY, COMPONENT " + "WHERE PROJECT.PNO=SUPPLY.PNO AND COMPONENT.CNO=SUPPLY.CNO AND COLOR=\"red\")));"; break; case 4: sql = "SELECT PNAME FROM PROJECT WHERE NOT EXISTS " + "(SELECT CNO FROM SUPPLY WHERE SNO=" + key + " AND NOT EXISTS " + "(SELECT * FROM SUPPLY WHERE SUPPLY.PNO=PROJECT.PNO));"; break; default: sql = "SELECT DISTINCT SNAME " + "FROM SUPPLIER, SUPPLY " + "WHERE SUPPLIER.SNO=SUPPLY.SNO AND SUPPLY.PNO=" + key; break; } try { Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); t_title.clear(); t_title.add(rs.getMetaData().getColumnName(1)); t_data.clear(); while (rs.next()) { key = rs.getString(1); // 1 refers to the first column t_data.add(new Vector()); t_data.get(line++).add(key); } rs.close(); stmt.close(); System.out.println(t_title); System.out.println(t_data); dataModel.setDataVector(t_data, t_title); // refresh dataModel } catch (SQLException e_stmt) { System.out.println("SQLException encountered when using SQL Statement"); e_stmt.printStackTrace(); } } }); } }

 

你可能感兴趣的:(Java,数据库,UI编程,Java,MySQL,数据库编程,JDBC,Swing)