Statement 和 PreparedStatement CallableStatement及hibernate中的session

 JDBC驱动的最佳化是基于使用的是什么功能. 选择PreparedStatement还是Statement取决于你要怎么使用它们. 对于只执行一次的SQL语句选择Statement是最好的. 相反, 如果SQL语句被多次执行选用PreparedStatement是最好的.
对于PreparedStatement加?再set否则和statement一样,就没有效果。数据库在执行sql语句的时候如果使用PreparedStatement语句会有一点优势:因为数据库会preparedStatement 语句进行预编译,下次执行相同的sql语句时,数据库端不会再进行预编译了,而直接用数据库的缓冲区,提高数据访问的效率(但尽量尽量采用使用?号的方式传递参数),如果sql语句只执行一次,以后不再复用建议使用statement
PreparedStatement的第一次执行消耗是很高的. 它的性能体现在后面的重复执行.

CallableStatement用于执行 SQL 存储过程的接口

.PreparedStatement是预编译的,对于批量处理可以大大提高效率. 也叫JDBC存储过程

2. 使用 Statement 对象。在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理。PreparedStatement 对象的开销比Statement大,对于一次性操作并不会带来额外的好处。
3. statement每次执行sql语句,相关数据库都要执行sql语句的编译,preparedstatement是预编译得,    preparedstatement支持批处理

 

二、使用PreparedStatement的Batch功能
Update大量的数据时, 先Prepare一个INSERT语句再多次的执行, 会导致很多次的网络连接. 要减少JDBC的调用次数改善性能, 你可以使用PreparedStatement的AddBatch()方法一次性发送多个查询给数据库. 例如, 让我们来比较一下下面的例子.

例 1: 多次执行Prepared Statement

 

 
  1. PreparedStatement ps = conn.prepareStatement(  
  2.    "INSERT into employees values (?, ?, ?)");  
  3.   
  4. for (n = 0; n < 100; n++) {  
  5.   
  6.   ps.setString(name[n]);  
  7.   ps.setLong(id[n]);  
  8.   ps.setInt(salary[n]);  
  9.   ps.executeUpdate();  
  10. }  

 

例 2: 使用Batch

 

 
  1. PreparedStatement ps = conn.prepareStatement(  
  2.    "INSERT into employees values (?, ?, ?)");  
  3.   
  4. for (n = 0; n < 100; n++) {  
  5.   
  6.   ps.setString(name[n]);  
  7.   ps.setLong(id[n]);  
  8.   ps.setInt(salary[n]);  
  9.   ps.addBatch();  
  10. }  
  11. ps.executeBatch();  

 

 

 void addBatch()
          将一组参数添加到此 PreparedStatement 对象的批处理命令中。
 void clearParameters()
          立即清除当前参数值。
 boolean execute()
          在此 PreparedStatement 对象中执行 SQL 语句,该语句可以是任何种类的 SQL 语句。
 ResultSet executeQuery()
          在此 PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象。
 int executeUpdate()
          在此 PreparedStatement 对象中执行 SQL 语句,该语句必须是一个 SQL 数据操作语言(Data Manipulation Language,DML)语句,比如 INSERTUPDATEDELETE 语句;或者是无返回内容的 SQL 语句,比如 DDL 语句。

 

以上是preperStatement的几个常用方法。

 

 execute  executeQuery、executeUpdate都是 SQL 语句的方法,区别如下:

       方法execute:
       用于执行返回多个结果集、多个更新计数或二者组合的语句。

       方法executeQuery
       用于产生单个结果集的语句,例如 SELECT 语句。这个方法被用来执行 SELECT 语句,它几乎是使用最多的 SQL 语句。

       方法executeUpdate
       用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQL DDL(数据定义语言)语句,例如 CREATE TABLE 和 DROP TABLE。INSERT、UPDATE 或 DELETE 语句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。对于 CREATE TABLE 或 DROP TABLE 等不操作行的语句,executeUpdate 的返回值总为零。

      

 

 在例 1中, PreparedStatement被用来多次执行INSERT语句. 在这里, 执行了100次INSERT操作, 共有101次网络往返. 其中,1次往返是预储statement, 另外100次往返执行每个迭代. 在例2中, 当在100次INSERT操作中使用addBatch()方法时, 只有两次网络往返. 1次往返是预储statement, 另一次是执行batch命令. 虽然Batch命令会用到更多的数据库的CPU周期, 但是通过减少网络往返,性能得到提高. 记住, JDBC的性能最大的增进是减少JDBC驱动与数据库之间的网络通讯.
  注:Oracel 10G的JDBC Driver限制最大Batch size是16383条,如果addBatch超过这个限制,那么executeBatch时就会出现“无效的批值”(Invalid Batch Value) 异常。因此在如果使用的是Oracle10G,在此bug减少前,Batch size需要控制在一定的限度。

有人主张,在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.也就是说,在任何时候都不要使用Statement。

