深入解析数据库编程

数据库编程

 

通过JDBC-ODBC桥连接数据库

JDBC应用

1、加载JDBC驱动程序

   在数据库应用系统调用JDDBCAPI方法之前,首先需要进行注册并装入JDBC驱动程序。在JAVA语言中java.lang.Class类中的Class.forName()方法是将指定的类装载到JAVA虚拟机(JVM)中,该方法的定义如下:

  public static ClassforName(String className)  throwsClassNotFoundException

  因为是静态方法,所以可以通过

    Class.forName("要装载的类的字符串");

  因为方法有可能抛出ClassNotFoundException异常,因此,我们将此语句用try{}catch(){}

  即:

     try

       {

          Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

       }

     catch(ClassNotFoundException e)

     {

        System.out.println(e.getMessage());

     }

 以上语句就完成了注册加载JDBC驱动程序。

经常的用法:

    //装载 MSSQL Server驱动

   Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");

    //装载MySQLJDBC驱动

   Class.forName("com.mysql.jdbc.Driverr");

    //装载OracleJDBC驱动

  Class.forName("oracle.jdbc.driver.OracleDriver");

    //jdbc:odbc

  Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

 

2、JDBC API类和接口

   当加载JDBC驱动程序成功后,java应用程序通过调用JDBC驱动程序API(应用程序接口)中的方法,建立与数据库连接,并发送SQL语句及处理数据库的返回结果。

   JDBCA API在java.sql包中提供的最主要的类和接口有:

  java.sql.DriverManager     //处理驱动程序的装载和建立新的数据库连接

  java.sql.Connection        //完成对某一指定数据库连接

  java.sql.Statement         //管理在一指定数据库连接上的sql语句的执行

  java.sql.ResultSet         //从数据库返回的结果集

 

3、JDBC URL

     URL(统一资源定位)提供了在Internet上定位资源所需的信息,它提供了一个计算机的网络地址,在网络数据库中,数据库的定位有JDBCURL来确定的,它提供了标识数据库的方法,该方法可以使相应的驱动程序识别数据库并与之建立连接。

     JDBCURL除了确定数据库的地址外,还含有确定与数据库连接的协议等信息。

     JDBCURL使用的标准语法:

    jdbc:<子协议>:<子名称>

协议:jdbc表示协议,它是唯一的,JDBC只有这一种协议.

子协议:主要用于识别数据库驱动程序,也就是说,不同的数据库驱动程序的子协议不同.

如: jdbc : odbc : student

 

     例如:  String url="jdbc:odbc:dataName";//dataName是数据源名

 

4、连接数据库

先介绍一下DriverManager

   作用:用于对数据库驱动程序的管理、注册、注销以及连接等主要功能是可以自动为数据库访问加载合适的驱动程序,进行数据库的连接。

 DriverManager(驱动程序管理器)类是JDBC(java数据库连接)的管理层,作用于用户和驱动程序之间.DriverManager类跟踪可用的驱动程序,并在数据库和相应驱动程序之间建立连接.

  当DriverManager激发getConnection()方法时,DriverManager类首先从它已加载的驱动程序池中找到一个可以接受该数据库URl的驱动程序,然后请求该驱动程序使用相关的数据库URl去连接到数据库中,于是,getConnection()方法建立了与数据库的连接.

  DriverManager 类包含一系列的驱动程序类,这些驱动程序类已通过调用方法DriverManager.registerDriver 对自己进行注册.所有的驱动程序类都必须包含一个静态部分.这个静态部分创建该类的实例,然后在加载该实例的DriverManager类时进行注册.这样,用户在正常情况下讲不会直接调用DriverManager.registerDriver方法,而是在加载驱动程序时由驱动程序自动调用.

可以通过两种不同的方法来注册一个驱动程序.

(1) 调用方法Class.forName.

 这将显示地加载驱动程序类.由于这于外部设置无关,因此推荐使用这种加载驱动程序的方法,

(2) 这种方法不(3)    是常用,在此不(4)    做详细说明.

 不管是用哪一种方法,新加载的Driver类都要通过调用DriverManager.registerDriver方法进行自我注册.加载类时自动执行这一过程.

在DriverManager中有一个非常重要的方法,就是getConnection(),在编程中通过这个方法获得一个连接.

 Static Connection getConnection(String url,String user,String password):连接到指定URl的数据库,使用用户名为user,密码为password.

Connection con=DriverManager.getConnection("jdbc:jtds:sqlServer://localhost/数据库名","用户名","密码");

