- 浏览: 747029 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
lengzl:
请问,那个Node 是哪个包里面的类?
JAVA 二叉树的递归和非递归遍历 -
gongchuangsu:
总结的很好,感谢感谢
JAVA 二叉树的递归和非递归遍历 -
Caelebs:
666666666 居然是10年发的,难怪截屏自动保存的名字是 ...
截图工具 -
jijiqw:
是注解不是注释。。。
Spring @Transactional (一) -
letueo:
[b][b][b][b][b][b][b][b][b][b][ ...
Spring @Transactional (一)
PreparedStatement是执行预编译的一个类,也就是先把SQL语句格式发送到数据库,然后填充里面的参数。
<%
String DBDRIVER="org.gjt.mm.mysql.Driver"; //数据库驱动
String DBURL="jdbc:mysql://localhost:3306/sshuser=root&password=root&useUnicode=true&characterEncoding=gbk"; //URL
PreparedStatement pstmt=null ResultSet rs=null;
%>
<%
try
{
Class.forName(DBDRIVER) ; //加载驱动
Connection conn = DriverManager.getConnection(DBURL) ; //获得连接
String sql = "SELECT id,uid,name,password FROM person" ;
pstmt = conn.prepareStatement(sql) ; //向数据库发送sql语句
rs = pstmt.executeQuery() ; //执行查询语句
%>
为什么 PreparedStatement 很重要, 以及怎样"正确"使用他们.
数据库有一个艰苦的工作. 它们不断地从许多客户端读取 SQL 查询, 对数据进行尽
可能高效的 查询. 处理语句可能成为一个代价较高的操作, 但是现在数据库都是很
好的设计, 这样这个困难 被减到最小. 但是这些优化需要应用程序开发者的协助,
这篇文章给你展示一下怎样正确使用 PreparedStatement 来漂亮地帮助数据库执行
这些优化.
一个数据库怎样执行一条语句?
显然, 不要希望这里有许多细节; 我们只看一下对这篇文章比较重要的部分. 当一个
数据库接收 到一条语句的时候, 数据库引擎首先解析这条语句, 查看语法错误. 一
旦语句解析了, 数据库 需要找出最有效的方法来执行这条语句. 这个计算起来代价
很大. 数据库检查什么索引(如果有 的话)能有所帮助, 或者它是否能全部读出一张
表中所有的记录. 数据库根据这些关于数据库所 存数据的统计数字来找出最好的
办法. 一旦制订出查询方案, 就可以由数据库引擎来执行.
需要 CPU 来产生访问方案. 理想的情况, 如果我们把相同的语句给数据库发送两
次, 我们期望 数据库重用第一条记录的访问方案. 这会比第二次重新产生方案要使
用较少的 CPU.
语句缓冲
数据库可以进行调节来做语句缓冲. 通常包含一些类型的语句缓冲. 缓冲使用语句
本身作为关键 字, 访问方案和相应的语句存储在缓冲区中. 这样就允许数据库引擎
对以前执行过的语句所使用 的访问方案进行重用. 举个例子来说, 如果我们向数据
库发送这样一条语句 "select a, b from t where c = 2", 计算好的访问方案就放入缓冲
区了. 如果我们以后再使用同样的语 句, 数据库就能重用以前的访问方案, 这样就
能节省 CPU.
但是要注意, 整条语句是一个关键字. 例如, 如果我们后来发送的语句是 "select a,b
from t where c = 3", 那么就不会找出以前的访问方案. 因为 "c=3" 和 "c=2" 是不一
样的. 所以, 例如:
For(int I = 0; I < 1000; ++I)
{
PreparedStatement ps = conn.prepareStatement("select a,b from t
where c = " + I);
ResultSet rs = Ps.executeQuery();
Rs.close();
Ps.close();
}
这里不会用到缓冲. 每次循环向数据库发送一条不同的 SQL 语句. 每次循环都重新
计算新的访问 方案, 用这种方法我们会浪费大量的 CPU 周期. 但是, 看看下一个片
段:
PreparedStatement ps = conn.prepareStatement("select a,b from t where c
= ?");
For(int I = 0; I < 1000; ++I)
{
ps.setInt(1, I);
ResultSet rs = ps.executeQuery();
Rs.close();
}
ps.close();
这样就会高效得多. 发送给数据库的语句在 sql 中使用 '?' 符号来参数化. 这意味着
每次循环 发送的是同一条语句, 在 "c=?" 部分带有不同的参数. 这样就允许数据库
重用语句的访问方案, 是程序在数据库内部运行得更高效. 这基本上能使你的程序
运行得更快, 或者使数据库用户能更多 地使用 CPU.
PreparedStatement 和 J2EE 服务器
当我们使用 J2EE 服务器的时候, 事情会变得更加复杂. 通常情况下, 一个预先准备
好的语句 (prepared statement) 是和一个单独的数据库连接相关联的. 当连接关闭时,
语句就被丢弃 了. 一般来说, 一个胖客户端应用程序在得到一个数据库连接后会一
直保持到程序结束. 它会使用 两种方法创建所有的语句: 急切创建(eagerly) 或者 懒
惰创建(lazily). Eagerly是说, 当程序启动时全部创建. Lazily是说随用随创建. 急切
的方法会在程序启动时有些延时, 但是一旦程序启动以后, 运行很好. 懒惰的方法启
动很快, 但是当程序运行时, 预先准备的语句在第一次使用是创建. 这就会造成性能
不平衡, 知道所有的 语句都准备好了, 但是最终程序会和急切方法一样快. 哪一种
最好要看你需要的是快速启动还是 均衡的性能.
一个 J2EE 应用程序所带来的问题就是它不能像这样工作. 它只在一个请求的生存
时间中保持一个 连接. 这意味着在他处理每一个请求时都会重新创建语句, 就不象
胖客户端只创建一次, 而不是每 个请求都创建那样有效,
当 J2EE 服务器给你的程序一个连接时, 并不是一个真正的连接, 而是一个经过包装
的. 你可以 通过查看那个连接的类的名字来检验一下. 它不是一个数据库的 JDBC
连接, 是你的服务器创建 的一个类. 通常, 如果你调用一个连接的 close 方法, 那么
jdbc 驱动程序会关闭这个连接. 我们希望的是当 J2EE 应用程序调用 close 的时候,
连接会返回到连接池中. 我们通过设计一个 代理的 jdbc 连接类来做这些, 但看起来
就象是实际的连接. 当我们调用这个连接的任何方法时, 代理类就会把请求前递给
实际的连接. 但是, 当我们调用类似 close 的方法时, 并不调用实际 连接的 close 方
法, 只是简单地把连接返回给连接池, 然后把代理连接标记为无效, 这样当它 被应
用程序重新使用时, 我们会得到异常.
包装是非常有用的, 因为它帮助 J2EE 应用程序服务器实现者比较聪明地加上预先
准备语句的 支持. 当程序调用 Connection.prepareStatement 时, 由驱动程序返回一
个 PreparedStatement 对象. 当应用程序得到它时, 保存这个句柄, 并且在请求完成
时, 关闭 请求之前关闭这个句柄. 但是, 在连接返回到连接池之后, 以后被同样或者
另一个应用程序重用时, 那么, 我们就理论上希望同样的 PreparedStatement 返回给
应用程序.
J2EE PreparedStatement 缓冲
J2EE PreparedStatement 缓冲由 J2EE 服务器内部的连接池管理器使用一个缓冲区
来 实现. J2EE 服务器在连接池中保存一个所有数据库的预先准备语句的一个列表.
当一个程序 调用一个连接的 prepareStatement 方法时, 服务器先检查这个语句是否
已经有了, 如果 是, 相应的 PreparedStatement 就在缓冲区内, 就返回给应用程序, 如
果不是, 请求就 会传递给 jdbc 驱动程序, 请求/预先准备语句 对象就会加入到缓冲
区里.
对于每一个连接我们需要一个缓冲区, 因为这是 jdbc 驱动程序的工作要求. 任何返
回的 preparedStatement 都是针对这个连接的.
如果我们要利用缓冲区的优势, 要使用和前面相同的规则. 我们需要使用参数话的
查询, 这样 它们就会和已经在缓冲区的某一个匹配. 大多数应用程序服务器都允许
你调整缓冲区的大小.
概要
总之, 对于预先准备语句, 我们应该使用参数化的查询. 这样允许数据库重用已经存
在的访问 方案, 从而减轻数据库的负担. 这样的缓冲区是这个数据库范围的, 所以
你可以安排你所有的 应用程序, 使用相似的参数化的 SQL, 就会提高这样的缓冲区
方案的效率, 因为一个应用程序 可以使用另一个应用程序的语句. 一个应用服务器
的优势也在于此, 因为访问数据库的逻辑应该 集中在数据访问层上(OR 映射, 实体
bean 或者直接 JDBC).
最后, 预先准备语句的正确使用也让你利用应用程序服务器的预先准备语句的缓冲
区的好处. 会提高你的应用程序的性能, 因为应用程序通过对以前的预先准备语句
的重用减少 JDBC 驱动程序调用的次数. 这样使它能和胖客户端的效率竞争, 并且
去掉了不能保持一个长期 连接的坏处.
如果你使用参数化的预先准备语句, 就可以提高数据库和你的服务器端的代码的效
率. 这些提高 都会允许你的应用程序提高性能.
<%
String DBDRIVER="org.gjt.mm.mysql.Driver"; //数据库驱动
String DBURL="jdbc:mysql://localhost:3306/sshuser=root&password=root&useUnicode=true&characterEncoding=gbk"; //URL
PreparedStatement pstmt=null ResultSet rs=null;
%>
<%
try
{
Class.forName(DBDRIVER) ; //加载驱动
Connection conn = DriverManager.getConnection(DBURL) ; //获得连接
String sql = "SELECT id,uid,name,password FROM person" ;
pstmt = conn.prepareStatement(sql) ; //向数据库发送sql语句
rs = pstmt.executeQuery() ; //执行查询语句
%>
为什么 PreparedStatement 很重要, 以及怎样"正确"使用他们.
数据库有一个艰苦的工作. 它们不断地从许多客户端读取 SQL 查询, 对数据进行尽
可能高效的 查询. 处理语句可能成为一个代价较高的操作, 但是现在数据库都是很
好的设计, 这样这个困难 被减到最小. 但是这些优化需要应用程序开发者的协助,
这篇文章给你展示一下怎样正确使用 PreparedStatement 来漂亮地帮助数据库执行
这些优化.
一个数据库怎样执行一条语句?
显然, 不要希望这里有许多细节; 我们只看一下对这篇文章比较重要的部分. 当一个
数据库接收 到一条语句的时候, 数据库引擎首先解析这条语句, 查看语法错误. 一
旦语句解析了, 数据库 需要找出最有效的方法来执行这条语句. 这个计算起来代价
很大. 数据库检查什么索引(如果有 的话)能有所帮助, 或者它是否能全部读出一张
表中所有的记录. 数据库根据这些关于数据库所 存数据的统计数字来找出最好的
办法. 一旦制订出查询方案, 就可以由数据库引擎来执行.
需要 CPU 来产生访问方案. 理想的情况, 如果我们把相同的语句给数据库发送两
次, 我们期望 数据库重用第一条记录的访问方案. 这会比第二次重新产生方案要使
用较少的 CPU.
语句缓冲
数据库可以进行调节来做语句缓冲. 通常包含一些类型的语句缓冲. 缓冲使用语句
本身作为关键 字, 访问方案和相应的语句存储在缓冲区中. 这样就允许数据库引擎
对以前执行过的语句所使用 的访问方案进行重用. 举个例子来说, 如果我们向数据
库发送这样一条语句 "select a, b from t where c = 2", 计算好的访问方案就放入缓冲
区了. 如果我们以后再使用同样的语 句, 数据库就能重用以前的访问方案, 这样就
能节省 CPU.
但是要注意, 整条语句是一个关键字. 例如, 如果我们后来发送的语句是 "select a,b
from t where c = 3", 那么就不会找出以前的访问方案. 因为 "c=3" 和 "c=2" 是不一
样的. 所以, 例如:
For(int I = 0; I < 1000; ++I)
{
PreparedStatement ps = conn.prepareStatement("select a,b from t
where c = " + I);
ResultSet rs = Ps.executeQuery();
Rs.close();
Ps.close();
}
这里不会用到缓冲. 每次循环向数据库发送一条不同的 SQL 语句. 每次循环都重新
计算新的访问 方案, 用这种方法我们会浪费大量的 CPU 周期. 但是, 看看下一个片
段:
PreparedStatement ps = conn.prepareStatement("select a,b from t where c
= ?");
For(int I = 0; I < 1000; ++I)
{
ps.setInt(1, I);
ResultSet rs = ps.executeQuery();
Rs.close();
}
ps.close();
这样就会高效得多. 发送给数据库的语句在 sql 中使用 '?' 符号来参数化. 这意味着
每次循环 发送的是同一条语句, 在 "c=?" 部分带有不同的参数. 这样就允许数据库
重用语句的访问方案, 是程序在数据库内部运行得更高效. 这基本上能使你的程序
运行得更快, 或者使数据库用户能更多 地使用 CPU.
PreparedStatement 和 J2EE 服务器
当我们使用 J2EE 服务器的时候, 事情会变得更加复杂. 通常情况下, 一个预先准备
好的语句 (prepared statement) 是和一个单独的数据库连接相关联的. 当连接关闭时,
语句就被丢弃 了. 一般来说, 一个胖客户端应用程序在得到一个数据库连接后会一
直保持到程序结束. 它会使用 两种方法创建所有的语句: 急切创建(eagerly) 或者 懒
惰创建(lazily). Eagerly是说, 当程序启动时全部创建. Lazily是说随用随创建. 急切
的方法会在程序启动时有些延时, 但是一旦程序启动以后, 运行很好. 懒惰的方法启
动很快, 但是当程序运行时, 预先准备的语句在第一次使用是创建. 这就会造成性能
不平衡, 知道所有的 语句都准备好了, 但是最终程序会和急切方法一样快. 哪一种
最好要看你需要的是快速启动还是 均衡的性能.
一个 J2EE 应用程序所带来的问题就是它不能像这样工作. 它只在一个请求的生存
时间中保持一个 连接. 这意味着在他处理每一个请求时都会重新创建语句, 就不象
胖客户端只创建一次, 而不是每 个请求都创建那样有效,
当 J2EE 服务器给你的程序一个连接时, 并不是一个真正的连接, 而是一个经过包装
的. 你可以 通过查看那个连接的类的名字来检验一下. 它不是一个数据库的 JDBC
连接, 是你的服务器创建 的一个类. 通常, 如果你调用一个连接的 close 方法, 那么
jdbc 驱动程序会关闭这个连接. 我们希望的是当 J2EE 应用程序调用 close 的时候,
连接会返回到连接池中. 我们通过设计一个 代理的 jdbc 连接类来做这些, 但看起来
就象是实际的连接. 当我们调用这个连接的任何方法时, 代理类就会把请求前递给
实际的连接. 但是, 当我们调用类似 close 的方法时, 并不调用实际 连接的 close 方
法, 只是简单地把连接返回给连接池, 然后把代理连接标记为无效, 这样当它 被应
用程序重新使用时, 我们会得到异常.
包装是非常有用的, 因为它帮助 J2EE 应用程序服务器实现者比较聪明地加上预先
准备语句的 支持. 当程序调用 Connection.prepareStatement 时, 由驱动程序返回一
个 PreparedStatement 对象. 当应用程序得到它时, 保存这个句柄, 并且在请求完成
时, 关闭 请求之前关闭这个句柄. 但是, 在连接返回到连接池之后, 以后被同样或者
另一个应用程序重用时, 那么, 我们就理论上希望同样的 PreparedStatement 返回给
应用程序.
J2EE PreparedStatement 缓冲
J2EE PreparedStatement 缓冲由 J2EE 服务器内部的连接池管理器使用一个缓冲区
来 实现. J2EE 服务器在连接池中保存一个所有数据库的预先准备语句的一个列表.
当一个程序 调用一个连接的 prepareStatement 方法时, 服务器先检查这个语句是否
已经有了, 如果 是, 相应的 PreparedStatement 就在缓冲区内, 就返回给应用程序, 如
果不是, 请求就 会传递给 jdbc 驱动程序, 请求/预先准备语句 对象就会加入到缓冲
区里.
对于每一个连接我们需要一个缓冲区, 因为这是 jdbc 驱动程序的工作要求. 任何返
回的 preparedStatement 都是针对这个连接的.
如果我们要利用缓冲区的优势, 要使用和前面相同的规则. 我们需要使用参数话的
查询, 这样 它们就会和已经在缓冲区的某一个匹配. 大多数应用程序服务器都允许
你调整缓冲区的大小.
概要
总之, 对于预先准备语句, 我们应该使用参数化的查询. 这样允许数据库重用已经存
在的访问 方案, 从而减轻数据库的负担. 这样的缓冲区是这个数据库范围的, 所以
你可以安排你所有的 应用程序, 使用相似的参数化的 SQL, 就会提高这样的缓冲区
方案的效率, 因为一个应用程序 可以使用另一个应用程序的语句. 一个应用服务器
的优势也在于此, 因为访问数据库的逻辑应该 集中在数据访问层上(OR 映射, 实体
bean 或者直接 JDBC).
最后, 预先准备语句的正确使用也让你利用应用程序服务器的预先准备语句的缓冲
区的好处. 会提高你的应用程序的性能, 因为应用程序通过对以前的预先准备语句
的重用减少 JDBC 驱动程序调用的次数. 这样使它能和胖客户端的效率竞争, 并且
去掉了不能保持一个长期 连接的坏处.
如果你使用参数化的预先准备语句, 就可以提高数据库和你的服务器端的代码的效
率. 这些提高 都会允许你的应用程序提高性能.
发表评论
-
Servlet上传文件
2012-02-07 23:58 1493准备工作:要到http://commons.apache.or ... -
成为Java高手需要达到的25个学习目标--经典
2012-01-29 16:07 1350本文将告诉你学习Java需 ... -
Timer, Quartz 和 Spring 实现作业调度
2011-11-28 15:43 1175一、java.util.Timer ... -
Java 产生不重复的随机数
2011-06-22 23:32 2361int numberCount = 6; ... -
Date类学习总结(Calendar Date 字符串 相互转换 格式化)
2011-06-20 16:12 1663Date类学习总结 1.计算某一月份的最大天数 ... -
jsp中的cookie用法小实例
2011-06-20 00:13 2492这个小实例有三个页面 index.jsp页面内容如下: Y ... -
JS实现简单的增删改查
2011-06-19 23:41 12962<%@ page language="ja ... -
Jsp 动态显示系统时间
2011-06-19 23:24 4899<%@ page language=" ... -
java 动态显示时间
2011-06-19 23:13 4060import java.util.Date; p ... -
js 动态显示时间
2011-06-19 22:53 1833<%@ page language=" ... -
HTML 显示系统时间
2011-06-19 22:13 7888代码1:(显示静态时间) <script type=& ... -
JavaScript 动态显示系统时间
2011-06-19 19:36 2081JavaScript 动态显示系统时间 <html ... -
两例JavaScript 获取当前系统日期和时间
2011-06-19 19:20 1252两例JavaScript 获取当前系统日期和时间 QUOTE ... -
java五种JSP页面跳转方法详解
2011-06-19 17:08 14771. RequestDispatcher.forward() ... -
Java Object方法
2011-06-19 16:47 1354package com.abin.test.connectio ... -
Java 数组,List,Itarator循环
2011-06-19 16:01 2307package com.abin.test.connect ... -
JAVA DBClass操作数据库,这样算不算单列模式
2011-06-19 14:53 1255到底怎样才算单列模式,单列模式事什么概念 package c ... -
Oracle日期函数集锦
2011-06-16 20:55 933Oracle日期函数集锦(一) 一、 常用日期数据格式 1 ... -
java 页面传送数组
2011-06-15 14:56 25971.可以通过嵌入java代码调用session或者reques ... -
java Calendar当前时间
2011-06-14 13:40 1665Calendar c = Calendar.getIn ...
相关推荐
- 为避免SQL注入攻击,强烈建议使用PreparedStatement而不是Statement,并且避免在JSP页面中硬编码敏感信息如数据库连接字符串和密码。 9. **最佳实践**: - 考虑使用DAO(Data Access Object)模式或Spring JDBC...
- 在JSP中,我们需要创建一个PreparedStatement对象来执行SQL插入语句。因为图片数据是二进制的,所以通常我们会将其存储在数据库中的BLOB(Binary Large Object)类型字段中。 ```jsp PreparedStatement pstmt ...
在Java服务器页面(JSP)技术中,数据库操作是常见的需求,主要用于动态网站的数据存储和检索。本示例将简要介绍如何使用JSP来连接并操作数据库。首先,我们需要理解JSP的基本结构和数据库连接的基本原理。 1. **...
本实例"jsp增删改"主要关注的是JSP在数据库操作中的应用,包括添加(Add)、删除(Delete)和修改(Update)数据的基本功能。这些是任何Web应用程序开发中的核心概念,特别是对于构建交互式网站和Web应用来说。 ...
【JSP 访问 SQL Server 2005 数据库】 在Web开发中,JavaServer Pages(JSP)常用于创建动态网页,而SQL Server 2005是一款功能强大的关系型数据库管理系统。将JSP与SQL Server 2005结合,可以实现Web应用程序与...
这篇文章将详细介绍PreparedStatement对象在JSP中操作数据库的使用方法,包括创建对象、传递参数、以及确保参数数据类型一致性等关键知识点。 首先,PreparedStatement实例可以包含预编译的SQL语句,这意味着SQL...
本文将详细介绍`PreparedStatement`的使用方法,主要面向Java服务器页面(JSP)的初学者。 #### 二、准备工作 为了能够使用`PreparedStatement`,首先需要确保已经安装了MySQL数据库,并且在项目中引入了MySQL ...
3. **执行SQL操作** - 根据用户请求,构造相应的SQL语句,如`INSERT`, `UPDATE`或`DELETE`,并调用Statement或PreparedStatement对象执行。 4. **处理结果** - 如果是增、改操作,可能需要返回影响行数;如果是查询...
在与MySQL数据库交互时,JSP通常会创建一个`java.sql.Connection`对象,通过`DriverManager.getConnection()`方法连接到数据库,然后使用`Statement`或`PreparedStatement`对象执行SQL语句。例如,创建用户时,可能...
在Web开发中,JavaServer Pages(JSP)和MySQL数据库的结合是常见的技术栈,用于构建动态、数据驱动的网站。本学习笔记将详细讲解如何使用JSP连接MySQL数据库,并创建一个简单的用户注册表单。 1. **JSP简介** JSP...
开发者需要编写SQL语句来执行数据操作,并使用PreparedStatement或Statement对象来执行。 3. **用户界面**: 用户通过友好的Web界面与系统交互。这些界面通常由HTML、CSS和JavaScript构建,JSP负责处理用户的请求并...
**JSP实现留言板功能** 在Web开发中,JavaServer Pages(JSP)是一种常见的技术,用于构建动态网页。本教程将深入探讨如何使用JSP来实现一个简单的留言板功能,这通常包括用户提交留言、查看历史留言以及管理员进行...
了解如何通过连接对象创建Statement或PreparedStatement来发送SQL语句。 #### 获得SQL语句的执行结果 通过执行SQL语句后获取的ResultSet对象来遍历查询结果集。 #### JDBC技术解析 JDBC技术解析介绍JDBC的架构...
**JSP(Java Server Pages)留言板项目详解** 在IT领域,Web开发是不可或缺的一部分,而JSP(Java Server Pages)是Java平台上的一个重要技术,用于创建动态网页。本项目是基于JSP实现的一个简单的留言板系统,非常...
JSP数据库编程则是将JSP与数据库系统相结合,以实现数据的存储、检索、更新和删除等操作。本指南将深入探讨这个主题,帮助你理解和掌握如何在JSP中有效地进行数据库交互。 首先,我们需要了解JDBC(Java Database ...
在JSP中,可能使用PreparedStatement预编译SQL语句,以防止SQL注入攻击。 6. **用户认证与授权**: 为了确保用户安全,论坛短消息系统需要实现用户登录和权限验证。这可能涉及cookies、session管理,以及对敏感...
请注意,这只是一个简化的示例,实际应用中应考虑错误处理、SQL注入防范以及更高效的数据库交互方法,如使用PreparedStatement。 总结一下,这个场景中的关键技术包括: 1. JSP:用于创建动态服务器页面。 2. ...