当一个 数据库接收 到一条语句的时候, 数据库引擎首先解析这条语句, 查看语法错误. 一 旦语句解析了, 数据库 需要找出最有效的方法来执行这条语句. 这个计算起来代价很大. 数据库检查什么索引(如果有 的话)能有所帮助, 或者它是否能全部读出一张表中所有的记录. 数据库根据这些关于数据库所 存数据的统计数字来找出最好的办法. 一旦制订出查询方案, 就可以由数据库引擎来执行. 需要 CPU 来产生访问方案. 想的情况, 如果我们把相同的语句给数据库发送两次, 我们期望 数据库重用第一条记录的访问方案. 这会比第二次重新产生方案要使用较少的 CPU. 语句缓冲数据库可以进行调节来做语句缓冲. 通常包含一些类型的语句缓冲. 缓冲使用语句本身作为关键 字, 访问方案和相应的语句存储在缓冲区中. 这样就允许数据库引擎

由于preparedstatement具备很多优点,开发者可能通常都使用它,只有在完全是因为性能原因或者是在一行sql语句中没有变量的时候才使用通常的statement

对以前执行过的语句所使用 的访问方案进行重用. 举个例子来说, 如果我们向数据库发送这样一条语句 "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 服务器

传送给数据库的 SQL 语句通过一个包含两个步骤的过程来返回结果。首先准备它们,然后处理它们。借助 Statement 对象,这两个阶段对应用程序而言变成一个阶段。PreparedStatement 允许将这两个步骤分开。准备步骤在创建对象时发生,而处理步骤在对 PreparedStatement 对象调用 executeQuery、executeUpdate 或 execute 方法时发生。

如果不添加参数标记,能够将 SQL 处理分割成单独的阶段并没有意义。参数标记放在应用程序中,从而使它能够告诉数据库它在准备时并不具有特定的值,但它在处理之前提供一个值。在 SQL 语句中,参数标记是使用问号表示的。

通过使用参数标记,有可能创建用于特定请求的一般 SQL 语句。例如,给定以下 SQL 查询语句:

     SELECT * FROM EMPLOYEE_TABLE WHERE LASTNAME = 'DETTINGER'

这是一个特定的 SQL 语句,它只返回一个值;即关于名为 Dettinger 的雇员的信息。通过添加参数标记,可以使语句更为灵活:

     SELECT * FROM EMPLOYEE_TABLE WHERE LASTNAME = ?

通过简单地将参数标记设置为某个值,可以获取关于表中的任何雇员的信息。

由于前一个 Statement 示例可以只经过一次准备阶段并接着使用不同的参数值来重复地进行处理,所以 PreparedStatement 能够提供比 Statement 更高的性能。

注意:要支持本机 JDBC 驱动程序的语句合用,必须使用 PreparedStatement。

prepareStatement 方法用来创建新的 PreparedStatement 对象。与 createStatement 方法不同,创建 PreparedStatement 对象时必须提供 SQL 语句。在那个时候,对 SQL 语句进行预编译以供使用。例如,假定已存在名为 conn 的 Connection 对象,以下示例将创建 PreparedStatement 对象并准备要在数据库中处理的 SQL 语句。

     PreparedStatement ps = conn.prepareStatement("SELECT * FROM EMPLOYEE_TABLE
                                                  WHERE LASTNAME = ?");

与 createStatement 方法相同,重载 prepareStatement 方法的目的是提供对指定 ResultSet 特征的支持。prepareStatement 方法还具有变体,可使用自动生成的键。以下是有效 prepareStatement 方法调用的一些示例:

在可以处理 PreparedStatement 对象之前,必须将每个参数标记设置为一些值。PreparedStatement 对象提供了许多个用于设置参数的方法。所有这些方法的格式均为 set,其中 是 Java 数据类型。这些方法的一些示例包括 setInt、setLong、setString、setTimestamp、setNull 和 setBlob。几乎所有这些方法都有两个参数:

  • 第一个参数是该参数在语句中的索引。参数标记具有从 1 开始的编号。
  • 第二个参数是要对第一个参数设置的值。有几个 set 方法具有附加的参数,如 setBinaryStream 上的长度参数。

 3:在hibernate中有以下几种方法获取connection和会话

首先要做hibernate中获取SessionFactoryUtils.getSession(getSessionFactory(), true),及session。再通过

SessionFactoryUtils.getDataSource(getSessionFactory()).getConnection(),获取连接。或者用session.connection(),但这个方法已经过时。

然后就是和jdbc都一样的了。

是hibernate还有专门的session可以进行数据库的操作

1,一个用户可以对应很多个SESSION ,但不一定对应一个connection (几个session可能共享一个connection

connection是指用户到数据库建立起来的(物理)连接
2. session是指这个物理连接上的传递的数据,或者说session是一个逻辑上的连接
3,session >= connection

你可能感兴趣的:(Statement 和 PreparedStatement CallableStatement及hibernate中的session)