定义:

public class DriverManager

方法:

public static synchronized ConnectiongetConnection(String url) throws SQLException

public static synchronized ConnectiongetConnection(String url, String user, String password) throws SQLException

public static synchronized Connection getConnection(String url) throws SQLException

public static synchronized Connection getConnection(String url,java.util.Properties info) throws SQLException

public static synchronized void registerDriver(java.sql.Driverdriver)throws SQLException(注册指定的驱动程序)

public static synchronized void deregisterDriver(Driver driver)     throws SQLException (注销指定的驱动程序)

......

 

 

 

例如: 

     try{

          Connection con=DriverManager.getConnection(url,"user","password");//连接数据库

 

        }

     catch(SQLException e)

     {

        System.out.println(e.getMessage());

     }

 

 

  Connection接口 Connection对象代表与数据库的连接,也就是在已经加载的Driver和数据库之间建立连接.你必须建立一个Connection class的实例,其中包括你的数据库的信息.

  连接过程包括所执行的SQL语句和在该连接上所返回的结果.一个应用程序可与单个数据库有一个或多个连接,或者可与许多数据库有连接.

 DiverManager的getConnection()方法,将建立在JDBC URL中定义的数据库的Connection连接上:

Connectioncon=DriverManager.getConnection("jdbc:jtds:sqlServer://localhost/数据库名","用户名","密码");

 能够锁定表、提交和恢复数据、断开连接等功能。

定义:

    publicinterface Connection

 

   Statement createStatement() throws SQLException;

    PreparedStatementprepareStatement(String sql) throws SQLException;

    voidcommit() throws SQLException;//提交数据,该数据永久性改变不能恢复

    voidrollback() throws SQLException;//放弃上次提交后的数据修改

    voidclose() throws SQLException;//关闭数据库连接

 

