1. 建立数据库连接
例1.1 使用JDBC-ODBC桥来连接一个Access数据库。
该数据库的名称为FirstExample,在ODBC数据源中的名称为forStudy,用户名和密码均为空。
package connectDataBase;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;public class connect { public static void main(String[] args) { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //加载数据库驱动 Connection con =DriverManager.getConnection("jdbc:odbc:forStudy","", ""); //这里是ODBC数据源名称 System.out.println("数据库连接成功!"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } }}
2. 关闭数据库连接
例2.1 关闭数据库连接示例。
package connectDataBase;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;public class connect { public static void main(String[] args) { Connection con = null; try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //加载数据库驱动 con =DriverManager.getConnection("jdbc:odbc:forStudy","", ""); //这里是ODBC数据源名称 System.out.println("数据库连接成功!"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }finally{ //在这里关闭数据库 if(con!=null){ try { if(!con.isClosed()) con.close(); //关闭数据库连接 System.out.println("数据库已关闭!"); } catch (SQLException e) { e.printStackTrace(); } } } }}
3. 添加新数据
一般将SQL语句存放在一个Statement对象中,然后先执行该对象的executeUpdate()方法就可以了。
例3.1 向数据库中添加新数据。
package connectDataBase;import java.sql.*;public class insertData { public static void main(String[] args) { Connection con = null; Statement sta; String sqlString = "insert into student values('30','小王','男','湖南湘潭','N-408','8293456')"; try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); con = DriverManager.getConnection("jdbc:odbc:forStudy","","");System.out.println("数据库连接成功!"); sta = con.createStatement(); sta.executeUpdate(sqlString); System.out.println("插入成功!"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { if(con!=null){ try { if(!con.isClosed()) con.close();System.out.println("数据库关闭!"); } catch (SQLException e) { e.printStackTrace(); } } } }}
一个可以接收用户输入的程序:
package connectDataBase;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.sql.*;public class insertData { public static void main(String[] args) { Connection con = null; Statement sta; String code,name,sex,address,room,tel; code = getInput("请输入编号: "); name = getInput("请输入姓名: "); sex = getInput("请输入性别: "); address = getInput("请输入地址: "); room = getInput("请输入寝室: "); tel = getInput("请输入电话: "); String sqlString = "insert into student values('"+code+"','"+name+"','"+sex+"','"+address+"','"+room+"','"+tel+"')"; try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); con = DriverManager.getConnection("jdbc:odbc:forStudy","","");System.out.println("数据库连接成功!"); sta = con.createStatement(); sta.executeUpdate(sqlString); System.out.println("插入成功!"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { if(con!=null){ try { if(!con.isClosed()) con.close();System.out.println("数据库关闭!"); } catch (SQLException e) { e.printStackTrace(); } } } } private static String getInput(String str) { String msg = ""; try { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print(str); msg = br.readLine(); } catch (IOException e) { e.printStackTrace(); } return msg; }}
单纯地通过拼接字符串的方式将程序中的变量组合成标准的SQL语句是非常容易出错的,如果字符本身中还含有双引号或单引号,转化工作就会变的更为困难。所以,java又提供了一个PreparedStatement类,该类一个重要的作用就是提供了一个“占位符”,可以方便程序员进行转换的工作。
上面的程序可以改为:
package connectDataBase;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.sql.*;public class insertData { public static void main(String[] args) { Connection con = null;// Statement sta; PreparedStatement ps; String code,name,sex,address,room,tel; code = getInput("请输入编号: "); name = getInput("请输入姓名: "); sex = getInput("请输入性别: "); address = getInput("请输入地址: "); room = getInput("请输入寝室: "); tel = getInput("请输入电话: ");// String sqlString = "insert into student values('"+code+"','"+name+"','"+sex+"','"+address+"','"+room+"','"+tel+"')"; String sqlString = "insert into student values(?,?,?,?,?,?)"; try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); con = DriverManager.getConnection("jdbc:odbc:forStudy","","");System.out.println("数据库连接成功!");// sta = con.createStatement();// sta.executeUpdate(sqlString); ps = con.prepareStatement(sqlString); ps.setString(1, code); //替换第一个占位符 ps.setString(2, name); ps.setString(3, sex); ps.setString(4, address); ps.setString(5, room); ps.setString(6, tel); ps.executeUpdate(); System.out.println("插入成功!"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { if(con!=null){ try { if(!con.isClosed()) con.close();System.out.println("数据库关闭!"); } catch (SQLException e) { e.printStackTrace(); } } } } private static String getInput(String str) { String msg = ""; try { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print(str); msg = br.readLine(); } catch (IOException e) { e.printStackTrace(); } return msg; }}
程序运行结果如下:
请输入编号: 0013请输入姓名: 张三请输入性别: 男请输入地址: 河南郑州请输入寝室: A-527请输入电话: 8723641数据库连接成功!插入成功!数据库关闭!
4. 删除数据
删除数据很简单,只要执行SQL语句中的删除命令delete即可。
package connectDataBase;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.sql.*;public class deleteData { public static void main(String[] args) { Connection con = null; Statement sta; String code= null; try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); con = DriverManager.getConnection("jdbc:odbc:forStudy","",""); code = getInput("请输入要删除的学生编号: "); String sql = "delete from student where code='"+code+"'"; sta =con.createStatement(); int k = sta.executeUpdate(sql); System.out.println("删除了"+k+"条记录,编号为:"+code); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { if(con!=null){ try { if(!con.isClosed()) con.close(); System.out.println("数据库关闭!"); } catch (SQLException e) { e.printStackTrace(); } } } } private static String getInput(String str) { String msg=null; try { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print(str); msg = br.readLine(); } catch (IOException e) { e.printStackTrace(); } return msg; }}
程序运行结果如下:
请输入要删除的学生编号: 30删除了1条记录,编号为:30数据库关闭!
5. 修改数据
使用SQL语句中的update命令就可以修改数据,下面是个简单的例子,将所有性别为“男”的记录改成女。
例5.1 修改数据示例。
package connectDataBase;import java.sql.*;public class updateData { public static void main(String[] args) { Connection con = null; Statement sta; String sql; int k; try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); con = DriverManager.getConnection("jdbc:odbc:forStudy", "", ""); System.out.println("数据库连接成功!"); sql ="update student set sex='女' where sex='男'"; sta = con.createStatement(); k = sta.executeUpdate(sql); System.out.println("修改了"+k+"条记录"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { if(con!=null){ try { if(!con.isClosed()) con.close(); System.out.println("数据库关闭!"); } catch (SQLException e) { e.printStackTrace(); } } } }}
程序运行结果如下:
数据库连接成功!修改了3条记录数据库关闭!
6. 查询数据
利用SELECT语句查询得到结果后,会将结果放在一个ResultSet集中,遍历这个集合就可以做任何需要的操作。
例6.1 先用SQL查询获取一个结果集,然后遍历这个结果集,将其中的记录输出到屏幕。
package connectDataBase;import java.sql.*;public class queryData { public static void main(String[] args) { Connection con = null; Statement sta; ResultSet rs; String code,name,sex,address,room,tel; String sql; try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); con = DriverManager.getConnection("jdbc:odbc:forStudy","",""); System.out.println("数据库连接成功!"); sta = con.createStatement(); sql = "select * from student"; rs = sta.executeQuery(sql); while(rs.next()){ code = rs.getString("code"); name = rs.getString("name"); sex = rs.getString("sex"); address = rs.getString("address"); room = rs.getString("room"); tel = rs.getString("tel"); System.out.println(code+" "+name+""+sex+" "+address+" "+room+" "+tel); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { if(con!=null){ try { if(!con.isClosed()) con.close(); System.out.println("数据库关闭!"); } catch (SQLException e) { e.printStackTrace(); } } } }}
程序运行结果如下:
数据库连接成功!0001 陈永华女 湖南长沙 N-405 131073112560012 李明女 湖南株洲 S-102 89452110013 张三女 河南郑州 A-527 8723641数据库关闭!
在上述程序中,需要先将游标执行一次next()方法,才能读取数据。这是因为游标开始的时候位于第一条记录的前面。
7. 学生信息管理系统实例
程序代码如下:
import java.awt.Container;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.*;import javax.swing.*;public class AddressList extends WindowAdapter implements ActionListener { JFrame jf; Container con; JPanel jp[]; JTextField jtf[]; JLabel jl[]; JButton firstBtn,preBtn,nextBtn,lastBtn,addBtn,editBtn,delBtn,cancelBtn,saveBtn,searchBtn; Connection conn = null; Statement sta = null; ResultSet rs = null; protected int recordState = onlyRead, curRow = 0, recordCnt = 0; public static final int onlyRead = 0, adding = 1, amending = 2; public static final String lblmsg[]={"学生姓名","学籍号","身份证件号","性别","籍贯","民族", "家庭住址","学校名称","学校标识码","年级","班级","联系电话"}; private static final int fieldCnt = 12; //在构造方法中构造界面 public AddressList(){ jf = new JFrame("学籍信息管理系统"); con = jf.getContentPane(); con.setLayout(new BoxLayout(con,BoxLayout.Y_AXIS)); jp = new JPanel[7]; for(int i=0;i<7;i++){ jp[i] = new JPanel(); jp[i].setLayout(new FlowLayout()); } jtf = new JTextField[fieldCnt]; jl = new JLabel[fieldCnt]; for(int i=0;i0) showData(); setFace(); } //打开数据库 public void connection() {// String path = this.getClass().getClassLoader().getResource("db/Student.mdb").getPath().substring(1); String path = "D:\\Student.mdb"; String url="jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ="+path; try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");// conn = DriverManager.getConnection("jdbc:odbc:Student", "", ""); conn = DriverManager.getConnection(url, "", ""); sta = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); rs = sta.executeQuery("select count(*) from student"); if(rs.next()) recordCnt = rs.getInt(1); //获取记录数 rs = sta.executeQuery("select * from student"); rs.next(); //将游标移动到第一条记录处 curRow = 1; } catch (ClassNotFoundException e) { JOptionPane.showMessageDialog(jf, "无法加载ODBC驱动"); } catch (SQLException e) { JOptionPane.showMessageDialog(jf, "数据库无法连接或没有记录"); } } //设置按钮的初始状态 protected void setFace(){ firstBtn.setEnabled(false); preBtn.setEnabled(false); nextBtn.setEnabled(true); lastBtn.setEnabled(true); addBtn.setEnabled(true); editBtn.setEnabled(true); delBtn.setEnabled(true); cancelBtn.setEnabled(false); saveBtn.setEnabled(false); } //退出系统时关闭数据库 public void windowClosing(WindowEvent e1){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } finally { System.exit(0); } } //依次在text中显示学生学籍信息(显示数据到控件中) public void showData(){ try { jtf[0].setText(rs.getString("name")); jtf[1].setText(rs.getString("stuID")); jtf[2].setText(rs.getString("IC")); jtf[3].setText(rs.getString("sex")); jtf[4].setText(rs.getString("native")); jtf[5].setText(rs.getString("nation")); jtf[6].setText(rs.getString("address")); jtf[7].setText(rs.getString("schname")); jtf[8].setText(rs.getString("schnum")); jtf[9].setText(rs.getString("grade")); jtf[10].setText(rs.getString("class")); jtf[11].setText(rs.getString("tel")); } catch (SQLException e) { JOptionPane.showMessageDialog(jf, "无法获取数据"); } } //几个辅助方法(供按钮调用) protected void setTextState(boolean flag){ //设置文本读写状态 for(int i=0;i =recordCnt){ //容错处理 nextBtn.setEnabled(false); lastBtn.setEnabled(false); curRow=recordCnt; return; } try { if(rs.next()){ //向后移动游标 showData(); curRow++; if(curRow==recordCnt){ nextBtn.setEnabled(false); lastBtn.setEnabled(false); } firstBtn.setEnabled(true); preBtn.setEnabled(true); } } catch (SQLException e) { JOptionPane.showMessageDialog(jf, "移动游标出错"); } } //"最后一条"按钮事件响应代码 protected void doMoveLast() { if(curRow>=recordCnt){ //容错处理 nextBtn.setEnabled(false); lastBtn.setEnabled(false); curRow=1; return; } try{ if(rs.last()){ //将游标移动到最后 showData(); curRow=recordCnt; nextBtn.setEnabled(false); lastBtn.setEnabled(false); firstBtn.setEnabled(true); preBtn.setEnabled(true); } } catch(SQLException e) { JOptionPane.showMessageDialog(jf, "移动游标出错"); } } //增加记录按钮事件响应代码 protected void doAdd() { if(recordState==onlyRead){ //原先是浏览状态,现在切换到编辑状态 firstBtn.setEnabled(false); preBtn.setEnabled(false); nextBtn.setEnabled(false); lastBtn.setEnabled(false); addBtn.setEnabled(true); editBtn.setEnabled(false); delBtn.setEnabled(false); cancelBtn.setEnabled(true); saveBtn.setEnabled(true); recordState=adding; setTextState(true); //将各个Text置为可写 setTextEmpty(); //将各个Text置空,准备编辑记录 }else { //原先就是编辑状态 if(doSave(false)) //先保存上次增加的记录 setTextEmpty(); //如果保存成功,准备增加下一条记录 } } //保存记录按钮事件响应代码 protected boolean doSave(boolean goViewState) { try { if(recordState==amending){ //如果是修改状态 for(int i=0;i 1){ firstBtn.setEnabled(true); preBtn.setEnabled(true); } if(curRow 0){ //如果剩余还有记录 if(curRow>=recordCnt) //如果删除的是最后一条记录 curRow=recordCnt; //否则的话,curRow的值无需改变,因为后一条记录自动成为了当前记录 rs.absolute(curRow); showData(); }else { curRow = 0; setTextEmpty(); } } catch (SQLException e) { JOptionPane.showMessageDialog(jf, "删除数据出错"); } } } //查找记录按钮事件响应代码 protected void doSearch(){ boolean b = true;; String IC = JOptionPane.showInputDialog(jf, "请输入要查找学生的身份证号:"); if(curRow<=1){ firstBtn.setEnabled(false); preBtn.setEnabled(false); curRow = 1; } try { if(rs.first()){ //移动游标到第一条记录 curRow = 1; //记录游标的新位置 //重新设置按钮状态 firstBtn.setEnabled(false); preBtn.setEnabled(false); nextBtn.setEnabled(true); lastBtn.setEnabled(true); } while(b&&IC!=null){ if(rs.getString("IC").equals(IC)){ try { jtf[0].setText(rs.getString("name")); jtf[1].setText(rs.getString("stuID")); jtf[2].setText(IC); jtf[3].setText(rs.getString("sex")); jtf[4].setText(rs.getString("native")); jtf[5].setText(rs.getString("nation")); jtf[6].setText(rs.getString("address")); jtf[7].setText(rs.getString("schname")); jtf[8].setText(rs.getString("schnum")); jtf[9].setText(rs.getString("grade")); jtf[10].setText(rs.getString("class")); jtf[11].setText(rs.getString("tel")); } catch (SQLException e) { JOptionPane.showMessageDialog(jf, "无法获取数据"); } return; }else{ if(curRow>=recordCnt){ curRow=recordCnt; b = false; JOptionPane.showMessageDialog(jf, "数据库中没找到该记录!"); } else{ if(rs.next()){ //向后移动游标 curRow++; if(curRow==recordCnt){ nextBtn.setEnabled(false); lastBtn.setEnabled(false); } firstBtn.setEnabled(true); preBtn.setEnabled(true); } } } } } catch (SQLException e) { JOptionPane.showMessageDialog(jf, "移动游标出错"); } } //actionPerformed()方法 public void actionPerformed(ActionEvent e){ Object obj; obj = e.getSource(); if(obj == firstBtn){ doMoveFirst(); }else if(obj == preBtn){ doMovePrevior(); }else if(obj == nextBtn){ doMoveNext(); }else if(obj==lastBtn){ doMoveLast(); }else if(obj==addBtn){ doAdd(); }else if(obj==saveBtn){ doSave(true); }else if(obj==editBtn){ doEdit(); }else if(obj==cancelBtn){ doCancel(); }else if(obj==delBtn){ doDelete(); }else if(obj==searchBtn){ doSearch(); } } public static void main(String[] args){ new AddressList(); }}