[toc]
7.1 JDBC技术概述
JDBC是Java程序访问数据库的标准,它是由一组Java语言编写的类和接口组成,这些类和接口统称为JDBC,它为Java提供一种通用的数据访问接口。
JDBC的基本功能包括: 建立与数据库的连接;发送SQL语句;处理数据库操作接口。
7.1.1 数据库访问的两层和三层模型
两层模型即客户-数据库服务器结构,也就是通常所说的C-S结构。在两层模型中,Java应用程序通过JDBC API直接和数据源交互。
三层模型是指客户-应用服务器-数据库服务器结构,也就是通常所说的B-S结构。在三层模型中,客户机通过Java小程序或浏览器发出SQL请求,该请求首先传输到应用服务器,应用服务器再通过JDBC与数据库服务器进行连接,由数据库服务器处理SQL语句,然后将结果返回给应用服务器,再由应用服务器将结果发送给客户机。
在Java程序中可以使用的数据库举动程序主要有四种类型,常用的有以下两种:
- JDBC-ODBC桥驱动程序(性能不高)
- 为了与Microsoft的ODBC连接而设计的。
- 专为某种数据库驱动而编写的驱动程序
- 应用程序通过JDBC驱动程序管理加载相应的驱动程序,通过驱动程序与具体的数据库连接,然后访问数据库。
7.1.3 安装JDBC驱动程序
使用JDBC-ODBC桥驱动程序连接数据库,不需要安装驱动程序,因为在Java API中已经包含该驱动程序。
使用专用驱动程序连接数据库,必须安装驱动程序。不不同的数据库系统提供了不同的数据库驱动程序。在开发Web应用程序中,需要把驱动程序打包文件复制到Tomcat的安装目录的lib目录中或Web应用程序的WEB-INF\lib目录中。
7.2 传统的数据库连接方法(⭐⭐⭐)
7.2.1 加载驱动程序
要使应用程序能够访问数据库,首先必须加载驱动程序。驱动程序是实现了Driver接口的类,它一般由数据库厂商提供。加载JDBC最常用的方法是使用Class类的forName()
静态方法
public static Class> forName(String className) throws ClassNotFoundException
如果要加载数据库厂商提供的专门的驱动程序,应该给出专门的驱动程序名。
使用方式:
Class.forName("org.postgresql.Driver")
7.2.2 建立连接对象
驱动程序加载后,使用DriverManager类的getConnection()
建立数据库连接对象。
- DriverManager类
为数据库与驱动程序建立连接 - JDBC URL
表示数据源,这样驱动程序就可以与它建立一个连接。jdbc:
: - jdbc表示协议,JDBC URL的协议总是jdbc
- subprotocol表示子协议,它表示驱动程序或数据库连接机制的名称
- subname为子名称,它表示数据库标识符
例子:
使用JDBC-ODBC:String durl = "jdbc:odbc:sample";
通过ODBC子协议连接到名为sampleDS的数据源。
连接PostgreSQL数据库,它的JDBC URL为:jdbc:postgresql://localhost:5432/dbname
实例:
String durl = "jdbc:postgresql://localhost:5432:paipaistore";
Connection conn = DriverManager.getConnection(durl, "paipaistore", "paipaistore");
常用的数据库的JDBC连接代码p170
7.2.3 创建语句对象
通过Connection对象,可以创建Statement对象(createStatement()
)和PreparedStatement对象(prepareStatement()
)和CallableStatement对象(prepareCall()
)。
例子,创建一个简单的Statement
Statement stmt = conn.createStatement();
7.2.4 获得SQL语句的执行结果
- 对于查询语句,
executeQuery(String sql)
返回ResultSet。ResultSet对象保存查询的结果集,再调用ResultSet的方法可以查询结果的每行进行处理。 - 对于DDL语句,如CREATE, ALTER, DROP和DML语句,如INSERT, UPDATE, DELETE等必须使用语句对象
executeUpdate(String sql)
。返回被影响的行数。
7.2.5 关闭建立的对象
在Connection接口,Statement接口,ResultSet接口中都定义了close()
。当这些对象使用完毕后应使用close()
关闭。
7.2.6 简单应用实例
p171
7.3 JDBC API介绍
7.3.1 Connection接口
p176
7.3.2 Statement接口
一旦创建了Statement对象,就可以用它来向数据库发送SQL语句,实现对数据库的查询和更新操作。
- 执行查询语句
public ResultSet executeQuery(String sql)
该方法创建的ResultSet对象是一个不可滚动的结果集,或者说是一个只能向前滚动的结果集,即只能从第一行向前移动知道最后一行为止,而不能向后访问结果集。 - 执行非查询语句
public int executeUpdate(String sql)
7.3.3 ResultSet接口
游标指向第一行的前面,可以调用ResultSet的next()
,使游标定位到下一条记录。如果返回false,说明已无记录。
public boolean next() throws SQLException
- 检索字段值
针对不同的数据类型,使用不同的getXxx()
获得值
如果列值为字符串型数据,可以使用:
public String getString(int columnIndex)
列号从1开始
public String getString(String columnName)
- 数据类型转换
p178
7.3.4 可滚动与可更新的ResultSet(会不会考?)
结果集对象可以前后移动指针访问结果集中的记录。不但可以访问,还可以通过结果集对象更新数据库。
- 可滚动的ResultSet
p178
7.4 预处理语句
如果数据库支持预编译,它可以将SQL语句传给数据库作预编译,以后每次执行这个SQL语句时,速度就可以提高很多。
7.4.1 创建PreparedStatement对象
用Connection的下列方法创建PreparedStatement对象。
public PreparedStatement prepareStatement(String sql)
public PreparedStatement prepareStatement(String sql, int resultType, int concurrency)
-
public PreparedStatement prepareStatement(String sql, int resultType, int concurrency, int holdability)
这些方法的第一个参数是SQL字符串。这些字符串包含一些参数,使用?作为占位符。
7.4.2 使用PreparedStatement对象
用于执行动态SQL语句。
String sql = "INSERT INTO products VALUES(?, ?, ?, ?)";
PreparedStatement p = conn.prepareStatement(sql);
注意:第一个占位符的序号为1,以此类推。当把预处理语句的SQL发送到数据库时,数据库将对它进行编译。
- 设置占位符
在执行SQL语句之前,必须使用数据替换每个占位符(setXxx()
)。
public void setInt(int parameterIndex, int x)
public void setString(int parameterIndex, String x)
- 用复杂数据设置占位符
p181 - 执行预处理语句
- 对查询语句应该调用
executeQuery()
- 对更新语句应该调用
executeUpdate()
注意:对于预处理语句,必须调用这些方法的无参数版本。如果调用executeQuery(String)
或executeUpdate(String)
会抛出异常。
7.5 连接池与数据源
为每个HTTP请求创建一个连接对象,Servlet数据库建立、执行查询、处理结果集、请求结束关闭连接、建立连接是比较耗费时间的操作,如果客户每次请求时都要建立连接,这件导致增大请求响应时间。
为了提高数据库访问效率,使用连接池和数据源技术。
7.5.1 连接池与数据源介绍
为每个HTTP请求创建一个连接对象,Servlet数据库建立、执行查询、处理结果集、请求结束关闭连接、建立连接是比较耗费时间的操作,如果客户每次请求时都要建立连接,这件导致增大请求响应时间。
为了提高数据库访问效率,使用连接池和数据源技术。
7.5.1 连接池与数据源介绍
- 事先建立若干连接对象,将它们存放在数据库连接池中供数据访问组件共享。
- DataSource是从连接池中获得连接对象。连接池预定义了一些连接,当应用程序需要连接对象时就从连接池取出一个,当连接对象使用完毕将其放回连接池,从而可以避免在每次请求连接时都要创建连接对象。
- 通过数据源获得数据库连接对象不能直接在应用程序中通过一个实例的方法来生成DataSource对象,而是需要采用Java命名与目录接口技术(JNDI)来获得DataSource对象的引用。
7.5.2 配置数据源
在Tomcat中可以配置两种数据源:
- 局部数据源:只能在呗定义数据源的应用程序中使用
- 全局数据源:可被所有的应用程序使用
注意:在Tomcat中,不管配置哪种数据源,都要讲JDBC驱动程序复制到Tomcat安装目录的lib目录中,并且需要重新启动服务器。
- 配置局部服务器
在Web应用程序中建立一个META-INF目录,在其中建立一个context.xml文件
- 在应用程序中使用数据源
在配置数据源之后,通过名字检索对象。
Context context = new InitialContext();
DataSource ds = (DataSource)context.loopup("java:comp/env/jdbc/sampleDS"); // 参数名为java:comp/env/ + 数据源名
得到DataSource对象的引用后,就可以通过它的getConnection()
获得数据库连接对象Connection。
- 配置全局数据源
全局数据源可被所有应用程序使用
p184