通用格式:

 

 

   try

    {

       Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

        Stringurl="jdbc:odbc:student";

        connectioncon=DriverManager.getConnection(url,"","");

       statement=con.createStatement();

        String sql="select *from studenttable";

        rset=statement.executeQuery(sql);

        ResultSetMetaDatadata=rset.getMetaData();

        intcol=data.getColumnCount();//获得列数

        for(int i=1;i<=col;i++)

        {

           if(i<col)

           {

               System.out.print(data.getColumnName(i)+" ");

            }

           else

            {

               System.out.println(data.getColumnName(i);

            }

         }

         while(rset.next())

          {

             for(inti=1;i<=col;i++)

              {

                if(i<col)

                   {

                      System.out.print(rset.getString(i)+" ");

                   }

                  else

                    {

                        stem.out.print(rset.getString(i));

                     }

              }

           }

         rset.close(); 

    }

     catch(Exception e)

     {}

 

4.Statement

 

  java.sql.Statement 提供在基层连接上运行SQl语句,并且访问结果.Connection接口提供了生成Statement的方法,一般情况下,我么通过connection.createStatement()方法就可以得到Statement的实例.

 下面是一些常用的方法:

 

execute():      运行语句,返回是否有结果集.也就是说当执行SQL语句时如果返回ResultSet对象则返回true.如果返回int 则返回false

executeQuery(String sql): 运行查询语句,返回一个ResultSet对象.

executeUpdate(String sql):运行更新操作,返回更新的行数.执行insert,update,delete返回受影响的行数.

 

 

5.PreparedStatement

   在实际数据库应用中,经常需要多次执行同一条语句,当数据库只处理一次SQL语句就可以多次反复执行,则会减小数据库处理的时间.

例如:

           Connectioncon = DAOFactory.getConnection();

        String sql = "insert into studenttable1 values(?,?,?)";

        PreparedStatement statement =con.prepareStatement(sql);       

        statement.setString(1, item.getName());

        statement.setString(2, item.getSex());

        statement.setString(3, item.getAge());

        statement.executeUpdate();

 

 

6.ResultSet

 

  Statement执行SQL语句时,有时会返回ResultSet结果集.ResultSet往往包含的是查询的结果集.此接口抽象了运行SELECT语句的结果,提供了逐行访问的方法,通过它访问结果的不同字段.结果集一般是一个表,其中有查询所返回的列标题及相应的值.

  通过ResultSet.next()方法把当前的指针向下移动一位.最初它位于第一行之前,因此第一次调用next将把指针置于第一行上,使它成为当前行.随着每次调用next导致指针向下移动,按照从上至下的次序获取ResultSet行.

 

  java.sql.ResultSet提供了检索不同类型字段的方法,最常用的方法如下:

   

  getString():获得在数据库里是varchar,char等数据类型的对象.

  getFloat(): 获得在数据库里是Float数据类型的对象.

  getDouble():获得在数据库里是Double Precision数据类型的对象.

  getDate(): 获得在数据库里是Date数据类型的对象.

  getBoolean():获得在数据库里是Boolean数据类型的对象.

  getObject():在SQL中无对应类型,可以获得序列化对象等.

  getBlob(): 获得在数据库里是Blob(二进制大型对象)数据类型的对象.

  getClob(): 获得在数据库里是Clob(字符串大型对象)数据类型的对象.

 

顺序查询:

    next()

 

 游标查询:

    publicboolean previous()//将游标向上移动,该方法返回boolean,当游标移动到结果集第一行之前,返回false;

    publicvoid beforeFirst()将游标移动到结果集的初始位置,即在第一行之前

    publicvoid afterLast()将游标移动到结果集的最后一行之后

    pulbicvoid first()//将游标移到结果集的第一行

    publicvoid last()//将游标移到结果集的最后一行

    publicboolean isAfterLast()//判断游标是否在最后一行之后

    publicboolean isBeforeFirst()///判断游标是否在第一行之之前

    pulbicboolean first()//判断游标是否移到结果集的第一行

    publicboolean last()//判断游标是否移到结果集的最后一行

   public  int getRow()//得到当前游标所指向行的行号.如果结果集没有行,返回0

    publicboolean absoloute(int row)//将游标移动到指定的(row)行号.如果row取负值,就是倒数的行数.absoloute(-1)表示移动到最后一行.当为-2表示倒数第二行.当移到最后一行之后,或第一行之前,则返回false.

 

如果用游标查询的话,必须按如下方法:

    Statement stmt=con.createStatement(int type,int concurrency);

    根据不同的参数返回相应类型的结果集.

    type的取值决定滚动方式:

 

TYPE_FORWARD_ONLY   //  结果集中的游标只能向下移动

TYPE_SCROLL_INSENSITIVE   //  结果集中的游标可以上下移动,当数据库变化时候,当前结果集不变.

 

TYPE_SCROLL_SENSITIVE  //  结果集中的游标可以上下移动,当数据库变化时候,当前结果集不变.

 

concurrency:是否可以用结果集更新数据库

CONCUR_READ_ONLY  //  不能用结果集更新数据库中的数据

CONCUR_UPDATABLE   // 能用结果集更新数据库中的数据

使用游标查询的例子:

 

            Connection con = DAOFactory.getConnection();

         Statementstatement = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);

         String sql = "select name,sex,age from studenttable1 ";     //where sex='m'";  

         ResultSetrs = statement.executeQuery(sql);    

         rs.last();//将游标移动到最后一行

         intlow=rs.getRow();//等到行数

         rs.absolute(1);

         for(int i=1;i<low;i++)

        {

         rs.absolute(i);

         System.out.print(rs.getString(1));

         System.out.print(rs.getString(2));

         System.out.print(rs.getString(3));

         System.out.println();

        }

       

 

 

 

 

一、查询

1、查询数据库

   select 语句的基本格式为:

   select 列名1,列名2,列名3 ...from  表名

如果查询所有列可以用*代替。

 

    如: select * from 表名。

 

 

 

2、使用参数查询数据库

  select 列名1,列名2,列名3 ...from  表名 [where 条件]

 

3、排序查询

  select * from 表名 order by 字段名

 

4、使用通配符查询

   可以用like进行模式匹配,使用"%"代替一个或多个字符,用下划线"_"代替一个字符。

   例如:

       select * from 表名 where 姓名 like 'k%'

 

二、更新记录

    update 表名 set 列名=''  where 列名=''

  //数据必须用单引号括起来,如果是数字的话''可以省掉不写

 

三、添加记录

    insertinto 表名 values('','','');

 

四、删除记录

   deletefrom 表名 where 列名=''

 

例题:

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.SQLException;

 

import java.sql.*;

public class TestDatabase{

 

    Connection con;

    String url="jdbc:odbc:student";

    String user="";

    String pass="";

    static

    {

        try{

            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

        } catch (ClassNotFoundExceptione) {

            // TODO自动生成 catch

            e.printStackTrace();

        }

    }

    private  Connection getCon() throwsSQLException

    { 

       con=DriverManager.getConnection(url,user,pass);             

       returncon;

    }

   

    public  voidselectMethod() throwsSQLException

