posts - 2, comments - 0, trackbacks - 0, articles - 0

2005年10月21日


1.通过接口可以实现不相关的类的相同行为.
2.通过接口可以指明多个类需要实现的方法.
3.通过接口可以了解对象的交互方法而不需要了解对象所对应的类蓝本.


一个普通数据库的连结过程为:
    1.加载驱动程序.
    2.通过DriverManager到得一个与数据库连结的句柄.
    3.通过连结句柄绑定要执行的语句.
    4.接收执行结果.
    5.可选的对结果的处理.
    6.必要的关闭和数据库的连结.

Class.forName方法是先在内存中溶解签名为"org.gjt.mm.mysql.Driver"的Driver类,Driver类就会把相应的实现类对应到JDBC API的接口中.注册驱动程序有多方法,Class.forName();是一种显式地加载.当一个驱动程序类被Classloader装载后,在溶解的过程中,DriverManager会注册这个驱动类的实例.这个调用是自动发生的,也就是说DriverManager.registerDriver()方法被自动调用了

在成功注册驱动程序后,我们就可以用DriverManager的静态方法getConnection来得到和数据库连结的引用:
    Connection conn = DriverManager.getConnection(url);
    如果连结是成功的,则返回Connection对象conn,如果为null或抛出异常,则说明没有
和数据库建立连结.

如果我们要对数据库中的表进行操作,要先缘故绑定一个语句:
    Statement stmt = conn.createStatement();
    然后利用这个语句来执行操作.根本操作目的,可以有两种结果返回,如果执行的查询
操作,返回为结果集ResultSet,如果执行更新操作,则返回操作的记录数int.
    注意,SQL操作严格区分只有两个,一种就是读操作(查询操作),另一种就是写操作(更
新操作),所以,create,insert,update,drop,delete等对数据有改写行为的操作都是更新操作.

关于Statement对象:
      前面说过,Statement对象是用来绑定要执行的操作的,在它上面有三种执行方法:即用来执行查询操作的executeQuery(),用来执行更新操作的executeUpdate()和用来执行动态的未知的操作的execute().一个Statement对象同时只能有一个结果集在活动.这是宽容性的,就是说即使没有调用ResultSet的close()方法,只要打开第二个结果集就隐含着对上一个结果集的关闭.所以如果你想同时对多个结果集操作,就要创建多个Statement对象,如果不需要同时操作,那么可以在一个Statement对象上须序操作多个结果集

 Statement的两个子类:
    PreparedStatement:对于同一条语句的多次执行,Statement每次都要把SQL语句发送给数据
库,这样做效率明显不高,而如果数据库支持预编译,PreparedStatement可以先把要执行的语句一次发
给它,然后每次执行而不必发送相同的语句,效率当然提高
PreparedStatement ps = conn.prepareStatement("select * from 表 where 字段=?");
    ps.setString(1,参数);
    ResultSet rs = ps.executeQuery();
   
    CallableStatement:是PreparedStatement的子类,它只是用来执行存储过程的.
    CallableStatement sc = conn.prepareCall("{call query()}");
    ResultSet rs = sc.executeQuery();

ResultSet对象实际维护的是一个二维指针,第一维是指向当前行,最初它指向的是结果集的第一行之前,所以如果要访问第一行,就要先next(),以后每一行都要先next()才能访问,然后第二维的指针指向列,只要当你去rs.getXXX(列)时,才通过Connection再去数据库把真实的数据取出来,否则没有什么机器能真的把要取的数据都放在内存中.

如果有记录又不知道是多少行,这时如果要对有记录和没有记录进行不同的处理,应该用以下流程进行判断:

    if(rs.next()){
        //因为已经先next()了,所经对记录应该用do{}while();来处理
        do{
            int i = rs.getInt(1);
            String a = rs.getString("a2");
        }while(rs.next());
    }
    esle{
        System.out.println("没有取得符合条件的记录!");
    }

获取结果集的信息:
    大多数情况下编程人员对数据库结构是了解的,可以知道结果集中各列的情况,但有时并
不知道结果集中有哪些列,是什么类型.这时可以通过getMetaData()来获取结果集的情况:

    ResulSetMetaData rsmd = rs.getMetaData();
    rsmd.getColumnCount()返回列的个数.
    getColumnLabel(int)返回该int所对应的列的显示标题
    getColumnName(int)返回该int所对应的列的在数据库中的名称.
    getColumnType(int)返回该int所对应的列的在数据库中的数据类型.
    getColumnTypeName(int)返回该int所对应的列的数据类型在数据源中的名称.
    isReadOnly(int)返回该int所对应的列是否只读.
    isNullable(int)返回该int所对应的列是否可以为空

posted @ 2005-10-21 16:57 大雄 阅读(176) | 评论 (0)编辑 收藏

http://www.cnjsp.org/view.jsp?column=2&id=12
使用连结池的意义 (2003-11-26 18:50)

一个普通的连结过程中,因为Connection一般要用到本地方法,这些初始化是非常耗用系统资源的,说明在一次连结中真正执行语消耗的资源是很少的.

如果你的服务器平均每5分种才有一次连结,你当然只用这种普通连结,因为整个一次连结过程才0.0几秒,你不必要再让连结池在余下的4.9几秒中也开着消耗资源,但如果每秒种有10次连结,这时普通连结消耗的初始化资源就很高了,用连结池就能显示它的优势.所以到底采用什么方式连结,完全要根据你的应用,而且要进行实实在在的并发仿真测试.不要看到书上说什么方式好就相信,真正的构架一个平台是一种艺术而不只是一种技术,要多方面综合测试找到最佳的组合.很多陷井并不是技术所能发现的.比如你查看你的JVM还有很多空闲资源,但系统却已经崩溃了.因为象连结初始化这种资源消耗在本地方法中,JVM是反映不出来的,但却在同一物理内存中,还有很多这样的陷井,重要的是经验和测试!

posted @ 2005-10-21 16:56 大雄 阅读(146) | 评论 (0)编辑 收藏