• java_web学习(12)JDBC


    数据持久化

          持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以”固化”,而持久化的实现过程大多通过各种关系数据库来完成。持久化的主要应用是将内存中的数据存储在关系型数据库中,当然也可以存储在磁盘文件、XML数据文件中。 
                                                                               
           Java 中的数据存储技术
           在Java中,数据库存取技术可分为如下几类:1>JDBC直接访问数据库;2>JDO技术;3>第三方O/R工具,如Hibernate, ibatis 等。JDBC是java访问数据库的基石,JDO, Hibernate等只是更好的封装了JDBC。
          JDBC基础
          JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,使用这个类库可以以一种标准的方法、方便地访问数据库资源。JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。JDBC的目标是使Java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员无需对特定的数据库系统的特点有过多的了解,从而大大简化和加快了开发过程。
          JDBC体系结构
          JDBC接口(API)包括两个层次:
          1>面向应用的API:Java API,抽象接口,供应用程序开发人员使用(连接数据库,执行SQL语句,获得结果);
          2>面向数据库的API:Java Driver API,供开发商开发数据库驱动程序用。
                                                                             
           JDBC驱动程序分类
           JDBC驱动程序:各个数据库厂商根据JDBC的规范制作的 JDBC 实现类的类库 。
           JDBC驱动程序总共有四种类型:
                1>第一类:JDBC-ODBC桥。
                2>第二类:部分本地API部分Java的驱动程序。
                3>第三类:JDBC网络纯Java驱动程序。
                4>第四类:本地协议的纯 Java 驱动程序。
           第三、四两类都是纯Java的驱动程序,因此,对于Java开发者来说,它们在性能、可移植性、功能等方面都有优势。
           ODBC
           早期对数据库的访问,都是调用数据库厂商提供的专有的 API。为了在 Windows 平台下提供统一的访问方式,微软推出了 ODBC(Open Database Connectivity,开放式数据库连接),并提供了 ODBC API,使用者在程序中只需要调用 ODBC API,由 ODBC 驱动程序将调用转换成为对特定的数据库的调用请求。一个基于ODBC的应用程序对数据库的操作不依赖任何DBMS,不直接与DBMS打交道,所有的数据库操作由对应的DBMS的ODBC驱动程序完成。也就是说,不论是FoxPro、Access , MYSQL还是Oracle数据库,均可用ODBC API进行访问。由此可见,ODBC的最大优点是能以统一的方式处理所有的数据库
           1>JDBC-ODBC桥
            JDBC-ODBC 桥本身也是一个驱动,利用这个驱动,可以使用 JDBC-API 通过ODBC 去访问数据库。这种机制实际上是把标准的 JDBC 调用转换成相应的 ODBC 调用,并通过 ODBC 访问数据库。因为需要通过多层调用,所以利用 JDBC-ODBC 桥访问数据库的效率较低。在 JDK 中,提供了 JDBC-ODBC 桥的实现类(sun.jdbc.odbc.JdbcOdbcDriver)。
                                                                     
     
           2>部分本地API部分Java的驱动程序
     
           这种类型的 JDBC 驱动程序使用 Java 编写,它调用数据库厂商提供的本地 API,通过这种类型的 JDBC 驱动程序访问数据库减少了 ODBC 的调用环节,提高了数据库访问的效率,在这种方式下需要在客户的机器上安装本地 JDBC 驱动程序和特定厂商的本地 API 。

                                                                   
            3>JDBC网络纯Java驱动程序 
            这种驱动利用中间件的应用服务器来访问数据库。应用服务器作为一个到多个数据库的网关,客户端通过它可以连接到不同的数据库服务器。应用服务器通常有自己的网络协议,Java 用户程序通过 JDBC 驱动程序将 JDBC 调用发送给应用服务器,应用服务器使用本地程序驱动访问数据库,从而完成请求。
                                                                  
             4>本地协议的纯 Java 驱动程序
             多数数据库厂商已经支持允许客户程序通过网络直接与数据库通信的网络协议。这种类型的驱动程序完全使用 Java 编写,通过与数据库建立的 Socket 连接,采用具体与厂商的网络协议把 JDBC 调用转换为直接连接的网络调用。
                                                                 
           JDBC API
            JDBC API 是一系列的接口,它使得应用程序能够进行数据库联接,执行SQL语句,并且得到返回结果。
                                                                   
            Driver 接口
             Java.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同数据库厂商提供不用的实现。在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类(java.sql.DriverManager)去调用这些Driver实现。
           加载与注册 JDBC 驱动
            加载 JDBC 驱动需调用 Class 类的静态方法 forName(),向其传递要加载的 JDBC 驱动的类名,DriverManager 类是驱动程序管理器类,负责管理驱动程序,通常不用显式调用 DriverManager 类的 registerDriver() 方法来注册驱动程序类的实例,因为 Driver 接口的驱动程序类都包含了静态代码块,在这个静态代码块中,会调用 DriverManager.registerDriver() 方法来注册自身的一个实例。
           建立连接
           可以调用 DriverManager 类的 getConnection() 方法建立到数据库的连接。JDBC URL 用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到数据库的连接。JDBC URL的标准由三部分组成,各部分间用冒号分隔:jdbc:<子协议>:<子名称>
           1>协议:JDBC URL中的协议总是jdbc;
           2>子协议:子协议用于标识一个数据库驱动程序;
           3>子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库提供足够的信息.
           几种常用数据库的JDBC URL
           
           对于 Oracle 数据库连接,采用如下形式:jdbc:oracle:thin:@localhost:1521:sid
           对于 SQLServer 数据库连接,采用如下形式:jdbc:microsoft:sqlserver//localhost:1433; DatabaseName=sid
           对于 MYSQL 数据库连接,采用如下形式:  jdbc:mysql://localhost:3306/sid
          访问数据库
          数据库连接被用于向数据库服务器发送命令和 SQL 语句,在连接建立后,需要对数据库进行访问,执行 sql 语句
          在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式:
    Statement
    PrepatedStatement
    CallableStatement

          Statement

          通过调用 Connection 对象的 createStatement 方法创建该对象,该对象用于执行静态的 SQL 语句,并且返回执行结果。Statement 接口中定义了下列方法用于执行 SQL 语句:
    ResultSet excuteQuery(String sql)
    int excuteUpdate(String sql)

           ResultSet

           通过调用 Statement 对象的 excuteQuery() 方法创建该对象,ResultSet 对象以逻辑表格的形式封装了执行数据库操作的结果集,ResultSet 接口由数据库厂商实现。ResultSet 对象维护了一个指向当前数据行的游标,初始的时候,游标在第一行之前,可以通过 ResultSet 对象的 next() 方法移动到下一行。ResultSet 接口的常用方法:
    boolean next()
    getString()
    …

           数据类型转换表

                                                                   

            JDBC API 小结

            1>java.sql.DriverManager用来装载驱动程序,获取数据库连接;

            2>java.sql.Connection完成对某一指定数据库的联接;

            3>java.sql.Statement在一个给定的连接中作为SQL执行声明的容器,他包含了两个重要的子类型。

    Java.sql.PreparedSatement// 用于执行预编译的sql声明
    Java.sql.CallableStatement// 用于执行数据库中存储过程的调用
            4>java.sql.ResultSet对于给定声明取得结果的途径。
     
          SQL 注入攻击

           SQL 注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令,从而利用系统的 SQL 引擎完成恶意行为的做法。对于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement 取代 Statement 就可以了

           PreparedStatement

           可以通过调用 Connection 对象的 preparedStatement() 方法获取 PreparedStatement 对象。PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句。PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的 setXXX() 方法来设置这些参数. setXXX() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值。
           PreparedStatement vs Statement

           1>代码的可读性和可维护性.

           2>PreparedStatement 能最大可能提高性能:
               DBServer会对预编译语句提供性能优化。因为预编译语句有可能被重复调用,所以语句在被DBServer的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中就会得到执行。
              在statement语句中,即使是相同操作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存.这样每执行一次都要对传入的语句编译一次. 
             (语法检查,语义检查,翻译成二进制命令,缓存)
          3>PreparedStatement 可以防止 SQL 注入 

    数据库事务

          在数据库中,所谓事务是指一组逻辑操作单元,使数据从一种状态变换到另一种状态。为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。
          事务的操作:先定义开始一个事务,然后对数据作修改操作,这时如果提交(COMMIT),这些修改就永久地保存下来,如果回退(ROLLBACK),数据库管理系统将放弃您所作的所有修改而回到开始事务时的状态。
          事务的ACID属性
          1>原子性(Atomicity)
              原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 
          2>一致性(Consistency)
              事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
          3>隔离性(Isolation)
              事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
          4>持久性(Durability)
              持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。
           以第一个 DML 语句的执行作为开始,以下面的其中之一作为结束:
    //COMMIT 或 ROLLBACK 语句
    //DDL 或 DCL 语句(自动提交)
    //用户会话正常结束
    //系统异常终了
    //DDL: Data Definition Language 数据定义语言(用来定义数据库结构): create table; alter table; drop table; create index; drop index
    //DCL: Data Control Language 数据控制语言(用来控制数据库的访问):grant; revoke; commit; rollback; lock;
    //DML: Data Manipulation Language 数据操纵语言(用来查询与更新记录): insert; update; delete; select

           COMMIT和ROLLBACK语句的优点

           使用COMMIT 和 ROLLBACK语句,可以:1>确保数据完整性;2>数据改变被提交之前预览;3>将逻辑上相关的操作分组。

           数据完整性:存储在数据库中的所有数据值均处于正确的状态。如果数据库中存储有不正确的数据值,则该数据库称为已丧失数据完整性。数据库采用多种方法来保证数据完整性,包括外键、束约、规则和触发器

           提交或回滚前的数据状态

           改变前的数据状态是可以恢复的,执行 DML 操作的用户可以通过 SELECT 语句查询提交或回滚之前的修正,其他用户不能看到当前用户所做的改变,直到当前用户结束事务,DML语句所涉及到的行被锁定, 其他用户不能操作。

           提交后的数据状态

           数据的改变已经被保存到数据库中,改变前的数据已经丢失,所有用户可以看到结果,锁被释放, 其他用户可以操作涉及到的数据。

           提交数据

    //改变数据
    DELETE FROM employees
    WHERE  employee_id = 99999;
    1 row deleted.
    
    INSERT INTO departments 
    VALUES (290, 'Corporate Tax', NULL, 1700);
    1 row inserted.
    //提交改变
    COMMIT;
    Commit complete.

           数据回滚后的状态

           使用 ROLLBACK 语句可使数据变化失效:1>数据改变被取消;2>修改前的数据状态可以被恢复。

    DELETE FROM copy_emp;
    22 rows deleted.
    ROLLBACK;
    Rollback complete.

           JDBC 事物处理

           事务:指构成单个逻辑工作单元的操作集合;
           事务处理:保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),要么整个事务回滚(rollback)到最初状态
           当一个连接对象被创建时,默认情况下是自动提交事务:每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚.
           为了让多个 SQL 语句作为一个事务执行:
    //调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务
    //在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务
    //在出现异常时,调用 rollback(); 方法回滚事务

           批量处理JDBC语句提高处理速度 

           当需要成批插入或者更新记录时。可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率
           JDBC的批量处理语句包括下面两个方法:
    //addBatch(String):添加需要批量处理的SQL语句或是参数;
    //executeBatch();执行批量处理语句;

           通常我们会遇到两种批量执行SQL语句的情况:

    //多条SQL语句的批量处理;
    //一个SQL语句的批量传参;

           多条SQL语句的批量处理:

                                            

            一个SQL语句的批量传参:
            情景:                                                                                              解决:
                               
             Oracle LOB
             LOB,即Large Objects(大对象),是用来存储大量的二进制和文本数据的一种数据类型(一个LOB字段可存储可多达4GB的数据)。
             LOB 分为两种类型:内部LOB和外部LOB。
             1)内部LOB将数据以字节流的形式存储在数据库的内部。因而,内部LOB的许多操作都可以参与事务,也可以像处理普通数据一样对其进行备份和恢复操作。
                Oracle支持三种类型的内部LOB:BLOB(二进制数据) ,CLOB(单字节字符数据) ,NCLOB(多字节字符数据)。
                CLOB和NCLOB类型适用于存储超长的文本数据,BLOB字段适用于存储大量的二进制数据,如图像、视频、音频,文件等。
             2)目前只支持一种外部LOB类型,即BFILE类型。在数据库内,该类型仅存储数据在操作系统中的位置信息,而数据的实体以外部文件的形式存在于操作系统的文件系统中。因而,该类型所表示的数据是只读的,不参与事务。该类型可帮助用户管理大量的由外部程序访问的文件。

           MySQL BLOB 类型介绍 

           MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。MySQL的四种BLOB类型(除了在存储的最大信息量上不同外,他们是等同的)
                                                 
            实际使用中根据需要存入的数据大小定义不同的BLOB类型。需要注意的是:如果存储的文件过大,数据库的性能会下降。
           使用JDBC来写入Blob型数据到Oracle中 
           1>Oracle的Blob字段比long字段的性能要好,可以用来保存如图片之类的二进制数据。
           2>Oracle的BLOB字段由两部分组成:数据(值)和指向数据的指针(定位器)。尽管值与表自身一起存储,但是一个BLOB列并不包含值,仅有它的定位指针。为了使用大对象,程序必须声明定位器类型的本地变量。
           3>当Oracle内部LOB被创建时,定位器被存放在列中,值被存放在LOB段中,LOB段是在数据库内部表的一部分。
           4>因为Blob自身有一个cursor,当写入Blob字段必须使用指针(定位器)对Blob进行操作,因而在写入Blob之前,必须获得指针(定位器)才能进行写入
           5>如何获得Blob的指针(定位器) :需要先插入一个empty的blob,这将创建一个blob的指针,然后再把这个empty的blob的指针查询出来,这样通过两步操作,就获得了blob的指针,可以真正的写入blob数据了。 
           步骤:
    //1、插入空blob insert into javatest(name,content) values(?,empty_blob()); 
    //2、获得blob的cursor select content from javatest where name= ? for update; 注意:  须加for update,锁定该行,直至该行被修改完毕,保证不产生并发冲突。 
    //3、利用 io,和获取到的cursor往数据库写数据流

          使用 JDBC 驱动程序处理元数据

    //Java 通过JDBC获得连接以后,得到一个Connection 对象,可以从这个对象获得有关数据库管理系统的各种信息,包括数据库中的各个表,表中的各个列,数据类型,触发器,存储过程等各方面的信息。根据这些信息,JDBC可以访问一个实现事先并不了解的数据库。
    //获取这些信息的方法都是在DatabaseMetaData类的对象上实现的,而DataBaseMetaData对象是在Connection对象上获得的。 

          DatabaseMetaData类

          DatabaseMetaData 类中提供了许多方法用于获得数据源的各种信息,通过这些方法可以非常详细的了解数据库的信息:
    //getURL():返回一个String类对象,代表数据库的URL。
    //getUserName():返回连接当前数据库管理系统的用户名。
    //isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。
    //getDatabaseProductName():返回数据库的产品名称。
    //getDatabaseProductVersion():返回数据库的版本号。
    //getDriverName():返回驱动驱动程序的名称。
    //getDriverVersion():返回驱动程序的版本号。

          ResultSetMetaData 类

          可用于获取关于 ResultSet 对象中列的类型和属性信息的对象:
    //getColumnName(int column):获取指定列的名称
    //getColumnCount():返回当前 ResultSet 对象中的列数。 
    //getColumnTypeName(int column):检索指定列的数据库特定的类型名称。 
    //getColumnDisplaySize(int column):指示指定列的最大标准宽度,以字符为单位。 
    //isNullable(int column):指示指定列中的值是否可以为 null。 
    //isAutoIncrement(int column):指示是否自动为指定列进行编号,这样这些列仍然是只读的。 

    JDBC数据库连接池

           必要性:

           在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤:1>在主程序(如servlet、beans)中建立数据库连接;2>进行sql操作;3>断开数据库连接。

           这种模式开发,存在的问题:
           1>普通的JDBC数据库连接使用 DriverManager 来获取,每次向数据库建立连接的时候都要将 Connection 加载到内存中,再验证用户名和密码(得花费0.05s~1s的时间)。需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接。这样的方式将会消耗大量的资源和时间。数据库的连接资源并没有得到很好的重复利用.若同时有几百人甚至几千人在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃。
           2>对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将导致重启数据库。
           3>这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。
           数据库连接池(connection pool)
           为解决传统开发中的数据库连接问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。
           数据库连接池的工作原理
                                                                    
            数据库连接池技术的优点
            1>资源重用:由于数据库连接得以重用,避免了频繁创建,释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增加了系统运行环境的平稳性。
            2>更快的系统反应速度:数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于连接池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而减少了系统的响应时间。
            3>新的资源分配手段:对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置,实现某一应用最大可用数据库连接数的限制,避免某一应用独占所有的数据库资源
            4>统一的连接管理,避免数据库连接泄露:在较为完善的数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄露。
            两种开源的数据库连接池
            1>JDBC 的数据库连接池使用 javax.sql.DataSource 来表示,DataSource 只是一个接口,该接口通常由服务器(Weblogic, WebSphere, Tomcat)提供实现,也有一些开源组织提供实现:DBCP 数据库连接池和C3P0 数据库连接池
            2>DataSource 通常被称为数据源,它包含连接池和连接池管理两个部分,习惯上也经常把 DataSource 称为连接池
            DBCP 数据源 
            DBCP 是 Apache 软件基金组织下的开源连接池实现,该连接池依赖该组织下的另一个开源系统:Common-pool. 如需使用该连接池实现,应在系统中增加如下两个 jar 文件:
                   Commons-dbcp.jar:连接池的实现
                   Commons-pool.jar:连接池实现的依赖库
            Tomcat 的连接池正是采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。
            DBCP 数据源使用范例
            数据源和数据库连接不同,数据源无需创建多个,它是产生数据库连接的工厂,因此整个应用只需要一个数据源即可。
            当数据库访问结束后,程序还是像以前一样关闭数据库连接:conn.close(); 但上面的代码并没有关闭数据库的物理连接,它仅仅把数据库连接释放,归还给了数据库连接池。
                                                                           
           C3P0 数据源
                                                                              
           服务器自带的连接池
           JDBC的API中没有提供连接池的方法。一些常用的WEB应用服务器如WebLogic,WebSphere,Tomcat等提供了连接池实现。 
           Tomcat数据库连接池的配置:
           JDBC2.0提供了javax.sql.DataSource的接口,负责与数据库建立连接,实际应用时不需要编写连接数据库代码,直接从数据源获得数据库的连接。
           DataSource中事先建立多个数据库连接,这些数据库连接保持在数据库连接池中,当程序访问数据库时,只需要从连接池取出空闲的连接,访问数据库结束,在将这些连接归还给连接池。
           DataSource对象可由容器(Tomcat)提供,不能使用创建实例的方法来生成DataSource对象,要采用JAVA的JNDI。
           命名服务和目录服务
           命名服务(naming service) :计算机系统中的一个基本功能。命名服务是将名字和计算机中的一个对象相关联,通过名字可以方便地找到对应的对象。例如,计算机中的文件系统就包含了一个命名服务,你可以通过文件名找到对应的文件对象
           目录服务(directory service) :目录服务是命名服务的延伸,目录服务不只保存对象和对象名的匹配,而且保存这个对象的各种属性,你可以对这些属性进行查询、修改、增加、删除操作。
           JNDI 简介
           JNDI(Java Naming and Directory Interface,Java命名和目录接口)是一些标准API接口,Java程序通过这些API可以访问命名目录服务。而命名目录服务将名称和对象联系起来,使得可以用名称访问对象。
           JNDI的定义不依赖于任何独立的命名目录服务器,对于各种命名目录服务器,都可通过统一的JNDI接口调用。
           JNDI在系统运行时会在内存中构建这个一个层次结构。通过程序访问到这个JNDI管理器的InitialContext对象就拥有了这个JNDI的上下文,就可以查找要用的对象,并使用它
           JNDI接口概述
           Context:javax.naming的核心接口,指定了命名上下文。定义了基本的操作,例如添加一个名称-对象的绑定,查找绑定到特定名称的对象,显示绑定列表,移除名称-对象绑定,创建或者销毁相同类型的上下文等
    //从服务器上连接
    Context ctx=new InitialContext()
          Context.lookup():检索指定的对象 
         
          Tomcat提供了一个与JavaEE应用服务相兼容的JNDI--InitialContext实现实例(把DataSource作为一种可配置的JNDI资源来处理)。所有的入口和资源都放在JNDI命名空间里的java:comp/env段里。
                                                                      
                                                                          
            数据库的分页语句
            在编写Web应用程序等系统时,会涉及到与数据库的交互,如果数据库中数据量很大的话,一次检索所有的记录,会占用系统很大的资源,因此常常采用采用分页语句:需要多少数据就只从数据库中取多少条记录。以下是Sql Server,Oracle和MySQL的分页语句(从数据库表中的第M条数据开始取N条记录)
            SQL Server
    //从数据库表中的第M条记录开始取N条记录,利用Top关键字(如果Select语句中既有top,又有order by,则是从排序好的结果集中选择):  
    SELECT *  
    FROM ( SELECT Top N *  
    FROM (SELECT Top (M + N - 1) * FROM 表名称 Order by 主键 desc) t1 ) t2  
    Order by 主键 asc  
    //例如从表Sys_option(主键为sys_id)中从10条记录还是检索20条记录,语句如下:    
    SELECT *  
    FROM ( SELECT TOP 20 *  
    FROM (SELECT TOP 29 * FROM Sys_option order by sys_id desc) t1) t2  
    Order by sys_id asc

           Oralce数据库

           从数据库表中第M条记录开始检索N条记录:                                                例如从表employees(主键为employee_id)中从11条记录还是检索20条记录,语句如下:

                                                     

           MySQL数据库

           My sql数据库最简单,是利用mySQL的LIMIT函数,LIMIT [offset,] rows从数据库表中M条记录开始检索N条记录的语句为: 

    SELECT * FROM 表名称 LIMIT M,N

          例如从表Sys_option(主键为sys_id)中从10条记录还是检索20条记录,语句如下:  

    select * from sys_option limit 10,20 
  • 相关阅读:
    Spring MVC与JAX-RS比较与分析
    JDK历史版本下载
    第六篇:为多态基类声明虚析构函数
    第五篇:明确拒绝不想编译器自动生成的拷贝构造函数和赋值运算符重载函数
    第四篇:了解 C++ 默默编写并调用的函数
    第三篇:确保对象在被使用前的初始化
    poj 2125(最小割)
    hdu 4704(费马小定理)
    hdu 4705(树形DP)
    poj 3469(网络流模版)
  • 原文地址:https://www.cnblogs.com/Vae1990Silence/p/4713976.html
Copyright © 2020-2023  润新知