    {

       String sql="select * fromstudenttable2";

            //"select *from studenttable1";

       //"select* from studenttable1 where sex=''";

       //"select* from studenttable1 where age>='20'";

      //"select * from studenttable2  whereage=12"; 

       //"select* from studenttable2 order by age";

       //"select* from studenttable2  where name like '%'";

       con=getCon();

       Statementstmt=con.createStatement();

       ResultSetrs=stmt.executeQuery(sql);

       while(rs.next())

       {

          System.out.print(rs.getString(1)+");

          System.out.print(rs.getString(2)+");

          System.out.print(rs.getString(3)+");

        System.out.println();

      

       }

         rs.close();

         stmt.close();

         con.close();

   

    }

   

    publicvoid updateMethod()throws SQLException   

    {

       

        String sql=" update studenttable2 set name='谢立'  where name='谢立明'";

            con=getCon();  

            Statement stmt= con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

                                                                   //此处必须这么写        

            stmt.executeUpdate(sql);

            stmt.close();

            con.close(); 

   

    }

    publicvoid insertMethod()throws SQLException

    {

        String sql="insert into studenttable2 (name,sex,age) values('谢立明','男',35)";

               

            con=getCon();  

            Statement stmt=con.createStatement();

            stmt.executeUpdate(sql);

            stmt.close();

            con.close();

   

    }

   

   

   

    publicvoid deleteMethod()throws SQLException

    {

             String sql="delete  from studenttable2  where name='谢立'";

            con=getCon();  

            Statement stmt= con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

                                                                    //此处必须这么写        

            stmt.executeUpdate(sql);

            stmt.close();

            con.close(); 

   

   

    }

   

    public void insertMethod1()throws SQLException

        {

            String sql="insert intostudenttable2 (name,sex,age) values(?,?,?)";

               

                con=getCon();  

                PreparedStatement pstmt=con.prepareStatement(sql);

                pstmt.setString(1,"李刚");

                 pstmt.setString(2,"");

                pstmt.setInt(3,17);               

                pstmt.executeUpdate();

                pstmt.close();

                con.close();   

        }

   

   

    public static voidmain(String[] args)

    {

          TestDatabaset=newTestDatabase();

          try{

             t.insertMethod1();

                t.selectMethod();

 

        } catch (SQLExceptione) {

            // TODO 自动生成 catch 块

            e.printStackTrace();

        }

    }

}

 

 

如果我们将上面的例子理解了。

我们介绍这个实例需要用到Vector,JTable 和AbstractTableModel

1、Vector类

   隶属于java.util包。不要求每个元素的类型相同,向量中可以混合多种对象类性。可以动态的增加元素。

 

    public class Vector extendsAbstractList implements List,Cloneable,Serializable

    public Vector()//创建一个空的Vector对象

    public Vector(Collection c) //构件一个包含集合的Vector,我们要用到它

    public void add(int index,Objectelement)//在index位置插入element

    public void addElement(Objectobj)  //在Vector的尾部添加obj对象

    publicvoid removeAllElements()//删除Vector对象中的所有元素

    publicint size()//返回Vector对象的元素个数。

 

 

2、JTable

   隶属于javax.swing它以2维表的形式显示数据

 publicJTable()

 pulbicJTable(TableModel dm)//以dm为数据模型默认的列模型,默认的选择模型建立一个JTable 对象

 public voidsetToolTipText(String text)//设置工具提示信息,当光标在组件附近提示text信息

 public voidsetAutoResizeMode(int mode)//设置表格自动调整尺寸模式

 public voidsetCellSelectionEnabled(boolean cellSelectionEnabled)//设置表格是否允许行选择和列选择同时存在

 public voidsetShowHorizontalLines(boolean showHorizontalLines)//设置表格是否显示单元格之间的水平线

 public voidsetShowVerticalLines(boolean showVerticalLines)//设置表格是否显示单元格之间的垂直线

 

3、AbstractTableModel类

   是一个抽象类,在应用系统时需要在程序中实现它。

   public abstract classAbstractTableModel extends Object implements TableModel,Serializable

   public AbstractTableModel()//构造器

   public int getColumnCount()//返回模型列的个数

   public String getColumnName(intcolumn)     //返回列名

    public booleanisCellEditable(int rowIndex, int columnIndex) //设置单元格不可编辑

    public void setValueAt(ObjectaValue, int rowIndex, int columnIndex) //把单元格的设置为aValue

    publicvoid fireTableStructureChanged() //

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值